1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
/// A lightweight interpreter interface. pub trait Interpreter: 'static { /// The value type the interpreter uses and returns. /// /// It is usually a trait object that allows supporting different kinds /// of actual values. /// /// Refer to the `value` module for example implementations. type Value: Clone; /// The error type that the interpreter raises. /// /// Could be a string, or the same as the `Value` type, or a dedicated /// error type. type Error: From<String> + From<&'static String>; /// The environment type that is used to evaluate code. /// /// Environments are complementary (mutable) structures that helps /// resolving static expressions. /// /// For example, environments might include these kinds of information: /// - The state (registers, heap and the stack). Tracking local and outer /// variables. /// - What to do next (the program counter). Making it possible to suspend /// and resume execution. This would require explicit support from the /// stdlib so execution can be suspended and resumed. /// /// Refer to the `env` module for example implementations. type Env; /// The expression type. /// /// The type that can represent parsed code of this language. /// If the language wants to operate code as data, then there /// needs a way to convert `Expr` to `Value`. /// For interpreters that use bytecode, this might also include /// the bytecode. /// /// Refer to the `expr` module for example implementations. type Expr; /// Evaluate code in string. This is a shortcut for calling `parse`, and /// `evaluate` with `global_env()`. fn interpret(code: &str) -> Result<Self::Value, Self::Error> { let env = Self::global_env(); let expr = Self::parse(code)?; Self::evaluate(&env, &expr) } /// Parse code into an `Expr`. /// /// For interpreters that use bytecode, consider compiling the code into /// bytecode in this function. fn parse(code: &str) -> Result<Self::Expr, Self::Error>; /// Define the default global environment. /// /// Usually this defines the standard library. fn global_env() -> Self::Env; /// Evaluate an expression in a given environment. fn evaluate(env: &Self::Env, expr: &Self::Expr) -> Result<Self::Value, Self::Error>; }