From 2fbb8f2b2f6ce0b379586ee5ee6bd43af5e12e51 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 13 Oct 2017 03:05:18 -0700 Subject: [PATCH] Can eval custom data constructors now --- src/schala_lang/eval.rs | 65 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/src/schala_lang/eval.rs b/src/schala_lang/eval.rs index 2762032..ef25550 100644 --- a/src/schala_lang/eval.rs +++ b/src/schala_lang/eval.rs @@ -1,21 +1,37 @@ -use schala_lang::parsing::{AST, Statement, Declaration, Expression, ExpressionType, Operation}; +use schala_lang::parsing::{AST, Statement, Declaration, Expression, Variant, ExpressionType, Operation}; +use std::collections::HashMap; +use std::rc::Rc; pub struct ReplState { + values: HashMap, ValueEntry>, +} + +enum ValueEntry { + Binding { + val: FullyEvaluatedExpr, + }, + Function { + body: Vec, + } } type EvalResult = Result; +#[derive(Debug, PartialEq, Clone)] enum FullyEvaluatedExpr { UnsignedInt(u64), SignedInt(i64), Float(f64), Str(String), Bool(bool), + Custom { + string_rep: Rc, + } } impl ReplState { pub fn new() -> ReplState { - ReplState { } + ReplState { values: HashMap::new() } } pub fn evaluate(&mut self, ast: AST) -> Vec { @@ -28,7 +44,7 @@ impl ReplState { } }, Err(error) => { - acc.push(format!("Error: {}", error)); + acc.push(format!("Eval error: {}", error)); return acc; }, } @@ -49,6 +65,7 @@ impl ReplState { Float(f) => Some(format!("{}", f)), Str(s) => Some(format!("\"{}\"", s)), Bool(b) => Some(format!("{}", b)), + Custom { string_rep } => Some(format!("{}", string_rep)), } }) }, @@ -58,8 +75,28 @@ impl ReplState { } } - fn eval_decl(&mut self, _decl: Declaration) -> EvalResult<()> { - Err("Not implmemented".to_string()) + fn eval_decl(&mut self, decl: Declaration) -> EvalResult<()> { + use self::Declaration::*; + use self::Variant::*; + + match decl { + FuncDecl(signature, statements) => { + let name = signature.name; + self.values.insert(name, ValueEntry::Function { body: statements.clone() }); + }, + TypeDecl(_name, body) => { + for variant in body.0.iter() { + match variant { + &UnitStruct(ref name) => self.values.insert(name.clone(), + ValueEntry::Binding { val: FullyEvaluatedExpr::Custom { string_rep: name.clone() } }), + &TupleStruct(ref name, ref args) => unimplemented!(), + &Record(ref name, ref fields) => unimplemented!(), + }; + } + }, + _ => return Err(format!("Declaration evaluation not yet implemented")) + } + Ok(()) } fn eval_expr(&mut self, expr: Expression) -> EvalResult { @@ -74,10 +111,28 @@ impl ReplState { BoolLiteral(b) => Ok(Bool(b)), PrefixExp(op, expr) => self.eval_prefix_exp(op, expr), BinExp(op, lhs, rhs) => self.eval_binexp(op, lhs, rhs), + Value(name) => self.eval_value(name), _ => Err(format!("Unimplemented")), } } + fn eval_value(&mut self, name: Rc) -> EvalResult { + use self::ValueEntry::*; + match self.values.get(&name) { + None => return Err(format!("Value {} not found", *name)), + Some(lookup) => { + match lookup { + &Binding { ref val } => Ok(val.clone()), + &Function { ref body } => { + Ok(FullyEvaluatedExpr::Custom { + string_rep: Rc::new(format!("", *name)) + }) + } + } + } + } + } + fn eval_binexp(&mut self, op: Operation, lhs: Box, rhs: Box) -> EvalResult { use self::FullyEvaluatedExpr::*; let evaled_lhs = self.eval_expr(*lhs)?;