diff --git a/src/eval.rs b/src/eval.rs deleted file mode 100644 index 7707b86..0000000 --- a/src/eval.rs +++ /dev/null @@ -1,38 +0,0 @@ -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()) - } -} \ No newline at end of file diff --git a/src/lexer.rs b/src/lexer.rs index 0a2bc74..d49eafd 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -1,4 +1,25 @@ -use crate::token::Token; +#[derive(Debug, PartialEq)] +pub enum Token { + Number(i64), + Ident(String), + + // Operators + Add, + Sub, + Mul, + Div, + Mod, + + // Parentheses + LParen, + RParen, + LBrace, + RBrace, + LBracket, + RBracket, + + Semicolon +} pub struct Lexer { source: Vec, diff --git a/src/main.rs b/src/main.rs index 4d61fc5..59ed221 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,7 @@ use std::{fs::File, io::Read}; -mod token; mod lexer; use lexer::Lexer; -mod parser; -use parser::Parser; -mod eval; -use eval::Evaluator; fn main() -> std::io::Result<()> { let args = std::env::args().collect::>(); @@ -18,24 +13,10 @@ fn main() -> std::io::Result<()> { let mut lexer = Lexer::new(&source); - let mut tokens = Vec::new(); - while let Some(tok) = lexer.next() { - print!("{tok:?}, "); - tokens.push(tok); - } - - println!("\n"); - - let mut parser = Parser::new(tokens); loop { - let parsed = parser.parse(); - match parsed { - parser::Expr::EOL => break, - _ => { - println!("AST: {:?}", parsed); - let eval = Evaluator::new(parsed); - println!("Eval: {:?}", eval.eval()); - } + match lexer.next() { + Some(tok) => print!("{tok:?}, "), + None => break } } diff --git a/src/parser.rs b/src/parser.rs deleted file mode 100644 index 9e26822..0000000 --- a/src/parser.rs +++ /dev/null @@ -1,139 +0,0 @@ -use crate::token::Token; - -#[derive(Debug, Clone)] -pub enum BinaryOp { - Add, - Sub, - Mul, - Div, - Mod -} - -#[derive(Debug, Clone)] -pub enum UnaryOp { - Neg -} - -fn prefix_bp(op: &UnaryOp) -> u8 { - match op { - UnaryOp::Neg => 5 - } -} - -fn infix_bp(op: &BinaryOp) -> (u8, u8) { - match op { - BinaryOp::Add | BinaryOp::Sub => (1, 2), - BinaryOp::Mul | BinaryOp::Div | BinaryOp::Mod => (3, 4) - } -} - -#[derive(Debug, Clone)] -pub enum Expr { - Number(i64), - Ident(String), - EOL, - - Binary { - op: BinaryOp, - left: Box, - right: Box - }, - - Unary { - op: UnaryOp, - right: Box - } -} - -pub struct Parser { - tokens: Vec, - pos: usize -} - -impl Parser { - pub fn new(tokens: Vec) -> Self { - Self { - tokens, - pos: 0 - } - } - - fn advance(&mut self) { - self.pos += 1; - } - - fn peek(&self) -> Option<&Token> { - self.tokens.get(self.pos) - } - - fn next(&mut self) -> Option { - let tok = self.peek().cloned(); - self.advance(); - tok - } - - fn parse_atom(&mut self) -> Expr { - match self.next() { - Some(Token::Number(n)) => Expr::Number(n), - Some(Token::Ident(id)) => Expr::Ident(id), - Some(Token::LParen) => { - let expr = self.parse_expr(0); - - match self.next() { - Some(Token::RParen) => expr, - _ => panic!("expected ')'") - } - }, - tok => panic!("unknown token: {tok:?}") - } - } - - fn parse_prefix(&mut self) -> Expr { - match self.peek() { - Some(Token::Sub) => { - self.advance(); - let op = UnaryOp::Neg; - - let bp = prefix_bp(&op); - let rhs = self.parse_expr(bp); - - Expr::Unary { op, right: Box::new(rhs) } - }, - _ => self.parse_atom() - } - } - - fn parse_expr(&mut self, min_bp: u8) -> Expr { - let mut lhs = self.parse_prefix(); - - loop { - let op = match self.peek() { - Some(Token::Add) => BinaryOp::Add, - Some(Token::Sub) => BinaryOp::Sub, - Some(Token::Mul) => BinaryOp::Mul, - Some(Token::Div) => BinaryOp::Div, - Some(Token::Mod) => BinaryOp::Mod, - _ => break - }; - - let (left_bp, right_bp) = infix_bp(&op); - - if left_bp < min_bp { - break; - } - - self.advance(); - - let rhs = self.parse_expr(right_bp); - - lhs = Expr::Binary { left: Box::new(lhs), op, right: Box::new(rhs) } - } - - lhs - } - - pub fn parse(&mut self) -> Expr { - if self.peek() == None {return Expr::EOL} - self.parse_expr(0) - } -} \ No newline at end of file diff --git a/src/token.rs b/src/token.rs deleted file mode 100644 index 778263c..0000000 --- a/src/token.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[derive(Debug, PartialEq, Clone)] -pub enum Token { - Number(i64), - Ident(String), - - // Operators - Add, - Sub, - Mul, - Div, - Mod, - - // Parentheses - LParen, - RParen, - LBrace, - RBrace, - LBracket, - RBracket, - - Semicolon -} \ No newline at end of file