From 34fdf2be00780188a98c9b0ada2b40032c9bfa18 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 30 Jul 2015 02:44:52 -0700 Subject: [PATCH] Add machinery for evaluation environments --- src/evaluate.rs | 40 +++++++++++++++++++++++++++++----------- src/main.rs | 6 ++++-- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/evaluate.rs b/src/evaluate.rs index 1a9e9c5..19ce08a 100644 --- a/src/evaluate.rs +++ b/src/evaluate.rs @@ -1,25 +1,43 @@ +use std::collections::HashMap; + use parser::AST; use parser::AST::*; -pub fn evaluate(ast: AST) -> String { - match reduce(ast) { - None => return "error".to_string(), - Some(DoNothing) => "".to_string(), - Some(Number(n)) => return format!("{}", n), - Some(LangString(s)) => return format!("\"{}\"", s), +pub struct Environment(pub HashMap); +type EvalResult = (AST, Environment); + +impl Environment { + pub fn new() -> Environment { + Environment(HashMap::new()) + } +} + +pub fn evaluate(ast: AST, env: Environment) -> String { + + let (reduced_ast, final_env) = reduce((ast, env)); + + match reduced_ast { + DoNothing => "".to_string(), + Number(n) => return format!("{}", n), + LangString(s) => return format!("\"{}\"", s), _ => return "not implemented".to_string() } } -fn reduce(ast: AST) -> Option { +fn reduce(evr: EvalResult) -> EvalResult { + let (ast, env) = evr; + match ast { Statements(stmts) => { - let mut reduction = Some(DoNothing); + let mut reduced_ast = DoNothing; + let mut reduced_env = env; for stmt in stmts.into_iter() { - reduction = reduce(stmt); + let (a, b) = reduce((stmt, reduced_env)); + reduced_ast = a; + reduced_env = b; } - reduction + (reduced_ast, reduced_env) }, - other_ast => Some(other_ast) + other_ast => (other_ast, env) } } diff --git a/src/main.rs b/src/main.rs index 453c08e..51b21ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use std::process; use tokenizer::tokenize; use parser::{parse, ParseResult}; -use evaluate::evaluate; +use evaluate::{evaluate, Environment}; mod tokenizer; mod parser; @@ -43,7 +43,9 @@ fn repl() { match parse(tokens) { ParseResult::Ok(ast) => { println!("AST: {:?}", ast); - let eval = evaluate(ast); + + let env = Environment::new(); + let eval = evaluate(ast, env); println!("{}", eval); }, ParseResult::Err(err) => println!("Error: {}", err)