From b1966d7199418f639ac25c9b57c79484eb1431b1 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 12 May 2018 00:59:50 -0700 Subject: [PATCH] Function calling works kind of --- schala-lang/src/ast_reducing.rs | 1 + schala-lang/src/eval.rs | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/schala-lang/src/ast_reducing.rs b/schala-lang/src/ast_reducing.rs index 4fadc15..bb3286b 100644 --- a/schala-lang/src/ast_reducing.rs +++ b/schala-lang/src/ast_reducing.rs @@ -18,6 +18,7 @@ pub enum Stmt { #[derive(Debug, Clone)] pub enum Expr { + Unit, Lit(Lit), Func(Func), Val(Rc), diff --git a/schala-lang/src/eval.rs b/schala-lang/src/eval.rs index 8d20af5..8b39584 100644 --- a/schala-lang/src/eval.rs +++ b/schala-lang/src/eval.rs @@ -404,8 +404,21 @@ impl<'a> State<'a> { fn apply_function(&mut self, f: Func, args: Vec) -> EvalResult { match f { Func::BuiltIn(sigil) => self.apply_builtin(sigil, args), - Func::UserDefined { params, body, .. } => { - Err(format!("Function application not done yet")) + Func::UserDefined { params, body, name } => { + + if params.len() != args.len() { + return Err(format!("Runtime error: calling a {}-argument function with {} args", params.len(), args.len())) + } + let mut func_state = State { values: self.values.new_frame(name.map(|n| format!("{}", n))) }; + for (param, val) in params.into_iter().zip(args.into_iter()) { + func_state.values.insert(param, ValueEntry::Binding { constant: true, val }); + } + // TODO figure out function return semantics + let mut ret = None; + for stmt in body { + ret = func_state.statement(stmt)?; + } + Ok(ret.unwrap_or(Expr::Unit)) } } }