mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
a working version
This commit is contained in:
parent
73358b98bd
commit
6284a90785
4 changed files with 181 additions and 66 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue