a working version

This commit is contained in:
Folkert 2021-08-18 17:36:27 +02:00
parent 73358b98bd
commit 6284a90785
4 changed files with 181 additions and 66 deletions

View file

@ -92,6 +92,11 @@ impl<'a> RawFunctionLayout<'a> {
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int8)))
}
Alias(Symbol::NUM_NAT, args, _) => {
debug_assert!(args.is_empty());
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Usize)))
}
// Floats
Alias(Symbol::NUM_F64, args, _) => {
debug_assert!(args.is_empty());
@ -102,6 +107,10 @@ impl<'a> RawFunctionLayout<'a> {
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Float32)))
}
Alias(symbol, _, _) if symbol.is_builtin() => Ok(Self::ZeroArgumentThunk(
Layout::new_help(env, var, content)?,
)),
Alias(_, _, var) => Self::from_var(env, var),
Error => Err(LayoutProblem::Erroneous),
}
@ -133,7 +142,8 @@ impl<'a> RawFunctionLayout<'a> {
Ok(Self::Function(fn_args, lambda_set, ret))
}
TagUnion(tags, _) if tags.is_newtype_wrapper(env.subs) => {
TagUnion(tags, ext) if tags.is_newtype_wrapper(env.subs) => {
debug_assert!(ext_var_is_empty_tag_union(env.subs, ext));
let slice_index = tags.variables().into_iter().next().unwrap();
let slice = env.subs[slice_index];
let var_index = slice.into_iter().next().unwrap();
@ -141,9 +151,13 @@ impl<'a> RawFunctionLayout<'a> {
Self::from_var(env, var)
}
Record(fields, _) if fields.len() == 1 => {
//
todo!()
Record(fields, ext) if fields.len() == 1 => {
debug_assert!(ext_var_is_empty_record(env.subs, ext));
let var_index = fields.iter_variables().next().unwrap();
let var = env.subs[var_index];
Self::from_var(env, var)
}
_ => {
let layout = layout_from_flat_type(env, flat_type)?;
@ -388,11 +402,16 @@ pub struct LambdaSet<'a> {
pub enum ClosureRepresentation<'a> {
/// the closure is represented as a union. Includes the tag ID!
Union {
tag_layout: &'a [Layout<'a>],
alphabetic_order_fields: &'a [Layout<'a>],
tag_name: TagName,
tag_id: u8,
union_layout: UnionLayout<'a>,
},
/// The closure is represented as a struct. The layouts are sorted
/// alphabetically by the identifier that is captured.
///
/// We MUST sort these according to their stack size before code gen!
AlphabeticOrderStruct(&'a [Layout<'a>]),
/// the representation is anything but a union
Other(Layout<'a>),
}
@ -428,9 +447,15 @@ impl<'a> LambdaSet<'a> {
.position(|(s, _)| *s == function_symbol)
.unwrap();
let (_, fields) = self
.set
.iter()
.find(|(s, _)| *s == function_symbol)
.unwrap();
ClosureRepresentation::Union {
tag_id: index as u8,
tag_layout: tags[index],
alphabetic_order_fields: fields,
tag_name: TagName::Closure(function_symbol),
union_layout: *union,
}
@ -447,6 +472,15 @@ impl<'a> LambdaSet<'a> {
} => todo!("recursive closures"),
}
}
Layout::Struct(_) => {
let (_, fields) = self
.set
.iter()
.find(|(s, _)| *s == function_symbol)
.unwrap();
ClosureRepresentation::AlphabeticOrderStruct(fields)
}
_ => ClosureRepresentation::Other(*self.representation),
}
}
@ -716,6 +750,12 @@ impl<'a> Layout<'a> {
Ok(Layout::Builtin(Builtin::Float32))
}
// Nat
Alias(Symbol::NUM_NAT, args, _) => {
debug_assert!(args.is_empty());
Ok(Layout::Builtin(Builtin::Usize))
}
Alias(_, _, var) => Self::from_var(env, var),
Error => Err(LayoutProblem::Erroneous),
}
@ -2176,6 +2216,20 @@ fn layout_from_tag_union<'a>(arena: &'a Bump, tags: UnionTags, subs: &Subs) -> L
}
}
#[cfg(debug_assertions)]
fn ext_var_is_empty_record(subs: &Subs, ext_var: Variable) -> bool {
// the ext_var is empty
let fields = roc_types::types::gather_fields(subs, RecordFields::empty(), ext_var);
fields.fields.is_empty()
}
#[cfg(not(debug_assertions))]
fn ext_var_is_empty_record(subs: &Subs, ext_var: Variable) -> bool {
// This should only ever be used in debug_assert! macros
unreachable!();
}
#[cfg(debug_assertions)]
fn ext_var_is_empty_tag_union(subs: &Subs, ext_var: Variable) -> bool {
// the ext_var is empty