Manage AST‘s

When compiling a Rhai script to an AST, the following data are packaged together as a single unit:

DataTypeDescriptionAccess API
Source nameImmutableStringoptional text name to identify the source of the scriptsource(&self), clone_source(&self), set_source(&mut self, source), clear_source(&mut self)
StatementsVec<Stmt>list of script statements at global levelstatements(&self), statements_mut(&mut self) (only available under internals)
Functions (not available under no_function)Modulefunctions defined in the scriptshared_lib(&self), lib(&self) (only available under internals)
Embedded module resolver (not available under no_module)StaticModuleResolverembedded module resolver for self-contained ASTresolver(&self) (only available under internals)

Use the source name to identify the source script in errors – useful when multiple modules are imported recursively.

Most of the AST API is available only under the internals feature.

For the complete AST API, refer to the documentation online.

Extract Only Functions

The following methods, not available under no_function, allow manipulation of the functions encapsulated within an AST:

MethodDescription
clone_functions_only(&self)clone the AST into a new AST with only functions, excluding statements
clone_functions_only_filtered(&self, filter)clone the AST into a new AST with only functions that pass the filter predicate, excluding statements
retain_functions(&mut self, filter)remove all functions in the AST that do not pass a particular predicate filter; statements are untouched
iter_functions(&self)return an iterator on all the functions in the AST
clear_functions(&mut self)remove all functions from the AST, leaving only statements

Extract Only Statements

The following methods allow manipulation of the statements in an AST:

MethodDescription
clone_statements_only(&self)clone the AST into a new AST with only the statements, excluding functions
clear_statements(&mut self)remove all statements from the AST, leaving only functions

Merge and Combine AST’s

The following methods merge one AST with another:

MethodDescription
merge(&self, &second), + operatorappend the second AST to this AST, yielding a new AST that is a combination of the two; statements are simply appended, functions in the second AST of the same name and arity override similar functions in this AST
merge_filtered(&self, &second, filter)append the second AST (but only functions that pass the predicate filter) to this AST, yielding a new AST that is a combination of the two; statements are simply appended, functions in the second AST of the same name and arity override similar functions in this AST
combine(&mut self, second), += operatorappend the second AST to this AST; statements are simply appended, functions in the second AST of the same name and arity override similar functions in this AST
combine_filtered(&mut self, second, filter)append the second AST (but only functions that pass the predicate filter) to this AST; statements are simply appended, functions in the second AST of the same name and arity override similar functions in this AST

When statements are appended, beware that this may change the semantics of the script.


#![allow(unused)]
fn main() {
// First script
let ast1 = engine.compile(
"
     fn foo(x) { 42 + x }
     foo(1)
")?;

// Second script
let ast2 = engine.compile(
r#"
     fn foo(n) { `hello${n}` }
     foo("!")
"#)?;

// Merge them
let merged = ast1.merge(&ast2);

// Notice that using the '+' operator also works:
let merged = &ast1 + &ast2;
}

merged in the above example essentially contains the following script program:

fn foo(n) { `hello${n}` }   // <- definition of first 'foo' is overwritten
foo(1)                      // <- notice this will be "hello1" instead of 43,
                            //    but it is no longer the return value
foo("!")                    // <- returns "hello!"

Walk an AST

The internals feature allows access to internal Rhai data structures, particularly the nodes that make up the AST.

AST node types

There are a few useful types when walking an AST:

TypeDescription
ASTNodean enum with two variants: Expr or Stmt
Expran expression
Stmta statement
BinaryExpra sub-type containing the LHS and RHS of a binary expression
FnCallExpra sub-type containing information on a function call
CustomExpra sub-type containing information on a custom syntax expression

The AST::walk method takes a callback function and recursively walks the AST in depth-first manner, with the parent node visited before its children.

Callback function signature

The function signature of the callback function is:

FnMut(&[ASTNode]) -> bool

The single argument passed to the method contains a slice of ASTNode types representing the path from the current node to the root of the AST.

Return true to continue walking the AST, or false to terminate.

Children visit order

The order of visits to the children of each node type:

Node typeChildren visit order
if statementcondition expression, then statements, else statements (if any)
switch statementmatch element, each of the case conditions and statements, default statements (if any)
while, do, loop statementcondition expression, statements body
for statementcollection expression, statements body
try ... catch statementtry statements body, catch statements body
return statementreturn value expression
import statementpath expression
Array literaleach of the element expressions
Object map literaleach of the element expressions
Interpolated stringeach of the string/expression segments
IndexingLHS, RHS
Field access/method callLHS, RHS
&&, ||LHS, RHS
Function call, operator expressioneach of the argument expressions
let, const statementvalue expression
Assignment statementl-value expression, value expression
Statements blockeach of the statements
Custom syntax expressioneach of the $expr$, $stmt$, $ident$, $bool$, $int$, $float$, $string$ blocks
All otherssingle child, or none