From 12c67d4d1593b55d53124e76381b2e32ee68c272 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Wed, 1 Jun 2022 14:48:31 -0500 Subject: [PATCH] Include environment when evaluating --- rust/src/evaluator.rs | 33 +++++++++++++++++++++++++++------ rust/src/main.rs | 3 ++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/rust/src/evaluator.rs b/rust/src/evaluator.rs index 8060170..0fff525 100644 --- a/rust/src/evaluator.rs +++ b/rust/src/evaluator.rs @@ -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 +} + +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), } } diff --git a/rust/src/main.rs b/rust/src/main.rs index 4c3e0ca..c3035f2 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -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!(), } }