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::ops;
use std::collections::HashMap;
use crate::parser; use crate::parser;
use parser::Atom; 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 { match ast {
parser::Expr::Atom(a) => a.clone(), parser::Expr::Atom(a) => a.clone(),
parser::Expr::UnaryMinus(a) => -eval(&a), parser::Expr::UnaryMinus(a) => -eval(&a, env),
parser::Expr::Plus(a, b) => eval(&a) + eval(&b), parser::Expr::Plus(a, b) => eval(&a, env) + eval(&b, env),
parser::Expr::Minus(a, b) => eval(&a) - eval(&b), parser::Expr::Minus(a, b) => eval(&a, env) - eval(&b, env),
parser::Expr::Mult(a, b) => eval(&a) * eval(&b), parser::Expr::Mult(a, b) => eval(&a, env) * eval(&b, env),
parser::Expr::Div(a, b) => eval(&a) / eval(&b), parser::Expr::Div(a, b) => eval(&a, env) / eval(&b, env),
_ => panic!("Couldn't evalute expression {{ {:?} }}", ast), _ => panic!("Couldn't evalute expression {{ {:?} }}", ast),
} }
} }

View File

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