1use crate::filtration::ScenarioFiltration;
2use fasteval::{Compiler, Evaler, Instruction, Slab};
3use ordered_float::OrderedFloat;
4
5pub struct Function {
6 instruction: Instruction,
7 slab: Slab,
8 expr_str: String,
9}
10
11impl Clone for Function {
12 fn clone(&self) -> Self {
13 Self::new(&self.expr_str).expect("Failed to re-compile on clone")
14 }
15}
16
17impl Function {
18 pub fn new(expr_str: &str) -> Result<Self, String> {
19 let parser = fasteval::Parser::new();
20 let mut slab = Slab::new();
21 let expr = parser
22 .parse(expr_str, &mut slab.ps)
23 .map_err(|e| format!("Parse Error: {:?}", e))?;
24 let instruction = expr.from(&slab.ps).compile(&slab.ps, &mut slab.cs);
25 Ok(Self {
26 instruction,
27 slab,
28 expr_str: expr_str.to_string(),
29 })
30 }
31
32 pub fn eval(
33 &self,
34 t: OrderedFloat<f64>,
35 filtration: &mut ScenarioFiltration,
36 ) -> Result<f64, fasteval::Error> {
37 if t != filtration.cache.time {
38 filtration.refresh_cache(t);
39 }
40 self.instruction
41 .eval(&self.slab, &mut filtration.cache.values)
42 }
43}