Few more places in codegen where we need to be able to deal with Pair records
This commit is contained in:
@@ -659,6 +659,12 @@ impl<'a> CodeGenerator<'a> {
|
||||
} => {
|
||||
if check_replaceable_opaque_type(&record.tipo(), &self.data_types) {
|
||||
self.build(record, module_build_name, &[])
|
||||
} else if record.tipo().is_pair() {
|
||||
AirTree::pair_index(
|
||||
*index,
|
||||
tipo.clone(),
|
||||
self.build(record, module_build_name, &[]),
|
||||
)
|
||||
} else {
|
||||
let function_name = format!("__access_index_{}", *index);
|
||||
|
||||
@@ -708,23 +714,37 @@ impl<'a> CodeGenerator<'a> {
|
||||
field_map,
|
||||
..
|
||||
} => {
|
||||
let data_type = lookup_data_type_by_tipo(&self.data_types, tipo);
|
||||
let val_constructor = if tipo.is_pair() {
|
||||
ValueConstructor::public(
|
||||
tipo.clone(),
|
||||
ValueConstructorVariant::Record {
|
||||
module: "".into(),
|
||||
name: name.clone(),
|
||||
field_map: field_map.clone(),
|
||||
arity: 2,
|
||||
location: Span::empty(),
|
||||
constructors_count: 1,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
let data_type = lookup_data_type_by_tipo(&self.data_types, tipo);
|
||||
|
||||
let val_constructor = ValueConstructor::public(
|
||||
tipo.clone(),
|
||||
ValueConstructorVariant::Record {
|
||||
name: name.clone(),
|
||||
arity: *arity,
|
||||
field_map: field_map.clone(),
|
||||
location: Span::empty(),
|
||||
module: module_name.clone(),
|
||||
constructors_count: data_type
|
||||
.expect("Created a module type without a definition?")
|
||||
.constructors
|
||||
.len()
|
||||
as u16,
|
||||
},
|
||||
);
|
||||
ValueConstructor::public(
|
||||
tipo.clone(),
|
||||
ValueConstructorVariant::Record {
|
||||
name: name.clone(),
|
||||
arity: *arity,
|
||||
field_map: field_map.clone(),
|
||||
location: Span::empty(),
|
||||
module: module_name.clone(),
|
||||
constructors_count: data_type
|
||||
.expect("Created a module type without a definition?")
|
||||
.constructors
|
||||
.len()
|
||||
as u16,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
AirTree::var(val_constructor, name, "")
|
||||
}
|
||||
@@ -772,43 +792,35 @@ impl<'a> CodeGenerator<'a> {
|
||||
TypedExpr::TupleIndex {
|
||||
index, tuple, tipo, ..
|
||||
} => {
|
||||
if tuple.tipo().is_pair() {
|
||||
AirTree::pair_index(
|
||||
*index,
|
||||
tipo.clone(),
|
||||
self.build(tuple, module_build_name, &[]),
|
||||
)
|
||||
} else {
|
||||
let function_name = format!("__access_index_{}", *index);
|
||||
let function_name = format!("__access_index_{}", *index);
|
||||
|
||||
if self.code_gen_functions.get(&function_name).is_none() {
|
||||
let mut body = AirTree::local_var("__fields", list(data()));
|
||||
if self.code_gen_functions.get(&function_name).is_none() {
|
||||
let mut body = AirTree::local_var("__fields", list(data()));
|
||||
|
||||
for _ in 0..*index {
|
||||
body = AirTree::builtin(
|
||||
DefaultFunction::TailList,
|
||||
list(data()),
|
||||
vec![body],
|
||||
)
|
||||
}
|
||||
|
||||
body = AirTree::builtin(DefaultFunction::HeadList, data(), vec![body]);
|
||||
|
||||
self.code_gen_functions.insert(
|
||||
function_name.clone(),
|
||||
CodeGenFunction::Function {
|
||||
body,
|
||||
params: vec!["__fields".to_string()],
|
||||
},
|
||||
);
|
||||
for _ in 0..*index {
|
||||
body = AirTree::builtin(
|
||||
DefaultFunction::TailList,
|
||||
list(data()),
|
||||
vec![body],
|
||||
)
|
||||
}
|
||||
|
||||
AirTree::index_access(
|
||||
function_name,
|
||||
tipo.clone(),
|
||||
self.build(tuple, module_build_name, &[]),
|
||||
)
|
||||
body = AirTree::builtin(DefaultFunction::HeadList, data(), vec![body]);
|
||||
|
||||
self.code_gen_functions.insert(
|
||||
function_name.clone(),
|
||||
CodeGenFunction::Function {
|
||||
body,
|
||||
params: vec!["__fields".to_string()],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
AirTree::index_access(
|
||||
function_name,
|
||||
tipo.clone(),
|
||||
self.build(tuple, module_build_name, &[]),
|
||||
)
|
||||
}
|
||||
|
||||
TypedExpr::ErrorTerm { tipo, .. } => AirTree::error(tipo.clone(), false),
|
||||
@@ -816,32 +828,66 @@ impl<'a> CodeGenerator<'a> {
|
||||
TypedExpr::RecordUpdate {
|
||||
tipo, spread, args, ..
|
||||
} => {
|
||||
let mut index_types = vec![];
|
||||
let mut update_args = vec![];
|
||||
if tipo.is_pair() {
|
||||
assert!(args.len() == 1);
|
||||
|
||||
let mut highest_index = 0;
|
||||
let Some(arg) = args.first() else {
|
||||
unreachable!("Pair update with no arguments")
|
||||
};
|
||||
|
||||
for arg in args
|
||||
.iter()
|
||||
.sorted_by(|arg1, arg2| arg1.index.cmp(&arg2.index))
|
||||
{
|
||||
let arg_val = self.build(&arg.value, module_build_name, &[]);
|
||||
|
||||
if arg.index > highest_index {
|
||||
highest_index = arg.index;
|
||||
let other_pair = self.build(spread, module_build_name, &[]);
|
||||
|
||||
if arg.index == 0 {
|
||||
AirTree::pair(
|
||||
arg_val,
|
||||
AirTree::pair_index(
|
||||
1,
|
||||
tipo.get_inner_types()[1].clone(),
|
||||
other_pair,
|
||||
),
|
||||
tipo.clone(),
|
||||
)
|
||||
} else {
|
||||
AirTree::pair(
|
||||
AirTree::pair_index(
|
||||
0,
|
||||
tipo.get_inner_types()[0].clone(),
|
||||
other_pair,
|
||||
),
|
||||
arg_val,
|
||||
tipo.clone(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
let mut index_types = vec![];
|
||||
let mut update_args = vec![];
|
||||
|
||||
let mut highest_index = 0;
|
||||
|
||||
for arg in args
|
||||
.iter()
|
||||
.sorted_by(|arg1, arg2| arg1.index.cmp(&arg2.index))
|
||||
{
|
||||
let arg_val = self.build(&arg.value, module_build_name, &[]);
|
||||
|
||||
if arg.index > highest_index {
|
||||
highest_index = arg.index;
|
||||
}
|
||||
|
||||
index_types.push((arg.index, arg.value.tipo()));
|
||||
update_args.push(arg_val);
|
||||
}
|
||||
|
||||
index_types.push((arg.index, arg.value.tipo()));
|
||||
update_args.push(arg_val);
|
||||
AirTree::record_update(
|
||||
index_types,
|
||||
highest_index,
|
||||
tipo.clone(),
|
||||
self.build(spread, module_build_name, &[]),
|
||||
update_args,
|
||||
)
|
||||
}
|
||||
|
||||
AirTree::record_update(
|
||||
index_types,
|
||||
highest_index,
|
||||
tipo.clone(),
|
||||
self.build(spread, module_build_name, &[]),
|
||||
update_args,
|
||||
)
|
||||
}
|
||||
TypedExpr::UnOp { value, op, .. } => {
|
||||
AirTree::unop(*op, self.build(value, module_build_name, &[]))
|
||||
@@ -4195,6 +4241,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
ValueConstructorVariant::Record {
|
||||
name: constr_name, ..
|
||||
} => {
|
||||
// TODO handle pair
|
||||
if constructor.tipo.is_bool() {
|
||||
Some(Term::bool(constr_name == "True"))
|
||||
} else if constructor.tipo.is_void() {
|
||||
|
||||
@@ -937,7 +937,7 @@ impl AirTree {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pair_index(index: usize, tipo: Rc<Type>, tuple: AirTree) -> AirTree {
|
||||
pub fn pair_index(index: u64, tipo: Rc<Type>, tuple: AirTree) -> AirTree {
|
||||
AirTree::cast_from_data(
|
||||
AirTree::builtin(
|
||||
if index == 0 {
|
||||
|
||||
Reference in New Issue
Block a user