Struct rhai::AST [−][src]
pub struct AST { /* fields omitted */ }Expand description
Compiled AST (abstract syntax tree) of a Rhai script.
Thread Safety
Currently, AST is neither Send nor Sync. Turn on the sync feature to make it Send + Sync.
Implementations
Create a new AST.
pub fn new_with_source(
statements: impl IntoIterator<Item = Stmt>,
functions: impl Into<Shared<Module>>,
source: impl Into<Identifier>
) -> Self
pub fn new_with_source(
statements: impl IntoIterator<Item = Stmt>,
functions: impl Into<Shared<Module>>,
source: impl Into<Identifier>
) -> SelfCreate a new AST with a source name.
Set the source.
Clear the source.
👎 Deprecated: this method is volatile and may change
this method is volatile and may change
(INTERNALS) Get the statements.
Exported under the internals feature only.
👎 Deprecated: this method is volatile and may change
this method is volatile and may change
(INTERNALS) Get the internal shared Module containing all script-defined functions.
Exported under the internals feature only.
Not available under no_function or no_module.
👎 Deprecated: this method is volatile and may change
this method is volatile and may change
(INTERNALS) Get the internal Module containing all script-defined functions.
Exported under the internals feature only.
Not available under no_function.
(INTERNALS) Get the embedded module resolver.
Exported under the internals feature only.
Not available under no_module.
pub fn clone_functions_only_filtered(
&self,
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool
) -> Self
pub fn clone_functions_only_filtered(
&self,
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool
) -> SelfMerge two AST into one. Both AST’s are untouched and a new, merged,
version is returned.
Statements in the second AST are simply appended to the end of the first without any processing.
Thus, the return value of the first AST (if using expression-statement syntax) is buried.
Of course, if the first AST uses a return statement at the end, then
the second AST will essentially be dead code.
All script-defined functions in the second AST overwrite similarly-named functions
in the first AST with the same number of parameters.
Example
use rhai::Engine; let engine = Engine::new(); let ast1 = engine.compile(" fn foo(x) { 42 + x } foo(1) ")?; let ast2 = engine.compile(r#" fn foo(n) { `hello${n}` } foo("!") "#)?; let ast = ast1.merge(&ast2); // Merge 'ast2' into 'ast1' // Notice that using the '+' operator also works: // let ast = &ast1 + &ast2; // 'ast' is essentially: // // 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!" // Evaluate it assert_eq!(engine.eval_ast::<String>(&ast)?, "hello!");
Combine one AST with another. The second AST is consumed.
Statements in the second AST are simply appended to the end of the first without any processing.
Thus, the return value of the first AST (if using expression-statement syntax) is buried.
Of course, if the first AST uses a return statement at the end, then
the second AST will essentially be dead code.
All script-defined functions in the second AST overwrite similarly-named functions
in the first AST with the same number of parameters.
Example
use rhai::Engine; let engine = Engine::new(); let mut ast1 = engine.compile(" fn foo(x) { 42 + x } foo(1) ")?; let ast2 = engine.compile(r#" fn foo(n) { `hello${n}` } foo("!") "#)?; ast1.combine(ast2); // Combine 'ast2' into 'ast1' // Notice that using the '+=' operator also works: // ast1 += ast2; // 'ast1' is essentially: // // 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!" // Evaluate it assert_eq!(engine.eval_ast::<String>(&ast1)?, "hello!");
pub fn merge_filtered(
&self,
other: &Self,
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool
) -> Self
pub fn merge_filtered(
&self,
other: &Self,
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool
) -> SelfMerge two AST into one. Both AST’s are untouched and a new, merged, version
is returned.
Statements in the second AST are simply appended to the end of the first without any processing.
Thus, the return value of the first AST (if using expression-statement syntax) is buried.
Of course, if the first AST uses a return statement at the end, then
the second AST will essentially be dead code.
All script-defined functions in the second AST are first selected based on a filter
predicate, then overwrite similarly-named functions in the first AST with the
same number of parameters.
Example
use rhai::Engine; let engine = Engine::new(); let ast1 = engine.compile(" fn foo(x) { 42 + x } foo(1) ")?; let ast2 = engine.compile(r#" fn foo(n) { `hello${n}` } fn error() { 0 } foo("!") "#)?; // Merge 'ast2', picking only 'error()' but not 'foo(_)', into 'ast1' let ast = ast1.merge_filtered(&ast2, |_, _, script, name, params| script && name == "error" && params == 0); // 'ast' is essentially: // // fn foo(n) { 42 + n } // <- definition of 'ast1::foo' is not overwritten // // because 'ast2::foo' is filtered away // foo(1) // <- notice this will be 43 instead of "hello1", // // but it is no longer the return value // fn error() { 0 } // <- this function passes the filter and is merged // foo("!") // <- returns "42!" // Evaluate it assert_eq!(engine.eval_ast::<String>(&ast)?, "42!");
pub fn combine_filtered(
&mut self,
other: Self,
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool
) -> &mut Self
pub fn combine_filtered(
&mut self,
other: Self,
filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool
) -> &mut SelfCombine one AST with another. The second AST is consumed.
Statements in the second AST are simply appended to the end of the first without any processing.
Thus, the return value of the first AST (if using expression-statement syntax) is buried.
Of course, if the first AST uses a return statement at the end, then
the second AST will essentially be dead code.
All script-defined functions in the second AST are first selected based on a filter
predicate, then overwrite similarly-named functions in the first AST with the
same number of parameters.
Example
use rhai::Engine; let engine = Engine::new(); let mut ast1 = engine.compile(" fn foo(x) { 42 + x } foo(1) ")?; let ast2 = engine.compile(r#" fn foo(n) { `hello${n}` } fn error() { 0 } foo("!") "#)?; // Combine 'ast2', picking only 'error()' but not 'foo(_)', into 'ast1' ast1.combine_filtered(ast2, |_, _, script, name, params| script && name == "error" && params == 0); // 'ast1' is essentially: // // fn foo(n) { 42 + n } // <- definition of 'ast1::foo' is not overwritten // // because 'ast2::foo' is filtered away // foo(1) // <- notice this will be 43 instead of "hello1", // // but it is no longer the return value // fn error() { 0 } // <- this function passes the filter and is merged // foo("!") // <- returns "42!" // Evaluate it assert_eq!(engine.eval_ast::<String>(&ast1)?, "42!");
pub fn retain_functions(
&mut self,
filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool
) -> &mut Self
pub fn retain_functions(
&mut self,
filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool
) -> &mut SelfFilter out the functions, retaining only some based on a filter predicate.
Not available under no_function.
Example
use rhai::Engine; let engine = Engine::new(); let mut ast = engine.compile(r#" fn foo(n) { n + 1 } fn bar() { print("hello"); } "#)?; // Remove all functions except 'foo(_)' ast.retain_functions(|_, _, name, params| name == "foo" && params == 1);
Iterate through all function definitions.
Not available under no_function.
Clear all function definitions in the AST.
Not available under no_function.
Clear all statements in the AST, leaving only function definitions.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for ASTimpl !UnwindSafe for ASTBlanket Implementations
Mutably borrows from an owned value. Read more