Struct molt_forked::interp::Interp

source ·
pub struct Interp<Ctx>
where Ctx: 'static,
{ pub context: Ctx, /* private fields */ }
Expand description

The Molt Interpreter.

The Interp struct is the primary API for embedding Molt into a Rust application. The application creates an instance of Interp, configures with it the required set of application-specific and standard Molt commands, and then uses it to evaluate Molt scripts and expressions. See the module level documentation for an overview.

§Example

By default, the Interp comes configured with the full set of standard Molt commands.

use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();
let four = interp.eval("expr {2 + 2}")?;
assert_eq!(four, Value::from(4));

The Interp can be associated with a lifetime. If so, it is allowed to create contexts consisting of references and mutable references within that lifetime. Under the hood, the references are stored as raw pointers.

Fields§

§context: Ctx

Embedded context

Implementations§

source§

impl Interp<()>

source

pub fn default() -> Self

Creates a new Molt interpreter with no commands defined. Use this when crafting command languages that shouldn’t include the normal TCL commands, or as a base to which specific Molt command sets can be added.

§Example
let mut interp = Interp::default(());
source§

impl<Ctx> Interp<Ctx>
where Ctx: 'static,

source

pub fn contains_proc(&self, proc_name: &str) -> bool

source

pub fn get_proc(&self, proc_name: &str) -> Option<&Rc<Procedure>>

source

pub fn new( context: Ctx, command: Command<Ctx>, use_env: bool, name: &'static str, ) -> Self

Creates a new Molt interpreter that is pre-populated with the standard Molt commands. Use command_names (or the info commands Molt command) to retrieve the full list, and the add_command family of methods to extend the interpreter with new commands.

TODO: Define command sets (sets of commands that go together, so that clients can add or remove them in groups).

let mut interp = Interp::default();
let four = interp.eval("expr {2 + 2}")?;
assert_eq!(four, Value::from(4));
source

pub fn eval(&mut self, script: &str) -> MoltResult

Evaluates a script one command at a time. Returns the Value of the last command in the script, or the value of any explicit return call in the script, or any error thrown by the script. Other Exception values are converted to normal errors.

Use this method (or eval_value) to evaluate arbitrary scripts, control structure bodies, and so forth. Prefer eval_value if the script is already stored in a Value, as it will be more efficient if the script is evaluated multiple times.

§Example

The following code shows how to evaluate a script and handle the result, whether it’s a computed Value or an error message (which is also a Value).


let mut interp = Interp::default();

let input = "set a 1";

match interp.eval(input) {
   Ok(val) => {
       // Computed a Value
       println!("Value: {}", val);
   }
   Err(exception) => {
       if exception.is_error() {
           // Got an error; print it out.
           println!("Error: {}", exception.value());
       } else {
           // It's a Return.
           println!("Value: {}", exception.value());
       }
   }
}
source

pub fn eval_value(&mut self, value: &Value) -> MoltResult

Evaluates the string value of a Value as a script. Returns the Value of the last command in the script, or the value of any explicit return call in the script, or any error thrown by the script. Other Exception values are converted to normal errors.

This method is equivalent to eval, but works on a Value rather than on a string slice. Use it or eval to evaluate arbitrary scripts, control structure bodies, and so forth. Prefer this to eval if the script is already stored in a Value, as it will be more efficient if the script is evaluated multiple times.

source

pub fn complete(&mut self, script: &str) -> bool

Determines whether or not the script is syntactically complete, e.g., has no unmatched quotes, brackets, or braces.

REPLs use this to determine whether or not to ask for another line of input.

§Example
let mut interp = Interp::default();
assert!(interp.complete("set a [expr {1+1}]"));
assert!(!interp.complete("set a [expr {1+1"));
source

pub fn expr(&mut self, expr: &Value) -> MoltResult

Evaluates a Molt expression and returns its value. The expression is passed as a Value which is interpreted as a String.

§Example
use molt::Interp;
use molt::types::*;
let mut interp = Interp::default();
let expr = Value::from("2 + 2");
let sum = interp.expr(&expr)?.as_int()?;

assert_eq!(sum, 4);
source

pub fn expr_bool(&mut self, expr: &Value) -> Result<bool, Exception>

Evaluates a boolean Molt expression and returns its value, or an error if it couldn’t be interpreted as a boolean.

§Example
use molt::Interp;
use molt::types::*;
let mut interp = Interp::default();

let expr = Value::from("1 < 2");
let flag: bool = interp.expr_bool(&expr)?;

assert!(flag);
source

pub fn expr_int(&mut self, expr: &Value) -> Result<MoltInt, Exception>

Evaluates a Molt expression and returns its value as an integer, or an error if it couldn’t be interpreted as an integer.

§Example
use molt::Interp;
use molt::types::*;
let mut interp = Interp::default();

let expr = Value::from("1 + 2");
let val: MoltInt = interp.expr_int(&expr)?;

assert_eq!(val, 3);
source

pub fn expr_float(&mut self, expr: &Value) -> Result<MoltFloat, Exception>

Evaluates a Molt expression and returns its value as a float, or an error if it couldn’t be interpreted as a float.

§Example
use molt::Interp;
use molt::types::*;
let mut interp = Interp::default();

let expr = Value::from("1.1 + 2.2");
let val: MoltFloat = interp.expr_float(&expr)?;

assert_eq!(val, 3.3);
source

pub fn var(&self, var_name: &Value) -> MoltResult

Retrieves the value of the named variable in the current scope. The var_name may name a scalar variable or an array element. This is the normal way to retrieve the value of a variable named by a command argument.

Returns an error if the variable is a scalar and the name names an array element, and vice versa.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a" using a script.
interp.eval("set a 1")?;

// The value of the scalar variable "a".
let val = interp.var(&Value::from("a"))?;
assert_eq!(val.as_str(), "1");

// Set the value of the array element "b(1)" using a script.
interp.eval("set b(1) Howdy")?;

// The value of the array element "b(1)":
let val = interp.var(&Value::from("b(1)"))?;
assert_eq!(val.as_str(), "Howdy");
source

pub fn var_exists(&self, var_name: &Value) -> bool

Returns 1 if the named variable is defined and exists, and 0 otherwise.

source

pub fn set_var( &mut self, var_name: &Value, value: Value, ) -> Result<(), Exception>

Sets the value of the variable in the current scope. The var_name may name a scalar variable or an array element. This is the usual way to assign a value to a variable named by a command argument.

Returns an error if the variable is scalar and the name names an array element, and vice-versa.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a"
let scalar = Value::from("a");  // The variable name
interp.set_var(&scalar, Value::from("1"))?;
assert_eq!(interp.var(&scalar)?.as_str(), "1");

// Set the value of the array element "b(1)":
let element = Value::from("b(1)");  // The variable name
interp.set_var(&element, Value::from("howdy"))?;
assert_eq!(interp.var(&element)?.as_str(), "howdy");
source

pub fn set_var_return(&mut self, var_name: &Value, value: Value) -> MoltResult

Sets the value of the variable in the current scope, return its value. The var_name may name a scalar variable or an array element. This is the usual way to assign a value to a variable named by a command argument when the command is expected to return the value.

Returns an error if the variable is scalar and the name names an array element, and vice-versa.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a"
let scalar = Value::from("a");  // The variable name
assert_eq!(interp.set_var_return(&scalar, Value::from("1"))?.as_str(), "1");

// Set the value of the array element "b(1)":
let element = Value::from("b(1)");  // The variable name
interp.set_var(&element, Value::from("howdy"))?;
assert_eq!(interp.set_var_return(&element, Value::from("1"))?.as_str(), "1");
source

pub fn scalar(&self, name: &str) -> MoltResult

Retrieves the value of the named scalar variable in the current scope.

Returns an error if the variable is not found, or if the variable is an array variable.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a" using a script.
interp.eval("set a 1")?;

// The value of the scalar variable "a".
let val = interp.scalar("a")?;
assert_eq!(val.as_str(), "1");
source

pub fn set_scalar(&mut self, name: &str, value: Value) -> Result<(), Exception>

Sets the value of the named scalar variable in the current scope, creating the variable if necessary.

Returns an error if the variable exists and is an array variable.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a"
interp.set_scalar("a", Value::from("1"))?;
assert_eq!(interp.scalar("a")?.as_str(), "1");
source

pub fn set_scalar_return(&mut self, name: &str, value: Value) -> MoltResult

Sets the value of the named scalar variable in the current scope, creating the variable if necessary, and returning the value.

Returns an error if the variable exists and is an array variable.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a"
assert_eq!(interp.set_scalar_return("a", Value::from("1"))?.as_str(), "1");
source

pub fn element(&self, name: &str, index: &str) -> MoltResult

Retrieves the value of the named array element in the current scope.

Returns an error if the element is not found, or the variable is not an array variable.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the array element variable "a(1)" using a script.
interp.eval("set a(1) Howdy")?;

// The value of the array element "a(1)".
let val = interp.element("a", "1")?;
assert_eq!(val.as_str(), "Howdy");
source

pub fn set_element( &mut self, name: &str, index: &str, value: Value, ) -> Result<(), Exception>

Sets the value of an array element in the current scope, creating the variable if necessary.

Returns an error if the variable exists and is not an array variable.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a"
interp.set_element("b", "1", Value::from("xyz"))?;
assert_eq!(interp.element("b", "1")?.as_str(), "xyz");
source

pub fn set_element_return( &mut self, name: &str, index: &str, value: Value, ) -> MoltResult

Sets the value of an array element in the current scope, creating the variable if necessary, and returning the value.

Returns an error if the variable exists and is not an array variable.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

// Set the value of the scalar variable "a"
assert_eq!(interp.set_element_return("b", "1", Value::from("xyz"))?.as_str(), "xyz");
source

pub fn unset(&mut self, name: &str)

Unsets a variable, whether scalar or array, given its name in the current scope. For arrays this is the name of the array proper, e.g., myArray, not the name of an element, e.g., myArray(1).

It is not an error to unset a variable that doesn’t exist.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

interp.set_scalar("a", Value::from("1"))?;
interp.set_element("b", "1", Value::from("2"))?;

interp.unset("a"); // Unset scalar
interp.unset("b"); // Unset entire array
source

pub fn unset_var(&mut self, name: &Value)

Unsets the value of the named variable or array element in the current scope.

It is not an error to unset a variable that doesn’t exist.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

let scalar = Value::from("a");
let array = Value::from("b");
let elem = Value::from("b(1)");

interp.unset_var(&scalar); // Unset scalar
interp.unset_var(&elem);   // Unset array element
interp.unset_var(&array);  // Unset entire array
source

pub fn unset_element(&mut self, array_name: &str, index: &str)

Unsets a single element in an array given the array name and index.

It is not an error to unset an array element that doesn’t exist.

§Example
use molt::types::*;
use molt::Interp;
use molt::molt_ok;
let mut interp = Interp::default();

interp.set_element("b", "1", Value::from("2"))?;

interp.unset_element("b", "1");
source

pub fn vars_in_scope(&self) -> MoltList

Gets a list of the names of the variables that are visible in the current scope. The list includes the names of array variables but not elements within them.

§Example
use molt::Interp;
use molt::types::*;

for name in interp.vars_in_scope() {
    println!("Found variable: {}", name);
}
source

pub fn vars_in_global_scope(&self) -> MoltList

Gets a list of the names of the variables defined in the global scope. The list includes the names of array variables but not elements within them.

§Example
use molt::Interp;
use molt::types::*;

for name in interp.vars_in_global_scope() {
    println!("Found variable: {}", name);
}
source

pub fn vars_in_local_scope(&self) -> MoltList

Gets a list of the names of the variables defined in the local scope. This does not include variables brought into scope via global or upvar, or any variables defined in the global scope. The list includes the names of array variables but not elements within them.

§Example
use molt::Interp;
use molt::types::*;

for name in interp.vars_in_local_scope() {
    println!("Found variable: {}", name);
}
source

pub fn upvar(&mut self, level: usize, name: &str)

Links the variable name in the current scope to the given scope. Note: the level is the absolute level, not the level relative to the current stack level, i.e., level=0 is the global scope.

This method is used to implement the upvar command, which allows variables to be passed by name; client code should rarely need to access it directly.

source

pub fn push_scope(&mut self)

Pushes a variable scope (i.e., a stack level) onto the scope stack.

Procs use this to define their local scope. Client code should seldom need to call this directly, but it can be useful in a few cases. For example, the Molt test harness’s test command runs its body in a local scope as an aid to test cleanup.

Note: a command that pushes a scope must also call Interp::pop_scope before it exits!

source

pub fn pop_scope(&mut self)

Pops a variable scope (i.e., a stack level) off of the scope stack. Calls to Interp::push_scope and Interp::pop_scope must exist in pairs.

source

pub fn scope_level(&self) -> usize

Return the current scope level. The global scope is level 0; each call to Interp::push_scope adds a level, and each call to Interp::pop_scope removes it. This method is used with Interp::upvar to access the caller’s scope when a variable is passed by name.

source

pub fn array_exists(&self, array_name: &str) -> bool

Determines whether or not the name is the name of an array variable.

§Example
interp.set_scalar("a", Value::from(1))?;
interp.set_element("b", "1", Value::from(2));

assert!(!interp.array_exists("a"));
assert!(interp.array_exists("b"));
source

pub fn array_get(&self, array_name: &str) -> MoltList

Gets a flat vector of the keys and values from the named array. This is used to implement the array get command.

§Example
use molt::Interp;
use molt::types::*;

for txt in interp.array_get("myArray") {
    println!("Found index or value: {}", txt);
}
source

pub fn array_set(&mut self, array_name: &str, kvlist: &[Value]) -> MoltResult

Merges a flat vector of keys and values into the named array. It’s an error if the vector has an odd number of elements, or if the named variable is a scalar. This method is used to implement the array set command.

§Example

For example, the following Rust code is equivalent to the following Molt code:

# Set individual elements
set myArray(a) 1
set myArray(b) 2

# Set all at once
array set myArray { a 1 b 2 }
use molt::Interp;
use molt::types::*;

interp.array_set("myArray", &vec!["a".into(), "1".into(), "b".into(), "2".into()])?;
source

pub fn array_names(&self, array_name: &str) -> MoltList

Gets a list of the indices of the given array. This is used to implement the array names command. If the variable does not exist (or is not an array variable), the method returns the empty list.

§Example
use molt::Interp;
use molt::types::*;

for name in interp.array_names("myArray") {
    println!("Found index : {}", name);
}
source

pub fn array_size(&self, array_name: &str) -> usize

Gets the number of elements in the named array. Returns 0 if the variable doesn’t exist (or isn’t an array variable).

§Example
use molt::Interp;
use molt::types::*;

let mut interp = Interp::default();

assert_eq!(interp.array_size("a"), 0);

interp.set_element("a", "1", Value::from("xyz"))?;
assert_eq!(interp.array_size("a"), 1);
source

pub fn has_proc(&self, name: &str) -> bool

Determines whether or not the interpreter contains a command with the given name.

source

pub fn rename_proc(&mut self, old_name: &str, new_name: &str)

Renames the command.

Note: This does not update procedures that reference the command under the old name. This is intentional: it is a common TCL programming technique to wrap an existing command by renaming it and defining a new command with the old name that calls the original command at its new name.

§Example
use molt::Interp;
use molt::types::*;
use molt::molt_ok;
let mut interp = Interp::default();

interp.rename_command("expr", "=");

let sum = interp.eval("= {1 + 1}")?.as_int()?;

assert_eq!(sum, 2);
source

pub fn remove_proc(&mut self, name: &str)

Removes the command with the given name.

This would typically be done when destroying an object command.

§Example
use molt::Interp;
use molt::types::*;
use molt::molt_ok;

let mut interp = Interp::default();

interp.remove_command("set");  // You'll be sorry....

assert!(!interp.has_command("set"));
source

pub fn command_names(&self) -> MoltList

Gets a vector of the names of the existing commands.

§Example
use molt::Interp;
use molt::types::*;
use molt::molt_ok;

let mut interp = Interp::default();

for name in interp.command_names() {
    println!("Found command: {}", name);
}
source

pub fn native_command_names(&self) -> String

source

pub fn proc_command_names(&self) -> String

source

pub fn command_type(&self, cmd_name: &str) -> MoltResult

Returns the body of the named procedure, or an error if the name doesn’t name a procedure.

source

pub fn proc_names(&self) -> MoltList

Gets a vector of the names of the existing procedures.

§Example
use molt::Interp;
use molt::types::*;
use molt::molt_ok;

let mut interp = Interp::default();

for name in interp.proc_names() {
    println!("Found procedure: {}", name);
}
source

pub fn proc_body(&self, procname: &str) -> MoltResult

Returns the body of the named procedure, or an error if the name doesn’t name a procedure.

source

pub fn proc_args(&self, procname: &str) -> MoltResult

Returns a list of the names of the arguments of the named procedure, or an error if the name doesn’t name a procedure.

source

pub fn proc_default( &self, procname: &str, arg: &str, ) -> Result<Option<Value>, Exception>

Returns the default value of the named argument of the named procedure, if it has one. Returns an error if the procedure has no such argument, or the procname doesn’t name a procedure.

source

pub fn recursion_limit(&self) -> usize

Gets the interpreter’s recursion limit: how deep the stack of script evaluations may be.

A script stack level is added by each nested script evaluation (i.e., by each call) to eval or eval_value.

§Example
let mut interp = Interp::default();
assert_eq!(interp.recursion_limit(), 1000);
source

pub fn set_recursion_limit(&mut self, limit: usize)

Sets the interpreter’s recursion limit: how deep the stack of script evaluations may be. The default is 1000.

A script stack level is added by each nested script evaluation (i.e., by each call) to eval or eval_value.

§Example
let mut interp = Interp::default();
interp.set_recursion_limit(100);
assert_eq!(interp.recursion_limit(), 100);
source

pub fn profile_save(&mut self, name: &str, start: Instant)

Unstable; use at own risk.

source

pub fn profile_clear(&mut self)

Unstable; use at own risk.

source

pub fn profile_dump(&self)

Unstable; use at own risk.

source

pub fn continue_on_error(&self) -> bool

get the current continue on error setting. the default is false.

§Example
let mut interp = Interp::default();
assert_eq!(interp.continue_on_error(), false);
source

pub fn set_continue_on_error(&mut self, c: bool)

set whether to continue anyway in case of error.

§Example
let mut interp = Interp::default();
interp.set_continue_on_error(true);
assert_eq!(interp.continue_on_error(), true);

Auto Trait Implementations§

§

impl<Ctx> Freeze for Interp<Ctx>
where Ctx: Freeze,

§

impl<Ctx> !RefUnwindSafe for Interp<Ctx>

§

impl<Ctx> !Send for Interp<Ctx>

§

impl<Ctx> !Sync for Interp<Ctx>

§

impl<Ctx> Unpin for Interp<Ctx>
where Ctx: Unpin,

§

impl<Ctx> !UnwindSafe for Interp<Ctx>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.