Add machinery for evaluation environments
This commit is contained in:
parent
4ef93fafb5
commit
34fdf2be00
@ -1,25 +1,43 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use parser::AST;
|
use parser::AST;
|
||||||
use parser::AST::*;
|
use parser::AST::*;
|
||||||
|
|
||||||
pub fn evaluate(ast: AST) -> String {
|
pub struct Environment(pub HashMap<String, AST>);
|
||||||
match reduce(ast) {
|
type EvalResult = (AST, Environment);
|
||||||
None => return "error".to_string(),
|
|
||||||
Some(DoNothing) => "".to_string(),
|
impl Environment {
|
||||||
Some(Number(n)) => return format!("{}", n),
|
pub fn new() -> Environment {
|
||||||
Some(LangString(s)) => return format!("\"{}\"", s),
|
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()
|
_ => return "not implemented".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce(ast: AST) -> Option<AST> {
|
fn reduce(evr: EvalResult) -> EvalResult {
|
||||||
|
let (ast, env) = evr;
|
||||||
|
|
||||||
match ast {
|
match ast {
|
||||||
Statements(stmts) => {
|
Statements(stmts) => {
|
||||||
let mut reduction = Some(DoNothing);
|
let mut reduced_ast = DoNothing;
|
||||||
|
let mut reduced_env = env;
|
||||||
for stmt in stmts.into_iter() {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use std::process;
|
|||||||
|
|
||||||
use tokenizer::tokenize;
|
use tokenizer::tokenize;
|
||||||
use parser::{parse, ParseResult};
|
use parser::{parse, ParseResult};
|
||||||
use evaluate::evaluate;
|
use evaluate::{evaluate, Environment};
|
||||||
|
|
||||||
mod tokenizer;
|
mod tokenizer;
|
||||||
mod parser;
|
mod parser;
|
||||||
@ -43,7 +43,9 @@ fn repl() {
|
|||||||
match parse(tokens) {
|
match parse(tokens) {
|
||||||
ParseResult::Ok(ast) => {
|
ParseResult::Ok(ast) => {
|
||||||
println!("AST: {:?}", ast);
|
println!("AST: {:?}", ast);
|
||||||
let eval = evaluate(ast);
|
|
||||||
|
let env = Environment::new();
|
||||||
|
let eval = evaluate(ast, env);
|
||||||
println!("{}", eval);
|
println!("{}", eval);
|
||||||
},
|
},
|
||||||
ParseResult::Err(err) => println!("Error: {}", err)
|
ParseResult::Err(err) => println!("Error: {}", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user