diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index 0a84cb6..c4af742 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -271,10 +271,10 @@ pub enum Expression { #[derive(Debug)] pub struct FunctionDefinition { - body: Vec + pub body: Vec } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Function { Builtin(Builtin), UserDefined(DefId) diff --git a/schala-lang/language/src/tree_walk_eval/mod.rs b/schala-lang/language/src/tree_walk_eval/mod.rs index 189db57..8edb576 100644 --- a/schala-lang/language/src/tree_walk_eval/mod.rs +++ b/schala-lang/language/src/tree_walk_eval/mod.rs @@ -1,6 +1,7 @@ use crate::reduced_ir::{ReducedIR, Expression, Lookup, Function, FunctionDefinition, Statement, Literal}; use crate::symbol_table::{DefId}; use crate::util::ScopeStack; +use crate::builtin::Builtin; use std::fmt::Write; use std::convert::From; @@ -101,7 +102,7 @@ impl RuntimeValue { enum Primitive { Tuple(Vec), Literal(Literal), - Callable(DefId), + Callable(Function), Unimplemented, /* PrimObject { @@ -117,7 +118,7 @@ impl Primitive { 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::Callable(function) => Expression::Callable(function.clone()), Primitive::Unimplemented => Expression::Unimplemented, } } @@ -177,12 +178,10 @@ impl<'a> State<'a> { Expression::Lookup { ref id, kind } => { let mem = id.into(); match kind { - Lookup::Function => { - if self.environments.lookup(&mem).is_some() { - Primitive::Callable(id.clone()) - } else { - return Err(format!("Function not found for id: {}", id)); - } + Lookup::Function => match self.environments.lookup(&mem) { + //TODO is this right? not sure + Some(RuntimeValue::Primitive(prim)) => prim.clone(), + _ => return Err(format!("Function not found for id: {}", id)), }, kind @ Lookup::LocalVar | kind @ Lookup::GlobalVar | kind @ Lookup::Param => { match self.environments.lookup(&mem) { @@ -205,7 +204,28 @@ impl<'a> State<'a> { } fn call_expression(&mut self, f: Expression, args: Vec) -> EvalResult { - Err("Call expression not implemented".to_string().into()) + let func = match self.expression(f)? { + Primitive::Callable(func) => func, + other => return Err(format!("Trying to call non-function value: {:?}", other)), + }; + match func { + Function::Builtin(builtin) => self.apply_builtin(builtin, args), + Function::UserDefined(def_id) => self.apply_function(def_id, args), + } + } + + fn apply_builtin(&mut self, builtin: Builtin, args: Vec) -> EvalResult { + return Err("unimplemented apply-builtin".to_string()); + } + + fn apply_function(&mut self, def_id: DefId, args: Vec) -> EvalResult { + let mem = (&def_id).into(); + Ok(match self.environments.lookup(&mem) { + Some(RuntimeValue::Function(FunctionDefinition { body })) => { + return Err("unimplemented apply-function".to_string()); + }, + e => return Err(format!("Error looking up function with id {}: {:?}", def_id, e)), + }) } }