write implementation

This commit is contained in:
Folkert 2021-06-20 21:55:04 +02:00
parent aba01ad62a
commit 5e1077bf3e
2 changed files with 107 additions and 6 deletions

View file

@ -1596,11 +1596,105 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
EmptyArray => empty_polymorphic_list(env),
Array { elem_layout, elems } => list_literal(env, scope, elem_layout, elems),
RuntimeErrorFunction(_) => todo!(),
CoerceToTagId { .. } => {
// we will do more here in the future
env.context.struct_type(&[], false).const_zero().into()
CoerceToTagId {
tag_id,
structure,
index,
union_layout,
} => {
let builder = env.builder;
// cast the argument bytes into the desired shape for this tag
let (argument, _structure_layout) = load_symbol_and_layout(scope, structure);
match union_layout {
UnionLayout::NonRecursive(tag_layouts) => {
debug_assert!(argument.is_struct_value());
let field_layouts = tag_layouts[*tag_id as usize];
let struct_layout = Layout::Struct(field_layouts);
let struct_type = basic_type_from_layout(env, &struct_layout);
let struct_value = access_index_struct_value(
builder,
argument.into_struct_value(),
struct_type.into_struct_type(),
);
builder
.build_extract_value(struct_value, *index as u32, "")
.expect("desired field did not decode")
}
UnionLayout::Recursive(tag_layouts) => {
debug_assert!(argument.is_pointer_value());
let field_layouts = tag_layouts[*tag_id as usize];
let struct_layout = Layout::Struct(field_layouts);
let struct_type = basic_type_from_layout(env, &struct_layout);
lookup_at_index_ptr(
env,
field_layouts,
*index as usize,
argument.into_pointer_value(),
struct_type.into_struct_type(),
&struct_layout,
)
}
UnionLayout::NonNullableUnwrapped(_) => todo!(),
UnionLayout::NullableWrapped {
nullable_id,
other_tags,
} => {
debug_assert!(argument.is_pointer_value());
debug_assert_ne!(*tag_id as i64, *nullable_id);
let tag_index = if (*tag_id as i64) < *nullable_id {
*tag_id
} else {
tag_id - 1
};
let field_layouts = other_tags[tag_index as usize];
let struct_layout = Layout::Struct(field_layouts);
let struct_type = basic_type_from_layout(env, &struct_layout);
lookup_at_index_ptr(
env,
field_layouts,
*index as usize,
argument.into_pointer_value(),
struct_type.into_struct_type(),
&struct_layout,
)
}
UnionLayout::NullableUnwrapped {
nullable_id,
other_fields,
} => {
debug_assert!(argument.is_pointer_value());
debug_assert_ne!(*tag_id != 0, *nullable_id);
let field_layouts = other_fields;
let struct_layout = Layout::Struct(field_layouts);
let struct_type = basic_type_from_layout(env, &struct_layout);
lookup_at_index_ptr(
env,
field_layouts,
*index as usize,
argument.into_pointer_value(),
struct_type.into_struct_type(),
&struct_layout,
)
}
}
}
GetTagId {
structure,
union_layout,