Struct rhai::AST [−][src]
pub struct AST(_, _);
Expand description
Compiled AST (abstract syntax tree) of a Rhai script.
Currently, AST
is neither Send
nor Sync
. Turn on the sync
feature to make it Send + Sync
.
Implementations
pub fn statements(&self) -> &[Stmt]ⓘ
👎 Deprecated: this method is volatile and may change
pub fn statements(&self) -> &[Stmt]ⓘ
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 Module
containing all script-defined functions.
Exported under the internals
feature only.
Clone the AST
’s functions into a new AST
.
No statements are cloned.
This operation is cheap because functions are shared.
Clone the AST
’s functions into a new AST
based on a filter predicate.
No statements are cloned.
This operation is cheap because functions are shared.
Clone the AST
’s script statements into a new AST
.
No functions are cloned.
Merge 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(r#"
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(r#"
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!");
Merge 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(r#"
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, |_, name, params| 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!");
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
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(r#"
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, |_, name, params| 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!");
Filter out the functions, retaining only some based on a filter predicate.
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);
pub fn iter_functions<'a>(
&'a self
) -> impl Iterator<Item = (FnAccess, &str, usize, Rc<ScriptFnDef>)> + 'a
pub fn iter_functions<'a>(
&'a self
) -> impl Iterator<Item = (FnAccess, &str, usize, Rc<ScriptFnDef>)> + 'a
Iterate through all functions
Clear all function definitions in the AST
.
Clear all statements in the AST
, leaving only function definitions.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for AST
impl !UnwindSafe for AST
Blanket Implementations
Mutably borrows from an owned value. Read more