Include environment when evaluating
This commit is contained in:
parent
2e40afb9b5
commit
12c67d4d15
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user