mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +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),
|
EmptyArray => empty_polymorphic_list(env),
|
||||||
Array { elem_layout, elems } => list_literal(env, scope, elem_layout, elems),
|
Array { elem_layout, elems } => list_literal(env, scope, elem_layout, elems),
|
||||||
RuntimeErrorFunction(_) => todo!(),
|
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 {
|
GetTagId {
|
||||||
structure,
|
structure,
|
||||||
union_layout,
|
union_layout,
|
||||||
|
|
|
@ -1361,8 +1361,13 @@ impl<'a> Expr<'a> {
|
||||||
.text("GetTagId ")
|
.text("GetTagId ")
|
||||||
.append(symbol_to_doc(alloc, *structure)),
|
.append(symbol_to_doc(alloc, *structure)),
|
||||||
|
|
||||||
CoerceToTagId { tag_id, structure } => alloc
|
CoerceToTagId {
|
||||||
.text(format!("CoerceToTagId {} ", tag_id))
|
tag_id,
|
||||||
|
structure,
|
||||||
|
index,
|
||||||
|
..
|
||||||
|
} => alloc
|
||||||
|
.text(format!("CoerceToTagId (Id {}) (Index {}) ", tag_id, index))
|
||||||
.append(symbol_to_doc(alloc, *structure)),
|
.append(symbol_to_doc(alloc, *structure)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5546,10 +5551,12 @@ fn substitute_in_expr<'a>(
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
CoerceToTagId { structure, tag_id } => match substitute(subs, *structure) {
|
CoerceToTagId { structure, tag_id, index, union_layout } => match substitute(subs, *structure) {
|
||||||
Some(structure) => Some(CoerceToTagId {
|
Some(structure) => Some(CoerceToTagId {
|
||||||
structure,
|
structure,
|
||||||
tag_id: *tag_id,
|
tag_id: *tag_id,
|
||||||
|
index: *index,
|
||||||
|
union_layout: *union_layout,
|
||||||
}),
|
}),
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue