Remix.run Logo
cmrdporcupine 4 days ago

I think that wouldn't be too foreign to anybody who has worked for a while in Rust? It's definitely more compact and expressive than the Rust equivalent, though.

This doesn't look or feel all that different to me:

  enum Expr {
      Const(f64),
      Var(String),
      Sum(Box<Expr>, Box<Expr>),
      Diff(Box<Expr>, Box<Expr>),
      Prod(Box<Expr>, Box<Expr>),
      Quot(Box<Expr>, Box<Expr>),
  }

  fn print_expr(exp: &Expr) {
      fn open_paren(prec: i32, op_prec: i32) {
          if prec > op_prec {
              print!("(");
          }
      }

      fn close_paren(prec: i32, op_prec: i32) {
          if prec > op_prec {
              print!(")");
          }
      }

      fn print_rec(prec: i32, exp: &Expr) {
          match exp {
              Expr::Const(c) => print!("{}", c),
              Expr::Var(v) => print!("{}", v),
              Expr::Sum(f, g) => {
                  open_paren(prec, 0);
                  print_rec(0, f);
                  print!(" + ");
                  print_rec(0, g);
                  close_paren(prec, 0);
              }
              Expr::Diff(f, g) => {
                  open_paren(prec, 0);
                  print_rec(0, f);
                  print!(" - ");
                  print_rec(1, g);
                  close_paren(prec, 0);
              }
              Expr::Prod(f, g) => {
                  open_paren(prec, 2);
                  print_rec(2, f);
                  print!(" * ");
                  print_rec(2, g);
                  close_paren(prec, 2);
              }
              Expr::Quot(f, g) => {
                  open_paren(prec, 2);
                  print_rec(2, f);
                  print!(" / ");
                  print_rec(3, g);
                  close_paren(prec, 2);
              }
          }
      }

      print_rec(0, exp);
  }