bubbles/runtime/eval/
mod.rs1mod binary;
4mod unary;
5
6use crate::compiler::expr::Expr;
7use crate::error::{DialogueError, Result};
8use crate::value::{Value, VariableStorage};
9
10pub fn eval<S, F>(expr: &Expr, storage: &S, fns: &F) -> Result<Value>
18where
19 S: VariableStorage,
20 F: Fn(&str, Vec<Value>) -> Result<Value>,
21{
22 match expr {
23 Expr::Number(n) => Ok(Value::Number(*n)),
24 Expr::Text(s) => Ok(Value::Text(s.clone())),
25 Expr::Bool(b) => Ok(Value::Bool(*b)),
26 Expr::Var(name) => storage
27 .get_ref(name)
28 .map(std::borrow::Cow::into_owned)
29 .ok_or_else(|| DialogueError::UndefinedVariable(name.clone())),
30 Expr::Call { name, args } => {
31 let evaluated: Result<Vec<Value>> =
32 args.iter().map(|a| eval(a, storage, fns)).collect();
33 fns(name, evaluated?)
34 }
35 Expr::Unary { op, expr } => unary::eval_unary(*op, expr, storage, fns),
36 Expr::Binary { left, op, right } => binary::eval_binary(left, *op, right, storage, fns),
37 }
38}
39
40#[cfg(test)]
41#[path = "eval_tests.rs"]
42mod tests;