λ Support functions! #5

Open
acw wants to merge 59 commits from awick/functions into develop
7 changed files with 46 additions and 8 deletions
Showing only changes of commit fab5a230f1 - Show all commits

View File

@@ -406,8 +406,30 @@ impl<M: Module> Backend<M> {
}
}
Expression::Construct(_, _, _, _) => unimplemented!(),
Expression::FieldRef(_, _, _, _) => unimplemented!(),
Expression::Construct(_, ty, name, fields) => {
let Type::Structure(fields) = ty else {
panic!("Got to backend with non-structure type in structure construction?!");
};
unimplemented!()
}
Expression::FieldRef(_, _, struct_type, val, field) => {
let (structure, _) = self.compile_value_or_ref(val, variables, builder)?;
let Type::Structure(fields) = struct_type else {
panic!("Got to backend with non-structure type in field reference?!");
};
let Some((field_type, offset)) = fields.field_type_and_offset(&field) else {
panic!("Got to backend with invalid field for structure type?!");
};
let field_cranelift_type = self.translate_type(field_type).value_type;
let value = builder.ins().load(field_cranelift_type, MemFlags::new(), structure, offset);
Ok((value, field_cranelift_type))
}
Expression::Block(_, _, mut exprs) => match exprs.pop() {
None => Ok((builder.ins().iconst(types::I64, 0), VOID_REPR_TYPE)),

View File

@@ -113,7 +113,7 @@ pub enum Expression<Type> {
ArcIntern<String>,
HashMap<ArcIntern<String>, ValueOrRef<Type>>,
),
FieldRef(Location, Type, ValueOrRef<Type>, ArcIntern<String>),
FieldRef(Location, Type, Type, ValueOrRef<Type>, ArcIntern<String>),
Block(Location, Type, Vec<Expression<Type>>),
Print(Location, ValueOrRef<Type>),
Call(Location, Type, Box<ValueOrRef<Type>>, Vec<ValueOrRef<Type>>),
@@ -129,7 +129,7 @@ impl<Type: Clone + TypeWithVoid> Expression<Type> {
Expression::Cast(_, t, _) => t.clone(),
Expression::Primitive(_, t, _, _) => t.clone(),
Expression::Construct(_, t, _, _) => t.clone(),
Expression::FieldRef(_, t, _, _) => t.clone(),
Expression::FieldRef(_, t, _, _, _) => t.clone(),
Expression::Block(_, t, _) => t.clone(),
Expression::Print(_, _) => Type::void(),
Expression::Call(_, t, _, _) => t.clone(),
@@ -145,7 +145,7 @@ impl<Type: Clone + TypeWithVoid> Expression<Type> {
Expression::Cast(l, _, _) => l,
Expression::Primitive(l, _, _, _) => l,
Expression::Construct(l, _, _, _) => l,
Expression::FieldRef(l, _, _, _) => l,
Expression::FieldRef(l, _, _, _, _) => l,
Expression::Block(l, _, _) => l,
Expression::Print(l, _) => l,
Expression::Call(l, _, _, _) => l,

View File

@@ -91,7 +91,7 @@ where
Ok(Value::Structure(Some(name.clone()), result_fields))
}
Expression::FieldRef(loc, _, valref, field) => match valref.eval(env)? {
Expression::FieldRef(loc, _, _, valref, field) => match valref.eval(env)? {
Value::Structure(oname, mut fields) => match fields.remove(field) {
None => Err(EvalError::NoFieldForValue(
loc.clone(),

View File

@@ -119,6 +119,20 @@ impl<T> Fields<T> {
cranelift_description
})
}
pub fn field_type_and_offset(&self, field: &ArcIntern<String>) -> Option<(&T, i32)> {
let mut offset = 0;
for (current, ty) in self.fields.iter() {
if current == field {
return Some((ty, offset));
}
offset += 8;
}
None
}
}
impl<T> IntoIterator for Fields<T> {

View File

@@ -73,7 +73,7 @@ impl Expression<Type> {
.braces();
allocator.text(name.to_string()).append(inner)
}
Expression::FieldRef(_, _, val, field) => val.pretty(allocator).append(
Expression::FieldRef(_, _, _, val, field) => val.pretty(allocator).append(
allocator
.text(".")
.append(allocator.text(field.to_string())),

View File

@@ -338,6 +338,7 @@ fn convert_expression(
let result = ir::Expression::FieldRef(
loc.clone(),
result_type.clone(),
etype.clone(),
val_or_ref,
field.clone().intern(),
);

View File

@@ -73,9 +73,10 @@ fn finalize_expression(
.collect(),
),
Expression::FieldRef(loc, ty, valref, field) => Expression::FieldRef(
Expression::FieldRef(loc, ty, struct_type, valref, field) => Expression::FieldRef(
loc,
finalize_type(ty, resolutions),
finalize_type(struct_type, resolutions),
finalize_val_or_ref(valref, resolutions),
field,
),