use crate::expr::{BinaryOp, Expr, UnaryOp}; pub struct Evaluator { ast: Expr } impl Evaluator { pub fn new(ast: Expr) -> Self { Self { ast } } fn eval_expr(&self, expr: Expr) -> i64 { match expr { Expr::Number(n) => n, Expr::Unary { op, right } => { match op { UnaryOp::Neg => -self.eval_expr(*right) } }, Expr::Binary { op, left, right } => { match op { BinaryOp::Add => self.eval_expr(*left) + self.eval_expr(*right), BinaryOp::Sub => self.eval_expr(*left) - self.eval_expr(*right), BinaryOp::Mul => self.eval_expr(*left) * self.eval_expr(*right), BinaryOp::Div => self.eval_expr(*left) / self.eval_expr(*right), BinaryOp::Mod => self.eval_expr(*left) % self.eval_expr(*right) } }, expr => panic!("can't eval expression: {expr:?}") } } pub fn eval(&self) -> i64 { self.eval_expr(self.ast.clone()) } }