From 6d8d2aecbd14370b0437c776bfe21db204c24f28 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 11 May 2018 23:23:54 -0700 Subject: [PATCH] Functions --- schala-lang/src/ast_reducing.rs | 2 ++ schala-lang/src/eval.rs | 20 ++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/schala-lang/src/ast_reducing.rs b/schala-lang/src/ast_reducing.rs index d75c20e..98a6e48 100644 --- a/schala-lang/src/ast_reducing.rs +++ b/schala-lang/src/ast_reducing.rs @@ -41,6 +41,7 @@ pub enum Lit { pub enum Func { BuiltIn(Rc), UserDefined { + name: Option>, params: Vec>, body: Vec, } @@ -98,6 +99,7 @@ impl Declaration { name: name.clone(), constant: true, expr: Expr::Func(Func::UserDefined { + name: None, params: params.iter().map(|param| param.0.clone()).collect(), body: statements.iter().map(|stmt| stmt.reduce()).collect(), }) diff --git a/schala-lang/src/eval.rs b/schala-lang/src/eval.rs index eceaed8..66671e0 100644 --- a/schala-lang/src/eval.rs +++ b/schala-lang/src/eval.rs @@ -336,6 +336,7 @@ impl<'a> State<'a> { impl Expr { fn to_repl(&self) -> String { use self::Lit::*; + use self::Func::*; match self { Expr::Lit(ref l) => match l { Nat(n) => format!("{}", n), @@ -344,6 +345,11 @@ impl Expr { Bool(b) => format!("{}", b), StringLit(s) => format!("{}", s), }, + Expr::Func(f) => match f { + BuiltIn(name) => format!("", name), + UserDefined { name: None, .. } => format!(""), + UserDefined { name: Some(name), .. } => format!("", name), + }, _ => format!("{:?}", self), } } @@ -384,14 +390,15 @@ impl<'a> State<'a> { literal @ Lit(_) => Ok(literal), Call { f, args } => self.apply_function(f, args), Val(v) => self.value(v), - _ => Err(format!("NOT IMPLEMENTED YET")) + func @ Func(_) => Ok(func), + e => Err(format!("Expr {:?} eval not implemented", e)) } } fn apply_function(&mut self, f: Func, args: Vec) -> EvalResult { match f { Func::BuiltIn(sigil) => self.apply_builtin(sigil, args), - Func::UserDefined { params, body } => { + Func::UserDefined { params, body, .. } => { Err(format!("Function application not done yet")) } } @@ -437,10 +444,16 @@ impl<'a> State<'a> { match self.values.lookup(&name) { None => return Err(format!("Value {} not found", *name)), Some(lookup) => match lookup { - &Binding { ref val, .. } => Ok(val.clone()), + Binding { val, .. } => Ok( + if let Expr::Func(Func::UserDefined { name: None, params, body }) = val { + Expr::Func(Func::UserDefined { name: Some(name.clone()), params: params.clone(), body: body.clone() }) //TODO here is unnecessary cloning + } else { + val.clone() + }), _ => Err(format!("Functions not done")), } } + } /* fn eval_value(&mut self, name: Rc) -> EvalResult { use self::ValueEntry::*; @@ -453,5 +466,4 @@ impl<'a> State<'a> { } } */ - } }