[][src]Module molt::interp

The Molt Interpreter

TODO: This should be primary documentation on using the Molt Interp.

The Interp struct is the primary API for embedding Molt into a Rust application. Given an Interp, the application may:

  • Evaluate scripts
  • Check scripts for completeness
  • Extend the language by defining new Molt commands in Rust
  • Set and get Molt variables in command bodies
  • Interpret Molt values as a variety of data types.
  • Access application data the context cache

The following describes the features of the Interp in general; follow the links for specifics of the various types and methods.

Interp is not Sync!

The Interp class (and the rest of Molt) is intended for use in a single thread. It is safe to have multiple Interps in different threads; but use String (or another Sync) when passing data between them. In particular, Value is not Sync.

Creating an Interpreter

There are two ways to create an interpreter. The usual way is to call Interp::new, which creates an interpreter and populates it with all of the standard Molt commands. Alternatively, Interp::empty creates an interpreter with no commands, allowing the application to define only those commands it needs. This is useful when the goal is to provide the application with a simple, non-scriptable console command set.

TODO: Define a way to add various subsets of the standard commands to an initially empty interpreter.

use molt::Interp;
let mut interp = Interp::new();
// ...

Evaluating Scripts

There are a number of ways to evaluate Molt scripts, all of which return MoltResult:

This example is not tested
pub type MoltResult = Result<Value, ResultCode>;

Value is the type of all Molt values (i.e., values that can be passed as parameters and stored in variables). ResultCode is an enum that encompasses all of the kinds of exceptional return from Molt code, including errors, return, break, and continue.

Interp::eval and Interp::eval_value evaluate a string as a Molt script, and return either a normal Value or a Molt error. The script is evaluated in the caller's context: if called at the application level, the script will be evaluated in the interpreter's global scope; if called by a Molt command, it will be evaluated in the scope in which that command is executing.

Interp::eval_body is used to evaluate the body of loops and other control structures. Unlike Interp::eval, it passes the return, break, and continue result codes back to the caller for handling.

Evaluating Expressions

In Molt, as in Standard Tcl, algebraic expressions are evaluated by the expr command. At the Rust level this feature is provided by the Interp::expr method, which takes the expression as a Value and returns the computed Value or an error.

There are three convenience methods, Interp::expr_bool, Interp::expr_int, and Interp::expr_float, which streamline the computation of a particular kind of value, and return an error if the computed result is not of that type.

Checking Scripts for Completeness

The Interp::complete checks whether a Molt script is complete: i.e., that it contains no unterminated quoted or braced strings that would prevent it from being evaluated as Molt code. This is primarily useful when implementing a Read-Eval-Print-Loop, as it allows the REPL to easily determine whether it should evaluate the input immediately or ask for an additional line of input.

Defining New Commands

The usual reason for embedding Molt in an application is to extend it with application-specific commands. There are a number of ways to do this.

The simplest method, and the one used by most of Molt's built-in commands, is to define a CommandFunc and register it with the interpreter using the Interp::add_command method:

pub type CommandFunc = fn(&mut Interp, &[Value]) -> MoltResult;

A CommandFunc is simply a Rust function that accepts an interpreter and a slice of Molt Value objects and returns a MoltResult. The slice of Value objects represents the name of the command and its arguments, which the function may interpret in any way it desires.

TODO: describe context commands and command objects.

TODO: flesh out Molt's ensemble command API, and then describe how to define ensemble commands.

Structs

Interp

The Molt Interpreter.