add evaluator
This commit is contained in:
parent
c70c5fab4d
commit
99be8a16c7
3 changed files with 48 additions and 4 deletions
38
src/eval.rs
Normal file
38
src/eval.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue