72 lines
1.7 KiB
Rust
72 lines
1.7 KiB
Rust
|
use std::ops;
|
||
|
|
||
|
use crate::parser;
|
||
|
use parser::Atom;
|
||
|
|
||
|
pub fn eval(ast: &parser::Expr) -> parser::Atom {
|
||
|
match ast {
|
||
|
parser::Expr::Atom(a) => a.clone(),
|
||
|
parser::Expr::UnaryMinus(a) => -eval(&a),
|
||
|
parser::Expr::Plus(a, b) => eval(&a) + eval(&b),
|
||
|
parser::Expr::Minus(a, b) => eval(&a) - eval(&b),
|
||
|
parser::Expr::Mult(a, b) => eval(&a) * eval(&b),
|
||
|
parser::Expr::Div(a, b) => eval(&a) / eval(&b),
|
||
|
_ => panic!("Couldn't evalute expression {{ {:?} }}", ast),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Neg for Atom {
|
||
|
type Output = Self;
|
||
|
|
||
|
fn neg(self) -> Self {
|
||
|
match self {
|
||
|
Atom::Num(a) => Atom::Num(-a),
|
||
|
_ => panic!("Can't negate non-numeral type!"),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Add for Atom {
|
||
|
type Output = Self;
|
||
|
|
||
|
fn add(self, other: Self) -> Self {
|
||
|
match (self, other) {
|
||
|
(Atom::Num(a), Atom::Num(b)) => Atom::Num(a + b),
|
||
|
_ => panic!("Can't add non-numeral types!"),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Sub for Atom {
|
||
|
type Output = Self;
|
||
|
|
||
|
fn sub(self, other: Self) -> Self {
|
||
|
match (self, other) {
|
||
|
(Atom::Num(a), Atom::Num(b)) => Atom::Num(a - b),
|
||
|
_ => panic!("Can't subtract non-numeral types!"),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Mul for Atom {
|
||
|
type Output = Self;
|
||
|
|
||
|
fn mul(self, other: Self) -> Self {
|
||
|
match (self, other) {
|
||
|
(Atom::Num(a), Atom::Num(b)) => Atom::Num(a * b),
|
||
|
_ => panic!("Can't multiply non-numeral types!"),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl ops::Div for Atom {
|
||
|
type Output = Self;
|
||
|
|
||
|
fn div(self, other: Self) -> Self {
|
||
|
match (self, other) {
|
||
|
(Atom::Num(a), Atom::Num(b)) => Atom::Num(a / b),
|
||
|
_ => panic!("Can't divide non-numeral types!"),
|
||
|
}
|
||
|
}
|
||
|
}
|