mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 00:09:33 +03:00
Make using records in defs work
This commit is contained in:
parent
349857a468
commit
010e390fd6
@ -75,7 +75,7 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||
ret_layout,
|
||||
cond_layout,
|
||||
} => {
|
||||
let ret_type = basic_type_from_layout(env.context, &ret_layout);
|
||||
let ret_type = basic_type_from_layout(env.arena, env.context, &ret_layout);
|
||||
let switch_args = SwitchArgs {
|
||||
cond_layout: cond_layout.clone(),
|
||||
cond_expr: cond,
|
||||
@ -92,7 +92,7 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||
|
||||
for (symbol, layout, expr) in stores.iter() {
|
||||
let val = build_expr(env, &scope, parent, &expr, procs);
|
||||
let expr_bt = basic_type_from_layout(context, &layout);
|
||||
let expr_bt = basic_type_from_layout(env.arena, context, &layout);
|
||||
let alloca = create_entry_block_alloca(
|
||||
env,
|
||||
parent,
|
||||
@ -209,7 +209,7 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||
}
|
||||
Array { elem_layout, elems } => {
|
||||
let ctx = env.context;
|
||||
let elem_type = basic_type_from_layout(ctx, elem_layout);
|
||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout);
|
||||
let builder = env.builder;
|
||||
|
||||
if elems.is_empty() {
|
||||
@ -379,7 +379,7 @@ fn build_branch2<'a, 'ctx, 'env>(
|
||||
procs: &Procs<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let ret_layout = cond.ret_layout;
|
||||
let ret_type = basic_type_from_layout(env.context, &ret_layout);
|
||||
let ret_type = basic_type_from_layout(env.arena, env.context, &ret_layout);
|
||||
|
||||
let cond_expr = build_expr(env, scope, parent, cond.cond, procs);
|
||||
|
||||
@ -576,12 +576,12 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||
let args = proc.args;
|
||||
let arena = env.arena;
|
||||
let context = &env.context;
|
||||
let ret_type = basic_type_from_layout(context, &proc.ret_layout);
|
||||
let ret_type = basic_type_from_layout(arena, context, &proc.ret_layout);
|
||||
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
||||
let mut arg_symbols = Vec::new_in(arena);
|
||||
|
||||
for (layout, arg_symbol) in args.iter() {
|
||||
let arg_type = basic_type_from_layout(env.context, &layout);
|
||||
let arg_type = basic_type_from_layout(arena, env.context, &layout);
|
||||
|
||||
arg_basic_types.push(arg_type);
|
||||
arg_symbols.push(arg_symbol);
|
||||
|
@ -1,3 +1,5 @@
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use inkwell::context::Context;
|
||||
use inkwell::types::BasicTypeEnum::{self, *};
|
||||
use inkwell::types::{ArrayType, BasicType, FunctionType, PointerType, StructType};
|
||||
@ -33,6 +35,7 @@ pub fn get_array_type<'ctx>(bt_enum: &BasicTypeEnum<'ctx>, size: u32) -> ArrayTy
|
||||
}
|
||||
|
||||
pub fn basic_type_from_layout<'ctx>(
|
||||
arena: &Bump,
|
||||
context: &'ctx Context,
|
||||
layout: &Layout<'_>,
|
||||
) -> BasicTypeEnum<'ctx> {
|
||||
@ -41,20 +44,29 @@ pub fn basic_type_from_layout<'ctx>(
|
||||
|
||||
match layout {
|
||||
FunctionPointer(args, ret_layout) => {
|
||||
let ret_type = basic_type_from_layout(context, &ret_layout);
|
||||
let mut arg_basic_types = Vec::with_capacity(args.len());
|
||||
let ret_type = basic_type_from_layout(arena, context, &ret_layout);
|
||||
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
||||
|
||||
for arg_layout in args.iter() {
|
||||
arg_basic_types.push(basic_type_from_layout(context, arg_layout));
|
||||
arg_basic_types.push(basic_type_from_layout(arena, context, arg_layout));
|
||||
}
|
||||
|
||||
let fn_type = get_fn_type(&ret_type, arg_basic_types.as_slice());
|
||||
let fn_type = get_fn_type(&ret_type, arg_basic_types.into_bump_slice());
|
||||
let ptr_type = fn_type.ptr_type(AddressSpace::Generic);
|
||||
|
||||
ptr_type.as_basic_type_enum()
|
||||
}
|
||||
Struct(_fields) => {
|
||||
panic!("TODO layout_to_basic_type for Struct");
|
||||
Struct(sorted_fields) => {
|
||||
// Determine types
|
||||
let mut field_types = Vec::with_capacity_in(sorted_fields.len(), arena);
|
||||
|
||||
for (_, field_layout) in sorted_fields.iter() {
|
||||
field_types.push(basic_type_from_layout(arena, context, field_layout));
|
||||
}
|
||||
|
||||
context
|
||||
.struct_type(field_types.into_bump_slice(), false)
|
||||
.as_basic_type_enum()
|
||||
}
|
||||
Tag(_fields) => {
|
||||
panic!("TODO layout_to_basic_type for Tag");
|
||||
@ -74,8 +86,8 @@ pub fn basic_type_from_layout<'ctx>(
|
||||
Map(_, _) | EmptyMap => panic!("TODO layout_to_basic_type for Builtin::Map"),
|
||||
Set(_) | EmptySet => panic!("TODO layout_to_basic_type for Builtin::Set"),
|
||||
List(elem_layout) => {
|
||||
let ptr_type =
|
||||
basic_type_from_layout(context, elem_layout).ptr_type(AddressSpace::Generic);
|
||||
let ptr_type = basic_type_from_layout(arena, context, elem_layout)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
|
||||
collection_wrapper(context, ptr_type).into()
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ mod test_gen {
|
||||
// Compute main_fn_type before moving subs to Env
|
||||
let layout = Layout::from_content(&arena, content, &subs, POINTER_SIZE)
|
||||
.unwrap_or_else(|err| panic!("Code gen error in test: could not convert to layout. Err was {:?} and Subs were {:?}", err, subs));
|
||||
let main_fn_type = basic_type_from_layout(&context, &layout)
|
||||
let main_fn_type = basic_type_from_layout(&arena, &context, &layout)
|
||||
.fn_type(&[], false);
|
||||
let main_fn_name = "$Test.main";
|
||||
|
||||
@ -335,7 +335,7 @@ mod test_gen {
|
||||
// Compute main_fn_type before moving subs to Env
|
||||
let layout = Layout::from_content(&arena, content, &subs, POINTER_SIZE)
|
||||
.unwrap_or_else(|err| panic!("Code gen error in test: could not convert to layout. Err was {:?} and Subs were {:?}", err, subs));
|
||||
let main_fn_type = basic_type_from_layout(&context, &layout)
|
||||
let main_fn_type = basic_type_from_layout(&arena, &context, &layout)
|
||||
.fn_type(&[], false);
|
||||
let main_fn_name = "$Test.main";
|
||||
|
||||
@ -1097,4 +1097,43 @@ mod test_gen {
|
||||
i64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn def_record() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
rec = { y: 17, x: 15, z: 19 }
|
||||
|
||||
rec.x
|
||||
"#
|
||||
),
|
||||
15,
|
||||
i64
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
rec = { x: 15, y: 17, z: 19 }
|
||||
|
||||
rec.y
|
||||
"#
|
||||
),
|
||||
17,
|
||||
i64
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
rec = { x: 15, y: 17, z: 19 }
|
||||
|
||||
rec.z
|
||||
"#
|
||||
),
|
||||
19,
|
||||
i64
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ fn layout_from_flat_type<'a>(
|
||||
}
|
||||
};
|
||||
|
||||
let mut field_layouts;
|
||||
let mut field_layouts: Vec<'a, (Lowercase, Layout<'a>)>;
|
||||
|
||||
match ext_layout {
|
||||
Layout::Struct(more_fields) => {
|
||||
@ -266,6 +266,9 @@ fn layout_from_flat_type<'a>(
|
||||
field_layouts.push((label.clone(), field_layout));
|
||||
}
|
||||
|
||||
// Sort fields by label
|
||||
field_layouts.sort_by(|(a, _), (b, _)| a.cmp(b));
|
||||
|
||||
Ok(Layout::Struct(field_layouts.into_bump_slice()))
|
||||
}
|
||||
TagUnion(tags, ext_var) => {
|
||||
|
Loading…
Reference in New Issue
Block a user