add evaluator

This commit is contained in:
Raptorox 2026-05-21 17:12:06 +02:00
parent c70c5fab4d
commit 99be8a16c7
No known key found for this signature in database
GPG key ID: 8B3556FC3ED1F6D8
3 changed files with 48 additions and 4 deletions

38
src/eval.rs Normal file
View file

@ -0,0 +1,38 @@
use crate::parser::{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())
}
}

View file

@ -5,6 +5,8 @@ mod lexer;
use lexer::Lexer; use lexer::Lexer;
mod parser; mod parser;
use parser::Parser; use parser::Parser;
mod eval;
use eval::Evaluator;
fn main() -> std::io::Result<()> { fn main() -> std::io::Result<()> {
let args = std::env::args().collect::<Vec<String>>(); let args = std::env::args().collect::<Vec<String>>();
@ -29,7 +31,11 @@ fn main() -> std::io::Result<()> {
let parsed = parser.parse(); let parsed = parser.parse();
match parsed { match parsed {
parser::Expr::EOL => break, parser::Expr::EOL => break,
_ => println!("{:?}", parsed) _ => {
println!("AST: {:?}", parsed);
let eval = Evaluator::new(parsed);
println!("Eval: {:?}", eval.eval());
}
} }
} }

View file

@ -1,6 +1,6 @@
use crate::token::Token; use crate::token::Token;
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum BinaryOp { pub enum BinaryOp {
Add, Add,
Sub, Sub,
@ -9,7 +9,7 @@ pub enum BinaryOp {
Mod Mod
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum UnaryOp { pub enum UnaryOp {
Neg Neg
} }
@ -27,7 +27,7 @@ fn infix_bp(op: &BinaryOp) -> (u8, u8) {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Expr { pub enum Expr {
Number(i64), Number(i64),
Ident(String), Ident(String),