mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
access record fields progress
This commit is contained in:
parent
8e11d69c45
commit
bfd9150af4
4 changed files with 62 additions and 33 deletions
|
@ -194,16 +194,59 @@ pub fn build_expr<'a, B: Backend>(
|
|||
builder.ins().stack_store(val, slot, Offset32::new(offset));
|
||||
}
|
||||
|
||||
let ir_type = type_from_layout(cfg, layout);
|
||||
builder.ins().stack_addr(ir_type, slot, Offset32::new(0))
|
||||
builder
|
||||
.ins()
|
||||
.stack_addr(cfg.pointer_type(), slot, Offset32::new(0))
|
||||
}
|
||||
Access {
|
||||
label,
|
||||
field_layout,
|
||||
struct_layout: Layout::Struct(fields),
|
||||
record,
|
||||
} => {
|
||||
let cfg = env.cfg;
|
||||
|
||||
// Reconstruct the struct to determine the combined layout
|
||||
// TODO get rid of clones
|
||||
let mut reconstructed_struct_layout =
|
||||
Vec::with_capacity_in(fields.len() + 1, env.arena);
|
||||
for field in fields.iter() {
|
||||
reconstructed_struct_layout.push(field.clone());
|
||||
}
|
||||
reconstructed_struct_layout.push((label.clone(), field_layout.clone()));
|
||||
reconstructed_struct_layout.sort_by(|a, b| {
|
||||
a.0.partial_cmp(&b.0)
|
||||
.expect("TODO: failed to sort struct fields in crane access")
|
||||
});
|
||||
|
||||
// Find the offset we are trying to access
|
||||
let mut offset = 0;
|
||||
for (local_label, layout) in reconstructed_struct_layout.iter() {
|
||||
if local_label == label {
|
||||
break;
|
||||
}
|
||||
|
||||
let field_size = match layout {
|
||||
Layout::Builtin(Builtin::Int64) => std::mem::size_of::<i64>(),
|
||||
_ => panic!(
|
||||
"Missing struct field size in offset calculation for struct access for {:?}",
|
||||
layout
|
||||
),
|
||||
};
|
||||
|
||||
offset += field_size;
|
||||
}
|
||||
|
||||
let offset = i32::try_from(offset)
|
||||
.expect("TODO gracefully handle usize -> i32 conversion in struct access");
|
||||
|
||||
let mem_flags = MemFlags::new();
|
||||
let record = build_expr(env, scope, module, builder, record, procs);
|
||||
|
||||
builder
|
||||
.ins()
|
||||
.load(cfg.pointer_type(), mem_flags, record, Offset32::new(offset))
|
||||
}
|
||||
// Access {
|
||||
// label,
|
||||
// field_layout,
|
||||
// struct_layout,
|
||||
// } => {
|
||||
// panic!("I don't yet know how to crane build {:?}", expr);
|
||||
// }
|
||||
Str(str_literal) => {
|
||||
if str_literal.is_empty() {
|
||||
panic!("TODO build an empty string in Crane");
|
||||
|
|
|
@ -10,20 +10,7 @@ pub fn type_from_layout(cfg: TargetFrontendConfig, layout: &Layout<'_>) -> Type
|
|||
use roc_mono::layout::Layout::*;
|
||||
|
||||
match layout {
|
||||
Pointer(_) | FunctionPointer(_, _) => cfg.pointer_type(),
|
||||
Struct(fields) => {
|
||||
// This will change as we add more fields and field types to the tests
|
||||
let naive_all_ints = fields.iter().all(|ref field| match field.1 {
|
||||
Builtin(Int64) => true,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
if naive_all_ints && fields.len() == 3 {
|
||||
types::I64.by(4).unwrap()
|
||||
} else {
|
||||
panic!("TODO layout_to_crane_type for Struct");
|
||||
}
|
||||
}
|
||||
Pointer(_) | FunctionPointer(_, _) | Struct(_) => cfg.pointer_type(),
|
||||
Builtin(builtin) => match builtin {
|
||||
Int64 => types::I64,
|
||||
Float64 => types::F64,
|
||||
|
|
|
@ -873,9 +873,7 @@ mod test_gen {
|
|||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// point = { x: 15, y: 17, z: 19 }
|
||||
|
||||
// point.x
|
||||
// { y: 17, x: 15, z: 19 }.x
|
||||
// "#
|
||||
// ),
|
||||
// 15,
|
||||
|
@ -885,20 +883,17 @@ mod test_gen {
|
|||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// point = { x: 15, y: 17, z: 19 }
|
||||
|
||||
// point.y
|
||||
// { x: 15, y: 17, z: 19 }.y
|
||||
// "#
|
||||
// ),
|
||||
// 17,
|
||||
// i64
|
||||
// );
|
||||
|
||||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// point = { x: 15, y: 17, z: 19 }
|
||||
|
||||
// point.z
|
||||
// { x: 15, y: 17, z: 19 }.z
|
||||
// "#
|
||||
// ),
|
||||
// 19,
|
||||
|
|
|
@ -101,6 +101,7 @@ pub enum Expr<'a> {
|
|||
label: Lowercase,
|
||||
field_layout: Layout<'a>,
|
||||
struct_layout: Layout<'a>,
|
||||
record: &'a Expr<'a>,
|
||||
},
|
||||
|
||||
Array {
|
||||
|
@ -398,7 +399,7 @@ fn from_can<'a>(
|
|||
ext_var,
|
||||
field_var,
|
||||
field,
|
||||
..
|
||||
loc_expr,
|
||||
} => {
|
||||
let subs = env.subs;
|
||||
let arena = env.arena;
|
||||
|
@ -419,10 +420,13 @@ fn from_can<'a>(
|
|||
}
|
||||
};
|
||||
|
||||
let record = arena.alloc(from_can(env, loc_expr.value, procs, None));
|
||||
|
||||
Expr::Access {
|
||||
label: field,
|
||||
field_layout,
|
||||
struct_layout,
|
||||
record,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue