From 7a7e4ec0f203d5e3a25ff56b33c4a8db71ab5092 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sun, 24 Oct 2021 06:04:58 -0700 Subject: [PATCH] Use Primitive type in evaluator --- schala-lang/language/src/reduced_ir/mod.rs | 2 +- .../language/src/tree_walk_eval/mod.rs | 55 ++++++++++++++----- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index 664b682..0a84cb6 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -288,7 +288,7 @@ pub enum Lookup { Param, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Literal { Nat(u64), Int(i64), diff --git a/schala-lang/language/src/tree_walk_eval/mod.rs b/schala-lang/language/src/tree_walk_eval/mod.rs index 81f6cc9..189db57 100644 --- a/schala-lang/language/src/tree_walk_eval/mod.rs +++ b/schala-lang/language/src/tree_walk_eval/mod.rs @@ -59,13 +59,13 @@ fn paren_wrapped(terms: impl Iterator) -> String { #[derive(Debug)] enum RuntimeValue { - Expression(Expression), Function(FunctionDefinition), + Primitive(Primitive), } -impl From for RuntimeValue { - fn from(ex: Expression) -> Self { - Self::Expression(ex) +impl From for RuntimeValue { + fn from(prim: Primitive) -> Self { + Self::Primitive(prim) } } @@ -90,12 +90,40 @@ fn expr_to_repl(expr: &Expression) -> String { impl RuntimeValue { fn to_repl(&self) -> String { match self { - RuntimeValue::Expression(ref expr) => expr_to_repl(expr), + RuntimeValue::Primitive(ref prim) => expr_to_repl(&prim.to_expr()), RuntimeValue::Function(ref expr) => "".to_string(), } } } +/// A fully-reduced value +#[derive(Debug, Clone)] +enum Primitive { + Tuple(Vec), + Literal(Literal), + Callable(DefId), + Unimplemented, + /* + PrimObject { + name: Rc, + tag: usize, + items: Vec, + }, + */ +} + +impl Primitive { + fn to_expr(&self) -> Expression { + match self { + Primitive::Tuple(items) => Expression::Tuple(items.iter().map(|item| item.to_expr()).collect()), + Primitive::Literal(lit) => Expression::Literal(lit.clone()), + Primitive::Callable(defid) => Expression::Callable(Function::UserDefined(defid.clone())), + Primitive::Unimplemented => Expression::Unimplemented, + } + } +} + + impl<'a> State<'a> { pub fn new() -> Self { Self { @@ -141,25 +169,24 @@ impl<'a> State<'a> { } } - fn expression(&mut self, expression: Expression) -> EvalResult { + fn expression(&mut self, expression: Expression) -> EvalResult { use Expression::Unimplemented; Ok(match expression { - lit @ Expression::Literal(_) => lit, - Expression::Tuple(items) => Expression::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::>>()?), + Expression::Literal(lit) => Primitive::Literal(lit), + Expression::Tuple(items) => Primitive::Tuple(items.into_iter().map(|expr| self.expression(expr)).collect::>>()?), Expression::Lookup { ref id, kind } => { let mem = id.into(); match kind { Lookup::Function => { if self.environments.lookup(&mem).is_some() { - Expression::Callable(Function::UserDefined(id.clone())) + Primitive::Callable(id.clone()) } else { return Err(format!("Function not found for id: {}", id)); } }, kind @ Lookup::LocalVar | kind @ Lookup::GlobalVar | kind @ Lookup::Param => { match self.environments.lookup(&mem) { - //Some(RuntimeValue::Expression(expr)) => (*expr).clone(), - Some(RuntimeValue::Expression(expr)) => Unimplemented, + Some(RuntimeValue::Primitive(expr)) => expr.clone(), _ => return Err(format!("Nothing found for variable lookup {} of kind {:?}", id, kind)), } }, @@ -168,16 +195,16 @@ impl<'a> State<'a> { Expression::Assign { ref lval, box rval } => { let mem = lval.into(); let mut env = self.environments.lookup(&mem); - Unimplemented + Primitive::Unimplemented }, Expression::Call { box f, args } => self.call_expression(f, args)?, - Unimplemented => Unimplemented, + Unimplemented => Primitive::Unimplemented, Expression::ReductionError(e) => return Err(e.into()), e => return Err(format!("Can't yet handle {:?}", e)), }) } - fn call_expression(&mut self, f: Expression, args: Vec) -> EvalResult { + fn call_expression(&mut self, f: Expression, args: Vec) -> EvalResult { Err("Call expression not implemented".to_string().into()) } }