pub struct Interpreter { /* private fields */ }Expand description
A Sema Lisp interpreter instance.
Use InterpreterBuilder for fine-grained control, or call
Interpreter::new for a default interpreter with stdlib enabled.
Implementations§
Source§impl Interpreter
impl Interpreter
pub fn new() -> Self
Sourcepub fn builder() -> InterpreterBuilder
pub fn builder() -> InterpreterBuilder
Create an InterpreterBuilder for fine-grained configuration.
Sourcepub fn eval(&self, expr: &Value) -> EvalResult
pub fn eval(&self, expr: &Value) -> EvalResult
Evaluate a single parsed Value expression.
Definitions (define) persist across calls.
Sourcepub fn eval_str(&self, input: &str) -> EvalResult
pub fn eval_str(&self, input: &str) -> EvalResult
Parse and evaluate a string containing one or more Sema expressions.
Definitions (define) persist across calls, so you can define a
function in one call and use it in the next.
Sourcepub fn register_fn<F>(&self, name: &str, f: F)
pub fn register_fn<F>(&self, name: &str, f: F)
Register a native function that can be called from Sema code.
§Example
use sema::{Interpreter, Value, SemaError};
let interp = Interpreter::new();
interp.register_fn("square", |args: &[Value]| {
if let Some(n) = args[0].as_int() {
Ok(Value::int(n * n))
} else {
Err(SemaError::type_error("integer", args[0].type_name()))
}
});Sourcepub fn load_file(&self, path: impl AsRef<Path>) -> EvalResult
pub fn load_file(&self, path: impl AsRef<Path>) -> EvalResult
Load and evaluate a .sema file.
Definitions persist in the global environment, just like [eval_str].
let interp = Interpreter::new();
interp.load_file("prelude.sema").unwrap();
interp.eval_str("(my-prelude-fn 42)").unwrap();Sourcepub fn preload_module(&self, name: &str, source: &str) -> Result<()>
pub fn preload_module(&self, name: &str, source: &str) -> Result<()>
Pre-load a module into the module cache so that (import "name")
resolves without reading from disk.
The name is the string users pass to import. The source is
evaluated in an isolated module environment, and all top-level
bindings (or only export-ed ones) are cached.
let interp = Interpreter::new();
interp.preload_module("utils", r#"
(define (double x) (* x 2))
"#).unwrap();
interp.eval_str(r#"(import "utils")"#).unwrap();
interp.eval_str("(double 21)").unwrap(); // => 42Use (module name (export ...) ...) to control which bindings are visible:
let interp = Interpreter::new();
interp.preload_module("math", r#"
(module math (export square)
(define (square x) (* x x))
(define internal 42))
"#).unwrap();Sourcepub fn global_env(&self) -> &Rc<Env>
pub fn global_env(&self) -> &Rc<Env>
Return a reference to the global environment.
pub fn env(&self) -> &Rc<Env>
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Interpreter
impl !RefUnwindSafe for Interpreter
impl !Send for Interpreter
impl !Sync for Interpreter
impl Unpin for Interpreter
impl UnsafeUnpin for Interpreter
impl !UnwindSafe for Interpreter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more