[−][src]Struct rhai::AST
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
impl AST
[src]
pub fn new(statements: Vec<Stmt>, lib: Module) -> Self
[src]
Create a new AST
.
pub fn statements(&self) -> &[Stmt]ⓘ
[src]
this method is volatile and may change
[INTERNALS] Get the statements.
pub fn lib(&self) -> &Module
[src]
this method is volatile and may change
[INTERNALS] Get the internal Module
containing all script-defined functions.
pub fn clone_functions_only(&self) -> Self
[src]
Clone the AST
's functions into a new AST
.
No statements are cloned.
This operation is cheap because functions are shared.
pub fn clone_functions_only_filtered(
&self,
filter: impl Fn(FnAccess, &str, usize) -> bool
) -> Self
[src]
&self,
filter: impl Fn(FnAccess, &str, usize) -> bool
) -> Self
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.
pub fn clone_statements_only(&self) -> Self
[src]
Clone the AST
's script statements into a new AST
.
No functions are cloned.
pub fn merge(&self, other: &Self) -> Self
[src]
Merge two AST
into one. Both AST
's are untouched and a new, merged, version
is returned.
The second AST
is 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!");
pub fn merge_filtered(
&self,
other: &Self,
filter: impl Fn(FnAccess, &str, usize) -> bool
) -> Self
[src]
&self,
other: &Self,
filter: impl Fn(FnAccess, &str, usize) -> bool
) -> Self
Merge two AST
into one. Both AST
's are untouched and a new, merged, version
is returned.
The second AST
is 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!");
pub fn retain_functions(
&mut self,
filter: impl Fn(FnAccess, &str, usize) -> bool
)
[src]
&mut self,
filter: impl Fn(FnAccess, &str, usize) -> bool
)
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 clear_functions(&mut self)
[src]
Clear all function definitions in the AST
.
pub fn clear_statements(&mut self)
[src]
Clear all statements in the AST
, leaving only function definitions.
Trait Implementations
impl<'_> Add<&'_ AST> for &'_ AST
[src]
type Output = AST
The resulting type after applying the +
operator.
fn add(self, rhs: Self) -> Self::Output
[src]
impl AsRef<[Stmt]> for AST
[src]
impl AsRef<Module> for AST
[src]
impl Clone for AST
[src]
impl Debug for AST
[src]
impl Default for AST
[src]
Auto Trait Implementations
impl !RefUnwindSafe for AST
impl !Send for AST
impl !Sync for AST
impl Unpin for AST
impl !UnwindSafe for AST
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,
fn borrow(&self) -> &TⓘImportant traits for &'_ mut R
impl<'_, R> Read for &'_ mut R where
R: Read + ?Sized, impl<'_, W> Write for &'_ mut W where
W: Write + ?Sized, impl<'_, I> Iterator for &'_ mut I where
I: Iterator + ?Sized, type Item = <I as Iterator>::Item;impl<'_, F> Future for &'_ mut F where
F: Unpin + Future + ?Sized, type Output = <F as Future>::Output;
[src]
Important traits for &'_ mut R
impl<'_, R> Read for &'_ mut R where
R: Read + ?Sized, impl<'_, W> Write for &'_ mut W where
W: Write + ?Sized, impl<'_, I> Iterator for &'_ mut I where
I: Iterator + ?Sized, type Item = <I as Iterator>::Item;impl<'_, F> Future for &'_ mut F where
F: Unpin + Future + ?Sized, type Output = <F as Future>::Output;
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut TⓘImportant traits for &'_ mut R
impl<'_, R> Read for &'_ mut R where
R: Read + ?Sized, impl<'_, W> Write for &'_ mut W where
W: Write + ?Sized, impl<'_, I> Iterator for &'_ mut I where
I: Iterator + ?Sized, type Item = <I as Iterator>::Item;impl<'_, F> Future for &'_ mut F where
F: Unpin + Future + ?Sized, type Output = <F as Future>::Output;
[src]
Important traits for &'_ mut R
impl<'_, R> Read for &'_ mut R where
R: Read + ?Sized, impl<'_, W> Write for &'_ mut W where
W: Write + ?Sized, impl<'_, I> Iterator for &'_ mut I where
I: Iterator + ?Sized, type Item = <I as Iterator>::Item;impl<'_, F> Future for &'_ mut F where
F: Unpin + Future + ?Sized, type Output = <F as Future>::Output;
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
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>,