move towards structure construction / deconstruction
This commit is contained in:
@@ -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)),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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())),
|
||||
|
||||
@@ -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(),
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user