Handle lambdas in reduced IR
This commit is contained in:
parent
7282a38a08
commit
4193971303
@ -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,
|
||||
|
@ -80,7 +80,11 @@ pub struct FunctionDefinition {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Function {
|
||||
Builtin(Builtin),
|
||||
UserDefined(DefId)
|
||||
UserDefined(DefId),
|
||||
Lambda {
|
||||
arity: u8,
|
||||
body: Vec<Statement>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -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<Expression>) -> EvalResult<Primitive> {
|
||||
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<Statement>, args: Vec<Expression>) -> EvalResult<Primitive> {
|
||||
|
||||
let mut evaluated_args: Vec<Primitive> = vec![];
|
||||
for arg in args.into_iter() {
|
||||
evaluated_args.push(self.expression(arg)?);
|
||||
}
|
||||
let mut evaluated_args: Vec<Primitive> = 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user