diff --git a/src/astprinter.rs b/src/astprinter.rs index bc1c9a0..4e9e824 100644 --- a/src/astprinter.rs +++ b/src/astprinter.rs @@ -1,37 +1,57 @@ use crate::expr::{Binary, Expr, ExprVisitor, Grouping, Literal, Unary, VisitableExpr}; -pub struct ASTPrinter; +pub struct ASTPrinter { + pub(crate) depth: u32 +} + +impl ASTPrinter { + fn ast_tab(&self) -> String { + (0..self.depth).map(|_| " ").collect::() + } +} impl ExprVisitor for ASTPrinter { - fn visit_binary(&self, b: &Binary) { - print!("( {}", b.operator.literal); + fn visit_binary(&mut self, b: &Binary) { + println!("{}BINARY",self.ast_tab()); + println!("{}op='{}'", self.ast_tab(), b.operator.lexeme); + println!("{}left=(", self.ast_tab()); + self.depth+=1; b.left.accept(self); + self.depth-=1; + println!("{})", self.ast_tab()); + println!("{}right=(", self.ast_tab()); + self.depth+=1; b.right.accept(self); - print!(")"); + self.depth-=1; + println!("{})", self.ast_tab()); } - fn visit_grouping(&self, g: &Grouping) { - print!("( group "); + fn visit_grouping(&mut self, g: &Grouping) { + println!("{}GROUPING(", self.ast_tab()); + self.depth+=1; g.expression.accept(self); - print!(")"); + self.depth-=1; + print!(") "); } - fn visit_literal(&self, l: &Literal) { + fn visit_literal(&mut self, l: &Literal) { match l { - Literal::LiteralNumber(i) => print!("{}", i), - Literal::LiteralString(s) => print!("{}", s), - Literal::LiteralBool(b) => print!("{}", b), - Literal::LiteralNil => print!("nil"), + Literal::LiteralNumber(i) => print!("{}NUMBER={}", self.ast_tab(), i), + Literal::LiteralString(s) => print!("{}STRING='{}'", self.ast_tab(), s), + Literal::LiteralBool(b) => print!("{}BOOL={}", self.ast_tab(), b), + Literal::LiteralNil => print!("{}NIL", self.ast_tab()), } } - fn visit_unary(&self, u: &Unary) { - print!("( {}", u.operator.literal); + fn visit_unary(&mut self, u: &Unary) { + println!("{}UNARY(op='{}'", self.ast_tab(), u.operator.lexeme); + self.depth+=1; u.right.accept(self); - print!(")"); + self.depth-=1; + print!(") "); } - fn visit_expr(&self, e: &Expr) { + fn visit_expr(&mut self, e: &Expr) { match e { Expr::BinaryExpr(b) => { b.accept(self); } Expr::GroupingExpr(g) => { g.accept(self); } diff --git a/src/expr.rs b/src/expr.rs index 6da9c08..8827404 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -30,43 +30,43 @@ pub enum Expr { } pub trait ExprVisitor { - fn visit_binary(&self, b: &Binary); - fn visit_grouping(&self, g: &Grouping); - fn visit_literal(&self, l: &Literal); - fn visit_unary(&self, u: &Unary); - fn visit_expr(&self, e: &Expr); + fn visit_binary(&mut self, b: &Binary); + fn visit_grouping(&mut self, g: &Grouping); + fn visit_literal(&mut self, l: &Literal); + fn visit_unary(&mut self, u: &Unary); + fn visit_expr(&mut self, e: &Expr); } pub trait VisitableExpr { - fn accept(&self, visitor: &impl ExprVisitor); + fn accept(&self, visitor: &mut impl ExprVisitor); } impl VisitableExpr for Binary { - fn accept(&self, visitor: &impl ExprVisitor) { + fn accept(&self, visitor: &mut impl ExprVisitor) { visitor.visit_binary(self); } } impl VisitableExpr for Grouping { - fn accept(&self, visitor: &impl ExprVisitor) { + fn accept(&self, visitor: &mut impl ExprVisitor) { visitor.visit_grouping(self); } } impl VisitableExpr for Literal { - fn accept(&self, visitor: &impl ExprVisitor) { + fn accept(&self, visitor: &mut impl ExprVisitor) { visitor.visit_literal(self); } } impl VisitableExpr for Unary { - fn accept(&self, visitor: &impl ExprVisitor) { + fn accept(&self, visitor: &mut impl ExprVisitor) { visitor.visit_unary(self); } } impl VisitableExpr for Expr { - fn accept(&self, visitor: &impl ExprVisitor) { + fn accept(&self, visitor: &mut impl ExprVisitor) { visitor.visit_expr(self); } } diff --git a/src/rlox_interpreter.rs b/src/rlox_interpreter.rs index f4bc270..337a127 100644 --- a/src/rlox_interpreter.rs +++ b/src/rlox_interpreter.rs @@ -48,8 +48,9 @@ impl RLoxInterpreter { let mut parser = Parser::new( scanner.tokens ); match parser.parse() { Some(expr) => { - let printer = ASTPrinter; + let mut printer = ASTPrinter { depth: 0 }; printer.visit_expr(&expr); + println!(); }, None => println!("An error occurred while parsing expression.") }