// usage: cargo run --release --example internals use fasteval3::{Compiler, EmptyNamespace}; // use this trait so we can call compile(). fn main() -> Result<(), fasteval3::Error> { let parser = fasteval3::Parser::new(); let mut slab = fasteval3::Slab::new(); let expr_str = "sin(deg/360 * 2*pi())"; let expr_ref = parser.parse(expr_str, &mut slab.ps)?.from(&slab.ps); // Let's take a look at the parsed AST inside the Slab: // If you find this structure confusing, take a look at the compilation // AST below because it is simpler. assert_eq!( format!("{:?}", slab.ps), r#"ParseSlab{ exprs:{ 0:Expression { first: EStdFunc(EVar("deg")), pairs: [ExprPair(EDiv, EConstant(360.0)), ExprPair(EMul, EConstant(2.0)), ExprPair(EMul, EStdFunc(EFuncPi))] }, 1:Expression { first: EStdFunc(EFuncSin(ExpressionI(0))), pairs: [] } }, vals:{} }"# ); // Pretty-Print: // ParseSlab{ // exprs:{ // 0:Expression { first: EStdFunc(EVar("deg")), // pairs: [ExprPair(EDiv, EConstant(360.0)), // ExprPair(EMul, EConstant(2.0)), // ExprPair(EMul, EStdFunc(EFuncPi))] // }, // 1:Expression { first: EStdFunc(EFuncSin(ExpressionI(0))), // pairs: [] } // }, // vals:{} // } let compiled = expr_ref.compile(&slab.ps, &mut slab.cs, &mut EmptyNamespace); // Let's take a look at the compilation results and the AST inside the Slab: // Notice that compilation has performed constant-folding: 1/360 * 2*pi = 0.017453292519943295 // In the results below: IFuncSin(...) represents the sin function. // InstructionI(1) represents the Instruction stored at index 1. // IMul(...) represents the multiplication operator. // 'C(0.017...)' represents a constant value of 0.017... . // IVar("deg") represents a variable named "deg". assert_eq!(format!("{compiled:?}"), "IFuncSin(InstructionI(1))"); assert_eq!( format!("{:?}", slab.cs), r#"CompileSlab{ instrs:{ 0:IVar("deg"), 1:IMul(InstructionI(0), C(0.017453292519943295)) } }"# ); Ok(()) }