81 lines
2.4 KiB
Rust
81 lines
2.4 KiB
Rust
use crate::expr::{Binary, Expr, ExprVisitor, Grouping, Literal, Unary};
|
|
use crate::stmt::{ExpressionStatement, PrintStatement, StatementVisitor};
|
|
|
|
pub struct ASTPrinter {
|
|
pub(crate) depth: u32
|
|
}
|
|
|
|
impl ASTPrinter {
|
|
fn ast_tab(&self) -> String {
|
|
(0..self.depth).map(|_| " ").collect::<String>()
|
|
}
|
|
}
|
|
|
|
impl ExprVisitor<()> for ASTPrinter {
|
|
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;
|
|
self.visit_expr(&*b.left);
|
|
self.depth-=1;
|
|
println!("{})", self.ast_tab());
|
|
println!("{}right=(", self.ast_tab());
|
|
self.depth+=1;
|
|
self.visit_expr(&*b.right);
|
|
self.depth-=1;
|
|
println!("{})", self.ast_tab());
|
|
}
|
|
|
|
fn visit_grouping(&mut self, g: &Grouping) {
|
|
println!("{}GROUPING(", self.ast_tab());
|
|
self.depth+=1;
|
|
self.visit_expr(&*g.expression);
|
|
self.depth-=1;
|
|
print!(") ");
|
|
}
|
|
|
|
fn visit_literal(&mut self, l: &Literal) {
|
|
match l {
|
|
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(&mut self, u: &Unary) {
|
|
println!("{}UNARY(op='{}'", self.ast_tab(), u.operator.lexeme);
|
|
self.depth+=1;
|
|
self.visit_expr(&*u.right);
|
|
self.depth-=1;
|
|
print!(") ");
|
|
}
|
|
|
|
fn visit_expr(&mut self, e: &Expr) {
|
|
match e {
|
|
Expr::BinaryExpr(b) => { self.visit_binary(b); }
|
|
Expr::GroupingExpr(g) => { self.visit_grouping(g); }
|
|
Expr::LiteralExpr(l) => { self.visit_literal(l); }
|
|
Expr::UnaryExpr(u) => { self.visit_unary(u); }
|
|
}
|
|
}
|
|
}
|
|
|
|
impl StatementVisitor<()> for ASTPrinter {
|
|
fn visit_expr_stmt(&mut self, e: &ExpressionStatement) -> () {
|
|
println!("{} EXPR_STMT(", self.ast_tab());
|
|
self.depth+=1;
|
|
self.visit_expr(&e.expr);
|
|
self.depth-=1;
|
|
print!(") ");
|
|
}
|
|
|
|
fn visit_print(&mut self, p: &PrintStatement) -> () {
|
|
println!("{} EXPR_STMT(", self.ast_tab());
|
|
self.depth+=1;
|
|
self.visit_expr(&p.expr);
|
|
self.depth-=1;
|
|
print!(") ");
|
|
}
|
|
} |