Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created December 12, 2023 18:16
Show Gist options
  • Save rust-play/11a155c7e491726989aa8b8141c5f0ea to your computer and use it in GitHub Desktop.
Save rust-play/11a155c7e491726989aa8b8141c5f0ea to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#[derive(Debug)]
enum Expr {
Literal(Literal),
Unary(UnaryOp, Box<Expr>),
Binary(Box<Expr>, BinaryOp, Box<Expr>),
Grouping(Box<Expr>),
}
#[derive(Debug)]
enum Literal {
Number(f64),
}
#[derive(Debug)]
enum UnaryOp {
Minus,
}
#[derive(Debug)]
enum BinaryOp {
Plus,
Star,
}
trait Visitor {
fn visit_literal(&mut self, literal: &Literal);
fn visit_unary(&mut self, unary_op: &UnaryOp, expr: &Expr);
fn visit_binary(&mut self, left_expr: &Expr, binary_op: &BinaryOp, right_expr: &Expr);
fn visit_grouping(&mut self, expr: &Expr);
}
struct AstPrinter;
impl AstPrinter {
fn print(&mut self, expr: &Expr) {
expr.accept(self);
}
}
impl Expr {
fn accept(&self, visitor: &mut dyn Visitor) {
match self {
Expr::Literal(literal) => visitor.visit_literal(literal),
Expr::Unary(unary_op, expr) => visitor.visit_unary(unary_op, expr),
Expr::Binary(left_expr, binary_op, right_expr) => {
visitor.visit_binary(left_expr, binary_op, right_expr)
}
Expr::Grouping(expr) => visitor.visit_grouping(expr),
}
}
}
impl Visitor for AstPrinter {
fn visit_literal(&mut self, literal: &Literal) {
match literal {
Literal::Number(n) => print!("{}", n),
}
}
fn visit_unary(&mut self, unary_op: &UnaryOp, expr: &Expr) {
print!("(");
match unary_op {
UnaryOp::Minus => print!("-"),
}
expr.accept(self);
print!(")");
}
fn visit_binary(&mut self, left_expr: &Expr, binary_op: &BinaryOp, right_expr: &Expr) {
print!("(");
left_expr.accept(self);
match binary_op {
BinaryOp::Plus => print!(" + "),
BinaryOp::Star => print!(" * "),
}
right_expr.accept(self);
print!(")");
}
fn visit_grouping(&mut self, expr: &Expr) {
print!("(");
expr.accept(self);
print!(")");
}
}
fn main() {
// -2 * (1 + 4)
let tokens = Expr::Binary(
Box::new(Expr::Unary(
UnaryOp::Minus,
Box::new(Expr::Literal(Literal::Number(1.0))),
)),
BinaryOp::Star,
Box::new(Expr::Grouping(Box::new(Expr::Binary(
Box::new(Expr::Literal(Literal::Number(1.0))),
BinaryOp::Plus,
Box::new(Expr::Literal(Literal::Number(4.0))),
)))),
);
let mut printer = AstPrinter;
printer.print(&tokens);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment