Re-Optimize an AST

Sometimes it is more efficient to store one single, large script with delimited code blocks guarded by constant variables. This script is compiled once to an AST.

Then, depending on the execution environment, constants are passed into the Engine and the AST is re-optimized based on those constants via Engine::optimize_ast, effectively pruning out unused code sections.

The final, optimized AST is then used for evaluations.

// Compile master script to AST
let master_ast = engine.compile(
"
    fn do_work() {
        // Constants in scope are also propagated into functions
        print(SCENARIO);
    }

    switch SCENARIO {
        1 => do_work(),
        2 => do_something(),
        3 => do_something_else(),
        _ => do_nothing()
    }
")?;

for n in 0..5_i64 {
    // Create a new scope - put constants in it to aid optimization
    let mut scope = Scope::new();
    scope.push_constant("SCENARIO", n);

    // Re-optimize the AST
    let new_ast = engine.optimize_ast(&scope, master_ast.clone(), OptimizationLevel::Simple);

    // Run it
    engine.run_ast(&new_ast)?;
}

Constants propagation

Beware that constants inside the custom Scope will also be propagated to functions defined within the script while normally such functions are pure and cannot see variables/constants within the global Scope.