[−][src]Struct molt::interp::Interp
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::new(); let four = interp.eval("expr {2 + 2}")?; assert_eq!(four, Value::from(4));
Implementations
impl Interp
[src]
pub fn empty() -> Self
[src]
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::empty(); assert!(interp.command_names().is_empty());
pub fn new() -> Self
[src]
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::new(); let four = interp.eval("expr {2 + 2}")?; assert_eq!(four, Value::from(4));
pub fn eval(&mut self, script: &str) -> MoltResult
[src]
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::new(); 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()); } } }
pub fn eval_value(&mut self, value: &Value) -> MoltResult
[src]
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.
pub fn complete(&mut self, script: &str) -> bool
[src]
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::new(); assert!(interp.complete("set a [expr {1+1}]")); assert!(!interp.complete("set a [expr {1+1"));
pub fn expr(&mut self, expr: &Value) -> MoltResult
[src]
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::new(); let expr = Value::from("2 + 2"); let sum = interp.expr(&expr)?.as_int()?; assert_eq!(sum, 4);
pub fn expr_bool(&mut self, expr: &Value) -> Result<bool, Exception>
[src]
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::new(); let expr = Value::from("1 < 2"); let flag: bool = interp.expr_bool(&expr)?; assert!(flag);
pub fn expr_int(&mut self, expr: &Value) -> Result<MoltInt, Exception>
[src]
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::new(); let expr = Value::from("1 + 2"); let val: MoltInt = interp.expr_int(&expr)?; assert_eq!(val, 3);
pub fn expr_float(&mut self, expr: &Value) -> Result<MoltFloat, Exception>
[src]
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::new(); let expr = Value::from("1.1 + 2.2"); let val: MoltFloat = interp.expr_float(&expr)?; assert_eq!(val, 3.3);
pub fn var(&self, var_name: &Value) -> MoltResult
[src]
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::new(); // 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");
pub fn var_exists(&self, var_name: &Value) -> bool
[src]
Returns 1 if the named variable is defined and exists, and 0 otherwise.
pub fn set_var(
&mut self,
var_name: &Value,
value: Value
) -> Result<(), Exception>
[src]
&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::new(); // 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");
pub fn set_var_return(&mut self, var_name: &Value, value: Value) -> MoltResult
[src]
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::new(); // 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");
pub fn scalar(&self, name: &str) -> MoltResult
[src]
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::new(); // 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");
pub fn set_scalar(&mut self, name: &str, value: Value) -> Result<(), Exception>
[src]
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::new(); // Set the value of the scalar variable "a" interp.set_scalar("a", Value::from("1"))?; assert_eq!(interp.scalar("a")?.as_str(), "1");
pub fn set_scalar_return(&mut self, name: &str, value: Value) -> MoltResult
[src]
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::new(); // Set the value of the scalar variable "a" assert_eq!(interp.set_scalar_return("a", Value::from("1"))?.as_str(), "1");
pub fn element(&self, name: &str, index: &str) -> MoltResult
[src]
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::new(); // 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");
pub fn set_element(
&mut self,
name: &str,
index: &str,
value: Value
) -> Result<(), Exception>
[src]
&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::new(); // 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");
pub fn set_element_return(
&mut self,
name: &str,
index: &str,
value: Value
) -> MoltResult
[src]
&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::new(); // Set the value of the scalar variable "a" assert_eq!(interp.set_element_return("b", "1", Value::from("xyz"))?.as_str(), "xyz");
pub fn unset(&mut self, name: &str)
[src]
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::new(); 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
pub fn unset_var(&mut self, name: &Value)
[src]
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::new(); 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
pub fn unset_element(&mut self, array_name: &str, index: &str)
[src]
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::new(); interp.set_element("b", "1", Value::from("2"))?; interp.unset_element("b", "1");
pub fn vars_in_scope(&self) -> MoltList
[src]
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); }
pub fn vars_in_global_scope(&self) -> MoltList
[src]
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); }
pub fn vars_in_local_scope(&self) -> MoltList
[src]
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); }
pub fn upvar(&mut self, level: usize, name: &str)
[src]
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.
pub fn push_scope(&mut self)
[src]
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!
pub fn pop_scope(&mut self)
[src]
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.
pub fn scope_level(&self) -> usize
[src]
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.
pub fn array_exists(&self, array_name: &str) -> bool
[src]
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"));
pub fn array_get(&self, array_name: &str) -> MoltList
[src]
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); }
pub fn array_set(&mut self, array_name: &str, kvlist: &[Value]) -> MoltResult
[src]
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()])?;
pub fn array_names(&self, array_name: &str) -> MoltList
[src]
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); }
pub fn array_size(&self, array_name: &str) -> usize
[src]
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::new(); assert_eq!(interp.array_size("a"), 0); interp.set_element("a", "1", Value::from("xyz"))?; assert_eq!(interp.array_size("a"), 1);
pub fn add_command(&mut self, name: &str, func: CommandFunc)
[src]
Adds a binary command with no related context to the interpreter. This is the normal way to add most commands.
If the command needs access to some form of application or context data,
use add_context_command
instead. See the
module level documentation for an overview and examples.
pub fn add_context_command(
&mut self,
name: &str,
func: CommandFunc,
context_id: ContextID
)
[src]
&mut self,
name: &str,
func: CommandFunc,
context_id: ContextID
)
Adds a binary command with related context data to the interpreter.
This is the normal way to add commands requiring application context. See the module level documentation for an overview and examples.
pub fn has_command(&self, name: &str) -> bool
[src]
Determines whether or not the interpreter contains a command with the given name.
pub fn rename_command(&mut self, old_name: &str, new_name: &str)
[src]
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::new(); interp.rename_command("expr", "="); let sum = interp.eval("= {1 + 1}")?.as_int()?; assert_eq!(sum, 2);
pub fn remove_command(&mut self, name: &str)
[src]
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::new(); interp.remove_command("set"); // You'll be sorry.... assert!(!interp.has_command("set"));
pub fn command_names(&self) -> MoltList
[src]
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::new(); for name in interp.command_names() { println!("Found command: {}", name); }
pub fn command_type(&self, command: &str) -> MoltResult
[src]
Returns the body of the named procedure, or an error if the name doesn't name a procedure.
pub fn proc_names(&self) -> MoltList
[src]
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::new(); for name in interp.proc_names() { println!("Found procedure: {}", name); }
pub fn proc_body(&self, procname: &str) -> MoltResult
[src]
Returns the body of the named procedure, or an error if the name doesn't name a procedure.
pub fn proc_args(&self, procname: &str) -> MoltResult
[src]
Returns a list of the names of the arguments of the named procedure, or an error if the name doesn't name a procedure.
pub fn proc_default(
&self,
procname: &str,
arg: &str
) -> Result<Option<Value>, Exception>
[src]
&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.
pub fn call_subcommand(
&mut self,
context_id: ContextID,
argv: &[Value],
subc: usize,
subcommands: &[Subcommand]
) -> MoltResult
[src]
&mut self,
context_id: ContextID,
argv: &[Value],
subc: usize,
subcommands: &[Subcommand]
) -> MoltResult
Calls a subcommand of the current command, looking up its name in an array of
Subcommand
tuples.
The subcommand, if found, is called with the same context_id
and argv
as its
parent ensemble. subc
is the index of the subcommand's name in the argv
array;
in most cases it will be 1
, but it is possible to define subcommands with
subcommands of their own. The subcommands
argument is a borrow of an array of
Subcommand
records, each defining a subcommand's name and CommandFunc
.
If the subcommand name is found in the array, the matching CommandFunc
is called.
otherwise, the error message gives the ensemble syntax. If an invalid subcommand
name was provided, the error message includes the valid options.
See the implementation of the array
command in commands.rs
and the
module level documentation for examples.
pub fn recursion_limit(&self) -> usize
[src]
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::new(); assert_eq!(interp.recursion_limit(), 1000);
pub fn set_recursion_limit(&mut self, limit: usize)
[src]
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::new(); interp.set_recursion_limit(100); assert_eq!(interp.recursion_limit(), 100);
pub fn save_context<T: 'static>(&mut self, data: T) -> ContextID
[src]
Saves the client's context data in the interpreter's context cache, returning a generated context ID. Client commands can retrieve the data given the ID.
See the module level documentation for an overview and examples.
Example
use molt::types::*; use molt::interp::Interp; let mut interp = Interp::new(); let data: Vec<String> = Vec::new(); let id = interp.save_context(data);
pub fn context<T: 'static>(&mut self, id: ContextID) -> &mut T
[src]
Retrieves mutable client context data given the context ID.
See the module level documentation for an overview and examples.
Example
use molt::types::*; use molt::interp::Interp; let mut interp = Interp::new(); let data: Vec<String> = Vec::new(); let id = interp.save_context(data); // Later... let data: &mut Vec<String> = interp.context(id); data.push("New Value".into()); // Or let data = interp.context::<Vec<String>>(id); data.push("New Value".into());
Panics
This call panics if the context ID is unknown, or if the retrieved data has an unexpected type.
pub fn context_id(&mut self) -> ContextID
[src]
Generates a unique context ID for command context data.
Normally the client will use save_context
to
save the context data and generate the client ID in one operation, rather than
call this explicitly.
Example
use molt::types::*; use molt::interp::Interp; let mut interp = Interp::new(); let id1 = interp.context_id(); let id2 = interp.context_id(); assert_ne!(id1, id2);
pub fn set_context<T: 'static>(&mut self, id: ContextID, data: T)
[src]
Saves a client context value in the interpreter for the given context ID. Client commands can retrieve the data given the context ID.
Normally the client will use save_context
to
save the context data and generate the client ID in one operation, rather than
call this explicitly.
TODO: This method allows the user to generate a context ID and put data into the context cache as two separate steps; and to update the the data in the context cache for a given ID. I'm not at all sure that either of those things is a good idea. Waiting to see.
Example
use molt::types::*; use molt::interp::Interp; let mut interp = Interp::new(); let id = interp.context_id(); let data: Vec<String> = Vec::new(); interp.set_context(id, data);
pub fn profile_save(&mut self, name: &str, start: Instant)
[src]
Unstable; use at own risk.
pub fn profile_clear(&mut self)
[src]
Unstable; use at own risk.
pub fn profile_dump(&self)
[src]
Unstable; use at own risk.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for Interp
impl !Send for Interp
impl !Sync for Interp
impl Unpin for Interp
impl !UnwindSafe for Interp
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,