Handle lambdas in reduced IR
This commit is contained in:
parent
7282a38a08
commit
4193971303
@ -130,7 +130,12 @@ impl<'a> Reducer<'a> {
|
|||||||
discriminator,
|
discriminator,
|
||||||
body,
|
body,
|
||||||
} => Unimplemented, //self.reduce_if_expression(deref_optional_box(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),
|
NamedStruct { name, fields } => Unimplemented, //self.reduce_named_struct(name, fields),
|
||||||
Index { .. } => Unimplemented,
|
Index { .. } => Unimplemented,
|
||||||
WhileExpression { .. } => Unimplemented,
|
WhileExpression { .. } => Unimplemented,
|
||||||
|
@ -80,7 +80,11 @@ pub struct FunctionDefinition {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Function {
|
pub enum Function {
|
||||||
Builtin(Builtin),
|
Builtin(Builtin),
|
||||||
UserDefined(DefId)
|
UserDefined(DefId),
|
||||||
|
Lambda {
|
||||||
|
arity: u8,
|
||||||
|
body: Vec<Statement>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -246,7 +246,23 @@ impl<'a> State<'a> {
|
|||||||
};
|
};
|
||||||
match func {
|
match func {
|
||||||
Function::Builtin(builtin) => self.apply_builtin(builtin, args),
|
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> {
|
fn apply_function(&mut self, body: Vec<Statement>, 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
|
|
||||||
|
|
||||||
let mut evaluated_args: Vec<Primitive> = vec![];
|
let mut evaluated_args: Vec<Primitive> = vec![];
|
||||||
for arg in args.into_iter() {
|
for arg in args.into_iter() {
|
||||||
evaluated_args.push(self.expression(arg)?);
|
evaluated_args.push(self.expression(arg)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut frame_state = State {
|
let mut frame_state = State {
|
||||||
environments: self.environments.new_scope(None)
|
environments: self.environments.new_scope(None)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (n, evaled) in evaluated_args.into_iter().enumerate() {
|
for (n, evaled) in evaluated_args.into_iter().enumerate() {
|
||||||
let n = n as u8;
|
let n = n as u8;
|
||||||
let mem = n.into();
|
let mem = n.into();
|
||||||
frame_state.environments.insert(mem, RuntimeValue::Primitive(evaled));
|
frame_state.environments.insert(mem, RuntimeValue::Primitive(evaled));
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_state.block(body)?
|
frame_state.block(body)
|
||||||
},
|
|
||||||
e => return Err(format!("Error looking up function with id {}: {:?}", def_id, e)),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user