Got LLVM structs working

This commit is contained in:
Richard Feldman 2020-03-10 02:40:08 -04:00
parent 8da7f26237
commit 913f18226b
2 changed files with 46 additions and 11 deletions

View file

@ -216,19 +216,18 @@ pub fn build_expr<'a, 'ctx, 'env>(
let array_type = get_array_type(&elem_type, 0); let array_type = get_array_type(&elem_type, 0);
let ptr_type = array_type.ptr_type(AddressSpace::Generic); let ptr_type = array_type.ptr_type(AddressSpace::Generic);
let struct_type = collection_wrapper(ctx, ptr_type); let struct_type = collection_wrapper(ctx, ptr_type);
let struct_val = struct_type.const_zero();
// The first field in the struct should be the pointer. // The first field in the struct should be the pointer.
builder let struct_val = builder
.build_insert_value( .build_insert_value(
struct_val, struct_type.const_zero(),
BasicValueEnum::PointerValue(ptr_type.const_null()), BasicValueEnum::PointerValue(ptr_type.const_null()),
0, 0,
"insert_ptr", "insert_ptr",
) )
.unwrap(); .unwrap();
BasicValueEnum::StructValue(struct_val) BasicValueEnum::StructValue(struct_val.into_struct_value())
} else { } else {
let len_u64 = elems.len() as u64; let len_u64 = elems.len() as u64;
let elem_bytes = elem_layout.stack_size(env.pointer_bytes) as u64; let elem_bytes = elem_layout.stack_size(env.pointer_bytes) as u64;
@ -257,24 +256,24 @@ pub fn build_expr<'a, 'ctx, 'env>(
let len = dbg!(BasicValueEnum::IntValue( let len = dbg!(BasicValueEnum::IntValue(
ctx.i32_type().const_int(len_u64, false) ctx.i32_type().const_int(len_u64, false)
)); ));
let struct_val = struct_type.const_zero(); let mut struct_val;
// Field 0: pointer // Field 0: pointer
builder struct_val = builder
.build_insert_value(struct_val, ptr_val, 0, "insert_ptr") .build_insert_value(struct_type.const_zero(), ptr_val, 0, "insert_ptr")
.unwrap(); .unwrap();
// Field 1: length // Field 1: length
builder struct_val = builder
.build_insert_value(struct_val, len, 1, "insert_len") .build_insert_value(struct_val, len, 1, "insert_len")
.unwrap(); .unwrap();
// Field 2: capacity (initially set to length) // Field 2: capacity (initially set to length)
builder struct_val = builder
.build_insert_value(struct_val, len, 2, "insert_capacity") .build_insert_value(struct_val, len, 2, "insert_capacity")
.unwrap(); .unwrap();
BasicValueEnum::StructValue(struct_val) BasicValueEnum::StructValue(struct_val.into_struct_value())
} }
} }
_ => { _ => {

View file

@ -494,6 +494,42 @@ mod test_gen {
assert_llvm_evals_to!("List.len [ 12, 9, 6, 3 ]", 4, i64, |x| x); assert_llvm_evals_to!("List.len [ 12, 9, 6, 3 ]", 4, i64, |x| x);
} }
#[test]
fn loaded_int_list_len() {
assert_llvm_evals_to!(
indoc!(
r#"
nums = [ 2, 4, 6 ]
List.len nums
"#
),
3,
i64,
|x| x
);
}
#[test]
fn fn_int_list_len() {
assert_llvm_evals_to!(
indoc!(
r#"
# TODO remove this annotation once monomorphization works!
getLen : List Int -> Int
getLen = \list -> List.len list
nums = [ 2, 4, 6 ]
getLen nums
"#
),
3,
i64,
|x| x
);
}
// #[test] // #[test]
// fn int_list_is_empty() { // fn int_list_is_empty() {
// assert_evals_to!("List.is_empty [ 12, 9, 6, 3 ]", 0, i32, |x| x); // assert_evals_to!("List.is_empty [ 12, 9, 6, 3 ]", 0, i32, |x| x);
@ -510,7 +546,7 @@ mod test_gen {
} }
#[test] #[test]
fn set_shared_int_list() { fn get_shared_int_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r#"