Skip to content

Instantly share code, notes, and snippets.

@MikuroXina
Last active September 21, 2020 23:23
Show Gist options
  • Select an option

  • Save MikuroXina/0c61b1eed755f6db6e33802b7e799512 to your computer and use it in GitHub Desktop.

Select an option

Save MikuroXina/0c61b1eed755f6db6e33802b7e799512 to your computer and use it in GitHub Desktop.
enum Expr {
Num(i64),
Op(Box<Expr>, fn(i64, i64) -> i64, Box<Expr>),
}
#[derive(Debug)]
enum Token {
Num(i64),
Add,
Sub,
}
impl Expr {
fn from(tokens: &[Token]) -> Result<Expr, String> {
match tokens {
&[Token::Num(l), Token::Add, ref r @ ..] => Ok(Expr::Op(
Box::new(Expr::Num(l)),
|a, b| a + b,
Box::new(Expr::from(r)?)
)),
&[Token::Num(l), Token::Sub, ref r @ ..] => Ok(Expr::Op(
Box::new(Expr::Num(l)),
|a, b| a - b,
Box::new(Expr::from(r)?)
)),
&[Token::Num(n)] => Ok(Expr::Num(n)),
_ => Err(format!("syntax error: {:#?}", tokens)),
}
}
fn eval(&self) -> i64 {
match self {
Expr::Num(n) => *n,
Expr::Op(l, f, r) => f(l.eval(), r.eval()),
}
}
}
fn main() {
let expr = Expr::from(&[
Token::Num(1),
Token::Add,
Token::Num(2),
Token::Sub,
Token::Num(-4)
]).unwrap();
println!("{}", expr.eval());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment