deelang/rust/src/evaluator.rs

93 lines
2.2 KiB
Rust
Raw Normal View History

use std::ops;
2022-06-01 14:48:31 -05:00
use std::collections::HashMap;
use crate::parser;
use parser::Atom;
2022-06-01 14:48:31 -05:00
pub struct Env<'a> {
pub parent: Option<&'a Env<'a>>,
pub values: HashMap<String, Atom>
}
impl<'a> Env<'a> {
pub fn global() -> Self {
Env {
parent: None,
values: HashMap::new(),
}
}
pub fn child(parent: &'a Env<'a>) -> Self {
Env {
parent: Some(parent),
values: HashMap::new(),
}
}
}
pub fn eval(ast: &parser::Expr, env: &mut Env) -> parser::Atom {
match ast {
parser::Expr::Atom(a) => a.clone(),
2022-06-01 14:48:31 -05:00
parser::Expr::UnaryMinus(a) => -eval(&a, env),
parser::Expr::Plus(a, b) => eval(&a, env) + eval(&b, env),
parser::Expr::Minus(a, b) => eval(&a, env) - eval(&b, env),
parser::Expr::Mult(a, b) => eval(&a, env) * eval(&b, env),
parser::Expr::Div(a, b) => eval(&a, env) / eval(&b, env),
_ => 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!"),
}
}
}