Files
rlox/src/astprinter.rs

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!(") ");
}
}