mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 00:09:33 +03:00
implement layout for Tag
This commit is contained in:
parent
8c7124aba6
commit
d875f8bfce
@ -10,7 +10,7 @@ pub fn type_from_layout(cfg: TargetFrontendConfig, layout: &Layout<'_>) -> Type
|
||||
use roc_mono::layout::Layout::*;
|
||||
|
||||
match layout {
|
||||
Pointer(_) | FunctionPointer(_, _) | Struct(_) | Tag(_) => cfg.pointer_type(),
|
||||
Pointer(_) | FunctionPointer(_, _) | Struct(_) | Union(_) => cfg.pointer_type(),
|
||||
Builtin(builtin) => match builtin {
|
||||
Int64 => types::I64,
|
||||
Float64 => types::F64,
|
||||
|
@ -68,7 +68,7 @@ pub fn basic_type_from_layout<'ctx>(
|
||||
.struct_type(field_types.into_bump_slice(), false)
|
||||
.as_basic_type_enum()
|
||||
}
|
||||
Tag(_fields) => {
|
||||
Union(_fields) => {
|
||||
panic!("TODO layout_to_basic_type for Tag");
|
||||
}
|
||||
Pointer(_layout) => {
|
||||
|
@ -124,7 +124,9 @@ fn flatten_patterns<'a>(branch: Branch<'a>) -> Branch<'a> {
|
||||
|
||||
fn flatten<'a>(path_pattern: (Path, Pattern<'a>), path_patterns: &mut Vec<(Path, Pattern<'a>)>) {
|
||||
match &path_pattern.1 {
|
||||
Pattern::AppliedTag { union, .. } => {
|
||||
Pattern::AppliedTag {
|
||||
union, arguments, ..
|
||||
} => {
|
||||
if union.alternatives.len() == 1 {
|
||||
// case map dearg ctorArgs of
|
||||
// [arg] ->
|
||||
|
@ -104,6 +104,7 @@ pub struct Env<'a, 'i> {
|
||||
pub ident_ids: &'i mut IdentIds,
|
||||
pub pointer_size: u32,
|
||||
symbol_counter: usize,
|
||||
pub jump_counter: &'a mut u64,
|
||||
}
|
||||
|
||||
impl<'a, 'i> Env<'a, 'i> {
|
||||
@ -217,6 +218,7 @@ impl<'a> Expr<'a> {
|
||||
ident_ids,
|
||||
pointer_size,
|
||||
symbol_counter: 0,
|
||||
jump_counter: arena.alloc(0),
|
||||
};
|
||||
|
||||
from_can(&mut env, can_expr, procs, None)
|
||||
|
@ -10,7 +10,7 @@ use roc_types::subs::{Content, FlatType, Subs, Variable};
|
||||
pub enum Layout<'a> {
|
||||
Builtin(Builtin<'a>),
|
||||
Struct(&'a [(Lowercase, Layout<'a>)]),
|
||||
Tag(&'a [Layout<'a>]),
|
||||
Union(&'a MutMap<TagName, &'a [Layout<'a>]>),
|
||||
Pointer(&'a Layout<'a>),
|
||||
/// A function. The types of its arguments, then the type of its return value.
|
||||
FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>),
|
||||
@ -93,12 +93,15 @@ impl<'a> Layout<'a> {
|
||||
|
||||
sum
|
||||
}
|
||||
Tag(fields) => {
|
||||
// the symbol is a 64-bit value, so 8 bytes
|
||||
let mut sum = 8;
|
||||
Union(fields) => {
|
||||
// the tag gets converted to a u8, so 1 byte.
|
||||
// But for one-tag unions, we don't store the tag, so 0 bytes
|
||||
let mut sum = (fields.len() > 1) as u32;
|
||||
|
||||
for field_layout in *fields {
|
||||
sum += field_layout.stack_size(pointer_size);
|
||||
for (_, tag_layout) in *fields {
|
||||
for field_layout in *tag_layout {
|
||||
sum += field_layout.stack_size(pointer_size);
|
||||
}
|
||||
}
|
||||
|
||||
sum
|
||||
@ -344,8 +347,18 @@ fn layout_from_flat_type<'a>(
|
||||
Ok(Layout::Builtin(Builtin::Byte(tag_to_u8)))
|
||||
}
|
||||
} else {
|
||||
// panic!("TODO handle a tag union with mutliple tags: {:?}", tags);
|
||||
Ok(Layout::Tag(&[]))
|
||||
let mut layouts = MutMap::default();
|
||||
for (tag_name, arguments) in tags {
|
||||
let mut arg_layouts = Vec::with_capacity_in(arguments.len(), arena);
|
||||
|
||||
for arg in arguments {
|
||||
arg_layouts.push(Layout::from_var(arena, arg, subs, pointer_size)?);
|
||||
}
|
||||
|
||||
layouts.insert(tag_name, arg_layouts.into_bump_slice());
|
||||
}
|
||||
|
||||
Ok(Layout::Union(arena.alloc(layouts)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user