diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index 9fa1bfd..e8e5740 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -130,7 +130,12 @@ impl<'a> Reducer<'a> { discriminator, body, } => Unimplemented, //self.reduce_if_expression(deref_optional_box(discriminator), body), - Lambda { params, body, .. } => Unimplemented, //self.reduce_lambda(params, body), + Lambda { params, body, .. } => { + Expression::Callable(Function::Lambda { + arity: params.len() as u8, + body: self.function(body), + }) + }, NamedStruct { name, fields } => Unimplemented, //self.reduce_named_struct(name, fields), Index { .. } => Unimplemented, WhileExpression { .. } => Unimplemented, diff --git a/schala-lang/language/src/reduced_ir/types.rs b/schala-lang/language/src/reduced_ir/types.rs index d2af782..273f174 100644 --- a/schala-lang/language/src/reduced_ir/types.rs +++ b/schala-lang/language/src/reduced_ir/types.rs @@ -80,7 +80,11 @@ pub struct FunctionDefinition { #[derive(Debug, Clone)] pub enum Function { Builtin(Builtin), - UserDefined(DefId) + UserDefined(DefId), + Lambda { + arity: u8, + body: Vec + } } #[derive(Debug, Clone)] diff --git a/schala-lang/language/src/tree_walk_eval/mod.rs b/schala-lang/language/src/tree_walk_eval/mod.rs index 2114189..fbcdd3b 100644 --- a/schala-lang/language/src/tree_walk_eval/mod.rs +++ b/schala-lang/language/src/tree_walk_eval/mod.rs @@ -246,7 +246,23 @@ impl<'a> State<'a> { }; match func { Function::Builtin(builtin) => self.apply_builtin(builtin, args), - Function::UserDefined(def_id) => self.apply_function(def_id, args), + Function::UserDefined(def_id) => { + let mem = (&def_id).into(); + match self.environments.lookup(&mem) { + Some(RuntimeValue::Function(FunctionDefinition { body })) => { + let body = body.clone(); //TODO ideally this clone would not happen + self.apply_function(body, args) + }, + e => Err(format!("Error looking up function with id {}: {:?}", def_id, e)) + } + }, + Function::Lambda { arity, body } => { + if arity as usize != args.len() { + return Err(format!("Lambda expression requries {} arguments, only {} provided", arity, args.len())); + } + let body = body.clone(); //TODO again ideally, no cloning here + self.apply_function(body, args) + } } } @@ -331,31 +347,24 @@ impl<'a> State<'a> { }) } - 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 })) => { - let body = body.clone(); //TODO ideally this clone would not happen + fn apply_function(&mut self, body: Vec, args: Vec) -> EvalResult { - let mut evaluated_args: Vec = vec![]; - for arg in args.into_iter() { - evaluated_args.push(self.expression(arg)?); - } + let mut evaluated_args: Vec = vec![]; + for arg in args.into_iter() { + evaluated_args.push(self.expression(arg)?); + } - let mut frame_state = State { - environments: self.environments.new_scope(None) - }; + let mut frame_state = State { + environments: self.environments.new_scope(None) + }; - for (n, evaled) in evaluated_args.into_iter().enumerate() { - let n = n as u8; - let mem = n.into(); - frame_state.environments.insert(mem, RuntimeValue::Primitive(evaled)); - } + for (n, evaled) in evaluated_args.into_iter().enumerate() { + let n = n as u8; + let mem = n.into(); + frame_state.environments.insert(mem, RuntimeValue::Primitive(evaled)); + } - frame_state.block(body)? - }, - e => return Err(format!("Error looking up function with id {}: {:?}", def_id, e)), - }) + frame_state.block(body) } }