mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
write implementation
This commit is contained in:
parent
aba01ad62a
commit
5e1077bf3e
2 changed files with 107 additions and 6 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue