[][src]Struct parsley::prelude::Context

pub struct Context {
    pub lang: HashMap<String, SExp>,
    // some fields omitted
}

Evaluation context for LISP expressions.

Note

Context::default() only provides very basic utilities. To obtain an evaluation context with useful functions available, use Context::base().

Some implementation details

Context maintains separate environments for "core" (special forms, etc.), "lang" (basic functions, vectors, and more), and "user" definitions. Most of the provided methods operate on the "user" environment, as the intended use case keeps the other environments immutable once they have been initialized.

Fields

lang: HashMap<String, SExp>

You can insert additional definitions here to make them available throughout the runtime. These definitions will not go out of scope automatically, but can be overridden (see get for semantic details).

Methods

impl Context
[src]

pub fn base() -> Self
[src]

Base context - defines a number of useful functions and constants for use in the runtime.

Example

use parsley::prelude::*;
let mut ctx = Context::base();

assert_eq!(
    ctx.eval(
        sexp![SExp::sym("null?"), SExp::sym("null")]
    ).unwrap(),
    SExp::from(true),
);

println!("{}", ctx.get("eq?").unwrap());   // "#<procedure>"
println!("{}", ctx.get("+").unwrap());     // "#<procedure>"

impl Context
[src]

pub fn math(self) -> Self
[src]

Math functions that are less commonly used. Intended to be layered on top of the base context.

Example

use parsley::prelude::*;
let mut ctx = &mut Context::base().math();
let mut asrt = |lhs, rhs| {
    assert_eq!(ctx.run(lhs).unwrap(), ctx.run(rhs).unwrap())
};

asrt("(is-nan NaN)", "#t");
asrt("(floor -4.07326)", "-5");
asrt("(ceil 7.1)", "8");
asrt("(hypot 3 4)", "5");
asrt("(recip 100)", "0.01");
asrt("(log (exp 7))", "7");

impl Context
[src]

pub fn capture(&mut self)
[src]

Start capturing printed content in a buffer.

pub fn capturing(self) -> Self
[src]

Capture display and write statement output in a buffer.

pub fn get_output(&mut self) -> Option<String>
[src]

Get the captured side-effect output.

impl Context
[src]

pub fn push(&mut self)
[src]

Add a new, nested scope.

See Context::pop for a usage example.

pub fn pop(&mut self)
[src]

Remove the most recently added scope.

If the stack height is 1, all definitions will be cleared, and the global scope will be replaced with an empty one.

Example

use parsley::prelude::*;
let mut ctx = Context::default();

assert_eq!(ctx.get("x"), None);
ctx.push();
ctx.define("x", SExp::Null);
assert_eq!(ctx.get("x"), Some(SExp::Null));
ctx.pop();
assert_eq!(ctx.get("x"), None);

pub fn define(&mut self, key: &str, value: SExp)
[src]

Create a new definition in the current scope.

pub fn get(&self, key: &str) -> Option<SExp>
[src]

Get the definition for a symbol in the execution environment.

Returns None if no definition is found.

Override semantics

This method searches for a definition in the following order:

  1. The core language
  2. User definitions, starting from the most recent scope and working backward to the top-level
  3. Language-level definitions

What this means is that definitions populated in the lang field can be overridden inside the runtime (e.g. in a REPL), but special form keywords cannot. For example, we can (define null "foo"), but we cannot (set! and or).

Examples

let ctx = parsley::Context::default(); // only core definitions included
assert!(ctx.get("potato").is_none());
use parsley::prelude::*;
let mut ctx = Context::default();

ctx.define("x", SExp::from(3));
assert_eq!(ctx.get("x"), Some(SExp::from(3)));

pub fn set(&mut self, key: &str, value: SExp) -> Result
[src]

Re-bind an existing definition to a new value.

Returns Ok if an existing definition was found and updated. Returns Err if no definition exists.

Example

use parsley::prelude::*;
let mut ctx = Context::default();

assert!(ctx.set("x", SExp::from(false)).is_err());    // Err, because x is not yet defined
ctx.define("x", SExp::from(3));                       // define x
assert_eq!(ctx.get("x"), Some(SExp::from(3)));        // check that its value is 3
assert!(ctx.set("x", SExp::from("potato")).is_ok());  // Ok because x is now defined
assert_eq!(ctx.get("x"), Some(SExp::from("potato"))); // check that its value is now "potato"

pub fn run(&mut self, expr: &str) -> Result
[src]

Run a code snippet in an existing Context.

Example

use parsley::prelude::*;
let mut ctx = Context::base();

assert!(ctx.run("x").is_err());
assert!(ctx.run("(define x 6)").is_ok());
assert_eq!(ctx.run("x").unwrap(), SExp::from(6));

pub fn eval(&mut self, expr: SExp) -> Result
[src]

Evaluate an S-Expression in a context.

The context will retain any definitions bound during evaluation (e.g. define, set!).

Examples

use parsley::prelude::*;
let result = Context::base().eval(
    sexp![SExp::sym("eq?"), 0, 1]
);
assert_eq!(result.unwrap(), SExp::from(false));
use parsley::prelude::*;
let mut ctx = Context::base();

let exp1 = sexp![SExp::sym("define"), SExp::sym("x"), 10];
let exp2 = SExp::sym("x");

ctx.eval(exp1);
assert_eq!(ctx.eval(exp2).unwrap(), SExp::from(10));

Trait Implementations

impl Default for Context
[src]

impl Write for Context
[src]

fn write_char(&mut self, c: char) -> Result<(), Error>
1.1.0
[src]

Writes a [char] into this writer, returning whether the write succeeded. Read more

fn write_fmt(&mut self, args: Arguments) -> Result<(), Error>
1.0.0
[src]

Glue for usage of the [write!] macro with implementors of this trait. Read more

Auto Trait Implementations

impl !Send for Context

impl !Sync for Context

Blanket Implementations

impl<T> From for T
[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    T: From<U>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Any for T where
    T: 'static + ?Sized
[src]