rat/src/eval.rs
2026-05-21 17:40:53 +02:00

42 lines
No EOL
1.1 KiB
Rust

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 } => {
let lhs = self.eval_expr(*left);
let rhs = self.eval_expr(*right);
match op {
BinaryOp::Add => lhs + rhs,
BinaryOp::Sub => lhs - rhs,
BinaryOp::Mul => lhs * rhs,
BinaryOp::Div => lhs / rhs,
BinaryOp::Mod => lhs % rhs,
BinaryOp::Exp => lhs.pow(rhs as u32) // probably shouldn't cast like that
}
},
expr => panic!("can't eval expression: {expr:?}")
}
}
pub fn eval(&self) -> i64 {
self.eval_expr(self.ast.clone())
}
}