access record fields progress

This commit is contained in:
Dan Bruder 2020-03-12 10:37:07 -04:00
parent 8e11d69c45
commit bfd9150af4
4 changed files with 62 additions and 33 deletions

View file

@ -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");

View file

@ -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,

View file

@ -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,

View file

@ -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,
}
}