store/define tags in llvm

This commit is contained in:
Folkert 2020-03-16 23:35:16 +01:00
parent 72ca6d675c
commit 6ff22de9dd

View file

@ -11,7 +11,7 @@ use inkwell::{AddressSpace, FloatPredicate, IntPredicate};
use crate::llvm::convert::{ use crate::llvm::convert::{
basic_type_from_layout, collection_wrapper, get_array_type, get_fn_type, basic_type_from_layout, collection_wrapper, get_array_type, get_fn_type,
}; };
use roc_collections::all::ImMap; use roc_collections::all::{ImMap, MutMap};
use roc_module::symbol::{Interns, Symbol}; use roc_module::symbol::{Interns, Symbol};
use roc_mono::expr::{Expr, Proc, Procs}; use roc_mono::expr::{Expr, Proc, Procs};
use roc_mono::layout::{Builtin, Layout}; use roc_mono::layout::{Builtin, Layout};
@ -315,6 +315,48 @@ pub fn build_expr<'a, 'ctx, 'env>(
BasicValueEnum::StructValue(struct_val.into_struct_value()) BasicValueEnum::StructValue(struct_val.into_struct_value())
} }
Tag {
tag_id,
tag_layout,
arguments,
..
} => {
// put the discriminant in the first slot
let discriminant = (
Expr::Byte(*tag_id),
Layout::Builtin(Builtin::Byte(MutMap::default())),
);
let it = std::iter::once(&discriminant).chain(arguments.iter());
let ctx = env.context;
let builder = env.builder;
// Determine types
let num_fields = arguments.len() + 1;
let mut field_types = Vec::with_capacity_in(num_fields, env.arena);
let mut field_vals = Vec::with_capacity_in(num_fields, env.arena);
for (field_expr, field_layout) in it {
let val = build_expr(env, &scope, parent, field_expr, procs);
let field_type = basic_type_from_layout(env.arena, env.context, &field_layout);
field_types.push(field_type);
field_vals.push(val);
}
// Create the struct_type
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
let mut struct_val = struct_type.const_zero().into();
// Insert field exprs into struct_val
for (index, field_val) in field_vals.into_iter().enumerate() {
struct_val = builder
.build_insert_value(struct_val, field_val, index as u32, "insert_field")
.unwrap();
}
BasicValueEnum::StructValue(struct_val.into_struct_value())
}
Access { Access {
label, label,
field_layout, field_layout,