move towards structure construction / deconstruction
This commit is contained in:
@@ -406,8 +406,30 @@ impl<M: Module> Backend<M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression::Construct(_, _, _, _) => unimplemented!(),
|
Expression::Construct(_, ty, name, fields) => {
|
||||||
Expression::FieldRef(_, _, _, _) => unimplemented!(),
|
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() {
|
Expression::Block(_, _, mut exprs) => match exprs.pop() {
|
||||||
None => Ok((builder.ins().iconst(types::I64, 0), VOID_REPR_TYPE)),
|
None => Ok((builder.ins().iconst(types::I64, 0), VOID_REPR_TYPE)),
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ pub enum Expression<Type> {
|
|||||||
ArcIntern<String>,
|
ArcIntern<String>,
|
||||||
HashMap<ArcIntern<String>, ValueOrRef<Type>>,
|
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>>),
|
Block(Location, Type, Vec<Expression<Type>>),
|
||||||
Print(Location, ValueOrRef<Type>),
|
Print(Location, ValueOrRef<Type>),
|
||||||
Call(Location, Type, Box<ValueOrRef<Type>>, Vec<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::Cast(_, t, _) => t.clone(),
|
||||||
Expression::Primitive(_, t, _, _) => t.clone(),
|
Expression::Primitive(_, t, _, _) => t.clone(),
|
||||||
Expression::Construct(_, t, _, _) => t.clone(),
|
Expression::Construct(_, t, _, _) => t.clone(),
|
||||||
Expression::FieldRef(_, t, _, _) => t.clone(),
|
Expression::FieldRef(_, t, _, _, _) => t.clone(),
|
||||||
Expression::Block(_, t, _) => t.clone(),
|
Expression::Block(_, t, _) => t.clone(),
|
||||||
Expression::Print(_, _) => Type::void(),
|
Expression::Print(_, _) => Type::void(),
|
||||||
Expression::Call(_, t, _, _) => t.clone(),
|
Expression::Call(_, t, _, _) => t.clone(),
|
||||||
@@ -145,7 +145,7 @@ impl<Type: Clone + TypeWithVoid> Expression<Type> {
|
|||||||
Expression::Cast(l, _, _) => l,
|
Expression::Cast(l, _, _) => l,
|
||||||
Expression::Primitive(l, _, _, _) => l,
|
Expression::Primitive(l, _, _, _) => l,
|
||||||
Expression::Construct(l, _, _, _) => l,
|
Expression::Construct(l, _, _, _) => l,
|
||||||
Expression::FieldRef(l, _, _, _) => l,
|
Expression::FieldRef(l, _, _, _, _) => l,
|
||||||
Expression::Block(l, _, _) => l,
|
Expression::Block(l, _, _) => l,
|
||||||
Expression::Print(l, _) => l,
|
Expression::Print(l, _) => l,
|
||||||
Expression::Call(l, _, _, _) => l,
|
Expression::Call(l, _, _, _) => l,
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ where
|
|||||||
Ok(Value::Structure(Some(name.clone()), result_fields))
|
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) {
|
Value::Structure(oname, mut fields) => match fields.remove(field) {
|
||||||
None => Err(EvalError::NoFieldForValue(
|
None => Err(EvalError::NoFieldForValue(
|
||||||
loc.clone(),
|
loc.clone(),
|
||||||
|
|||||||
@@ -119,6 +119,20 @@ impl<T> Fields<T> {
|
|||||||
cranelift_description
|
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> {
|
impl<T> IntoIterator for Fields<T> {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ impl Expression<Type> {
|
|||||||
.braces();
|
.braces();
|
||||||
allocator.text(name.to_string()).append(inner)
|
allocator.text(name.to_string()).append(inner)
|
||||||
}
|
}
|
||||||
Expression::FieldRef(_, _, val, field) => val.pretty(allocator).append(
|
Expression::FieldRef(_, _, _, val, field) => val.pretty(allocator).append(
|
||||||
allocator
|
allocator
|
||||||
.text(".")
|
.text(".")
|
||||||
.append(allocator.text(field.to_string())),
|
.append(allocator.text(field.to_string())),
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ fn convert_expression(
|
|||||||
let result = ir::Expression::FieldRef(
|
let result = ir::Expression::FieldRef(
|
||||||
loc.clone(),
|
loc.clone(),
|
||||||
result_type.clone(),
|
result_type.clone(),
|
||||||
|
etype.clone(),
|
||||||
val_or_ref,
|
val_or_ref,
|
||||||
field.clone().intern(),
|
field.clone().intern(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -73,9 +73,10 @@ fn finalize_expression(
|
|||||||
.collect(),
|
.collect(),
|
||||||
),
|
),
|
||||||
|
|
||||||
Expression::FieldRef(loc, ty, valref, field) => Expression::FieldRef(
|
Expression::FieldRef(loc, ty, struct_type, valref, field) => Expression::FieldRef(
|
||||||
loc,
|
loc,
|
||||||
finalize_type(ty, resolutions),
|
finalize_type(ty, resolutions),
|
||||||
|
finalize_type(struct_type, resolutions),
|
||||||
finalize_val_or_ref(valref, resolutions),
|
finalize_val_or_ref(valref, resolutions),
|
||||||
field,
|
field,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user