Skip to main content

AST

Struct AST 

Source
pub struct AST { /* private fields */ }
Available on crate feature rhai only.
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§

Source§

impl AST

Source

pub fn lib(&self) -> &Module

👎Deprecated since 1.3.0:

use shared_lib instead

Available on crate feature internals and non-crate feature no_function only.

(internals) Get the internal Module containing all script-defined functions. Exported under the internals feature only.

Not available under no_function.

§Deprecated

This method is deprecated. Use shared_lib instead.

This method will be removed in the next major version.

Source§

impl AST

Source

pub fn new( statements: impl IntoIterator<Item = Stmt>, functions: impl Into<Arc<Module>>, ) -> AST

Available on crate feature internals only.

(internals) Create a new AST. Exported under the internals feature only.

Source

pub fn new_with_source( statements: impl IntoIterator<Item = Stmt>, functions: impl Into<Arc<Module>>, source: impl Into<ImmutableString>, ) -> AST

Available on crate feature internals only.

(internals) Create a new AST with a source name. Exported under the internals feature only.

Source

pub fn new_from_module(module: impl Into<Arc<Module>>) -> AST

Available on non-crate feature no_function only.

Create a new AST from a shared Module.

Source

pub fn empty() -> AST

Create an empty AST.

Source

pub fn source(&self) -> Option<&str>

Get the source, if any.

Source

pub fn set_source(&mut self, source: impl Into<ImmutableString>) -> &mut AST

Set the source.

Source

pub fn clear_source(&mut self) -> &mut AST

Clear the source.

Source

pub fn statements(&self) -> &[Stmt]

Available on crate feature internals only.

(internals) Get the statements. Exported under the internals feature only.

Source

pub fn has_functions(&self) -> bool

Available on non-crate feature no_function only.

Does this AST contain script-defined functions?

Not available under no_function.

Source

pub const fn shared_lib(&self) -> &Arc<Module>

Available on crate feature internals only.

(internals) Get the internal shared Module containing all script-defined functions. Exported under the internals feature only.

Not available under no_function.

Source

pub const fn resolver(&self) -> Option<&Arc<StaticModuleResolver>>

Available on crate feature internals and non-crate feature no_module only.

(internals) Get the embedded module resolver. Exported under the internals feature only.

Not available under no_module.

Source

pub fn clone_functions_only(&self) -> AST

Available on non-crate feature no_function only.

Clone the AST’s functions into a new AST. No statements are cloned.

Not available under no_function.

This operation is cheap because functions are shared.

Source

pub fn clone_functions_only_filtered( &self, filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool, ) -> AST

Available on non-crate feature no_function only.

Clone the AST’s functions into a new AST based on a filter predicate. No statements are cloned.

Not available under no_function.

This operation is cheap because functions are shared.

Source

pub fn clone_statements_only(&self) -> AST

Clone the AST’s script statements into a new AST. No functions are cloned.

Source

pub fn merge(&self, other: &AST) -> AST

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("
    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!");
Source

pub fn combine(&mut self, other: AST) -> &mut AST

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!");
Source

pub fn merge_filtered( &self, other: &AST, filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool, ) -> AST

Available on non-crate feature no_function only.

Merge two AST into one. Both AST’s are untouched and a new, merged, version is returned.

Not available under no_function.

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!");
Source

pub fn combine_filtered( &mut self, other: AST, filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool, ) -> &mut AST

Available on non-crate feature no_function only.

Combine one AST with another. The second AST is consumed.

Not available under no_function.

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!");
Source

pub fn retain_functions( &mut self, filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool, ) -> &mut AST

Available on non-crate feature no_function only.

Filter 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);
Source

pub fn iter_fn_def(&self) -> impl Iterator<Item = &Arc<ScriptFuncDef>>

Available on crate feature internals only.

(internals) Iterate through all function definitions. Exported under the internals feature only.

Not available under no_function.

Source

pub fn iter_functions(&self) -> impl Iterator<Item = ScriptFnMetadata<'_>>

Available on non-crate feature no_function only.

Iterate through all function definitions.

Not available under no_function.

Source

pub fn clear_functions(&mut self) -> &mut AST

Available on non-crate feature no_function only.

Clear all function definitions in the AST.

Not available under no_function.

Source

pub fn clear_statements(&mut self) -> &mut AST

Clear all statements in the AST, leaving only function definitions.

Source

pub fn iter_literal_variables( &self, include_constants: bool, include_variables: bool, ) -> impl Iterator<Item = (&str, bool, Dynamic)>

Extract all top-level literal constant and/or variable definitions. This is useful for extracting all global constants from a script without actually running it.

A literal constant/variable definition takes the form of: const VAR = value; and let VAR = value; where value is a literal expression or will be optimized into a literal.

§Example
use rhai::{Engine, Scope};

let engine = Engine::new();

let ast = engine.compile(
"
    const A = 40 + 2;   // constant that optimizes into a literal
    let b = 123;        // literal variable
    const B = b * A;    // non-literal constant
    const C = 999;      // literal constant
    b = A + C;          // expression

    {                   // <- new block scope
        const Z = 0;    // <- literal constant not at top-level

        print(Z);       // make sure the block is not optimized away
    }
")?;

let mut iter = ast.iter_literal_variables(true, false)
                  .map(|(name, is_const, value)| (name, is_const, value.as_int().unwrap()));

assert_eq!(iter.next(), Some(("A", true, 42)));
assert_eq!(iter.next(), Some(("C", true, 999)));
assert_eq!(iter.next(), None);

let mut iter = ast.iter_literal_variables(false, true)
                  .map(|(name, is_const, value)| (name, is_const, value.as_int().unwrap()));

assert_eq!(iter.next(), Some(("b", false, 123)));
assert_eq!(iter.next(), None);

let mut iter = ast.iter_literal_variables(true, true)
                  .map(|(name, is_const, value)| (name, is_const, value.as_int().unwrap()));

assert_eq!(iter.next(), Some(("A", true, 42)));
assert_eq!(iter.next(), Some(("b", false, 123)));
assert_eq!(iter.next(), Some(("C", true, 999)));
assert_eq!(iter.next(), None);

let scope: Scope = ast.iter_literal_variables(true, false).collect();

assert_eq!(scope.len(), 2);

Ok(())
Source

pub fn walk( &self, on_node: &mut (impl FnMut(&[ASTNode<'_>]) -> bool + ?Sized), ) -> bool

Available on crate feature internals only.

(internals) Recursively walk the AST, including function bodies (if any). Return false from the callback to terminate the walk. Exported under the internals feature only.

Trait Implementations§

Source§

impl<A> Add<A> for &AST
where A: AsRef<AST>,

Source§

type Output = AST

The resulting type after applying the + operator.
Source§

fn add(self, rhs: A) -> <&AST as Add<A>>::Output

Performs the + operation. Read more
Source§

impl<A> AddAssign<A> for AST
where A: Into<AST>,

Source§

fn add_assign(&mut self, rhs: A)

Performs the += operation. Read more
Source§

impl AsRef<Arc<Module>> for AST

Available on non-crate feature no_function only.
Source§

fn as_ref(&self) -> &Arc<Module>

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl AsRef<Module> for AST

Available on non-crate feature no_function only.
Source§

fn as_ref(&self) -> &Module

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl AsRef<[Stmt]> for AST

Source§

fn as_ref(&self) -> &[Stmt]

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl Borrow<Arc<Module>> for AST

Available on non-crate feature no_function only.
Source§

fn borrow(&self) -> &Arc<Module>

Immutably borrows from an owned value. Read more
Source§

impl Borrow<Module> for AST

Available on non-crate feature no_function only.
Source§

fn borrow(&self) -> &Module

Immutably borrows from an owned value. Read more
Source§

impl Borrow<[Stmt]> for AST

Source§

fn borrow(&self) -> &[Stmt]

Immutably borrows from an owned value. Read more
Source§

impl Clone for AST

Source§

fn clone(&self) -> AST

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AST

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for AST

Source§

fn default() -> AST

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for AST

§

impl !UnwindSafe for AST

§

impl Freeze for AST

§

impl Send for AST

§

impl Sync for AST

§

impl Unpin for AST

§

impl UnsafeUnpin for AST

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ServiceExt for T

Source§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Available on crate feature map-response-body only.
Apply a transformation to the response body. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

Available on crate feature trace only.
High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

Available on crate feature trace only.
High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Available on crate feature follow-redirect only.
Follow redirect resposes using the Standard policy. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> Variant for T
where T: Any + Clone + SendSync,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert this Variant trait object to &dyn Any.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert this Variant trait object to &mut dyn Any.
Source§

fn as_boxed_any(self: Box<T>) -> Box<dyn Any>

Convert this Variant trait object to Box<dyn Any>.
Source§

fn type_name(&self) -> &'static str

Get the name of this type.
Source§

fn clone_object(&self) -> Box<dyn Variant>

Clone this Variant trait object.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more