Include environment when evaluating

This commit is contained in:
Dane Johnson 2022-06-01 14:48:31 -05:00
parent 2e40afb9b5
commit 12c67d4d15
2 changed files with 29 additions and 7 deletions

View File

@ -1,16 +1,37 @@
use std::ops;
use std::collections::HashMap;
use crate::parser;
use parser::Atom;
pub fn eval(ast: &parser::Expr) -> parser::Atom {
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(),
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),
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),
}
}

View File

@ -18,6 +18,7 @@ struct Cli {
}
fn repl(cli: &Cli) {
let mut global = evaluator::Env::global();
loop {
let mut line = String::new();
io::stdin().read_line(&mut line).unwrap();
@ -27,7 +28,7 @@ fn repl(cli: &Cli) {
} else {
match &tree {
parser::Stmt::ReplPrint(expr) =>
println!("{}", evaluator::eval(expr)),
println!("{}", evaluator::eval(expr, &mut global)),
_ => todo!(),
}
}