feat: almost done

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
rvcas 2023-03-23 23:06:02 -04:00 committed by Lucas
parent 709ee914ed
commit f07a959ab8
3 changed files with 255 additions and 319 deletions

View File

@ -35,7 +35,7 @@ use builder::{
AssignmentProperties, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
};
use self::stack::AirStack;
use self::{scope::Scope, stack::AirStack};
#[derive(Clone)]
pub struct CodeGenerator<'a> {
@ -456,19 +456,20 @@ impl<'a> CodeGenerator<'a> {
let constr_var = format!("__constr_name_{}", self.id_gen.next());
let subject_tipo = subject.tipo();
if clauses.len() <= 1 {
let mut value_vec: Vec<Air> = vec![];
let mut pattern_vec: Vec<Air> = vec![];
let mut subject_vec: Vec<Air> = vec![];
let mut value_stack = ir_stack.empty_with_scope();
let mut pattern_stack = ir_stack.empty_with_scope();
let mut subject_stack = ir_stack.empty_with_scope();
self.build(&clauses[0].then, &mut value_vec);
self.build(&clauses[0].then, &mut value_stack);
self.build(subject, &mut subject_vec);
self.build(subject, &mut subject_stack);
self.assignment(
&clauses[0].pattern,
&mut pattern_vec,
&mut subject_vec,
&mut pattern_stack,
subject_stack,
&subject_tipo,
AssignmentProperties {
value_type: clauses[0].then.tipo(),
@ -476,10 +477,10 @@ impl<'a> CodeGenerator<'a> {
},
);
ir_stack.append(&mut pattern_vec);
ir_stack.append(&mut value_vec);
pattern_stack.merge_child(value_stack);
ir_stack.merge_child(pattern_stack);
} else {
// HERE TODO
// TODO: go over rearrange clauses
let clauses = if subject_tipo.is_list() {
builder::rearrange_clauses(clauses.clone())
} else {
@ -487,7 +488,7 @@ impl<'a> CodeGenerator<'a> {
};
if let Some((last_clause, clauses)) = clauses.split_last() {
let mut pattern_vec = vec![];
let mut pattern_stack = ir_stack.empty_with_scope();
let mut clause_properties = ClauseProperties::init(
&subject_tipo,
@ -496,7 +497,7 @@ impl<'a> CodeGenerator<'a> {
);
self.handle_each_clause(
&mut pattern_vec,
&mut pattern_stack,
&mut clause_properties,
clauses,
&subject_tipo,
@ -504,75 +505,59 @@ impl<'a> CodeGenerator<'a> {
let last_pattern = &last_clause.pattern;
let mut final_scope = scope.clone();
let mut final_pattern_stack = ir_stack.empty_with_scope();
let mut final_clause_stack = ir_stack.empty_with_scope();
let mut finally_stack = ir_stack.empty_with_scope();
final_scope.push(self.id_gen.next());
if !matches!(last_pattern, Pattern::Tuple { .. }) {
pattern_vec.push(Air::Finally {
scope: final_scope.clone(),
});
}
let mut final_clause_vec = vec![];
self.build(&last_clause.then, &mut final_clause_vec);
self.build(&last_clause.then, &mut final_clause_stack);
*clause_properties.is_final_clause() = true;
self.when_ir(
self.when_pattern(
last_pattern,
&mut pattern_vec,
&mut final_clause_vec,
&mut final_pattern_stack,
final_clause_stack,
&subject_tipo,
&mut clause_properties,
final_scope,
);
if *clause_properties.needs_constr_var() {
ir_stack.push(Air::Let {
scope: scope.clone(),
name: constr_var.clone(),
});
let mut subject_scope = scope.clone();
subject_scope.push(self.id_gen.next());
self.build(subject, ir_stack);
let mut scope = scope;
scope.push(self.id_gen.next());
ir_stack.push(Air::When {
scope: scope.clone(),
subject_name,
tipo: subject_tipo.clone(),
});
ir_stack.push(Air::Var {
scope,
constructor: ValueConstructor::public(
subject_tipo,
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: constr_var,
variant_name: String::new(),
})
if !matches!(last_pattern, Pattern::Tuple { .. }) {
finally_stack.finally(final_pattern_stack);
} else {
ir_stack.push(Air::When {
scope: scope.clone(),
subject_name,
tipo: subject_tipo,
});
let mut scope = scope;
scope.push(self.id_gen.next());
self.build(subject, ir_stack);
finally_stack.merge(final_pattern_stack);
}
ir_stack.append(&mut pattern_vec);
if *clause_properties.needs_constr_var() {
let mut subject_stack = ir_stack.empty_with_scope();
self.build(subject, &mut subject_stack);
ir_stack.let_assignment(constr_var.clone(), subject_stack);
let mut var_stack = ir_stack.empty_with_scope();
var_stack.local_var(subject_tipo.clone(), constr_var);
ir_stack.when(
subject_tipo,
subject_name,
var_stack,
pattern_stack,
finally_stack,
);
} else {
let mut subject_stack = ir_stack.empty_with_scope();
self.build(subject, &mut subject_stack);
ir_stack.when(
subject_tipo,
subject_name,
subject_stack,
pattern_stack,
finally_stack,
);
}
}
}
}
@ -649,7 +634,6 @@ impl<'a> CodeGenerator<'a> {
TypedExpr::RecordUpdate {
spread, args, tipo, ..
} => {
let mut update_ir = vec![];
let mut index_types = vec![];
let mut highest_index = 0;
@ -722,7 +706,7 @@ impl<'a> CodeGenerator<'a> {
fn handle_each_clause(
&mut self,
ir_stack: &mut Vec<Air>,
ir_stack: &mut AirStack,
clause_properties: &mut ClauseProperties,
clauses: &[TypedClause],
subject_type: &Arc<Type>,
@ -746,7 +730,9 @@ impl<'a> CodeGenerator<'a> {
if let Some(clause_guard) = &clause.guard {
let mut clause_guard_vec = vec![];
*clause_properties.is_complex_clause() = true;
let clause_guard_name = format!("__clause_guard_{}", self.id_gen.next());
let mut clause_guard_scope = scope.clone();
@ -787,13 +773,13 @@ impl<'a> CodeGenerator<'a> {
let mut clause_scope = scope.clone();
clause_scope.push(self.id_gen.next());
self.when_ir(
self.when_pattern(
&clause.pattern,
&mut clause_subject_vec,
&mut clause_then_vec,
subject_type,
clause_properties,
clause_scope,
);
let data_type =
@ -814,6 +800,7 @@ impl<'a> CodeGenerator<'a> {
complex_clause: *clause_properties.is_complex_clause(),
subject_name,
});
let mut scope = scope;
scope.push(self.id_gen.next());
@ -840,11 +827,11 @@ impl<'a> CodeGenerator<'a> {
if let Pattern::List { elements, tail, .. } = &clause.pattern {
(elements.len(), tail.is_some())
} else if let Pattern::Assign { pattern, .. } = &clause.pattern {
if let Pattern::List { elements, tail, .. } = pattern.as_ref() {
(elements.len(), tail.is_some())
} else {
let Pattern::List { elements, tail, .. } = pattern.as_ref() else {
unreachable!("{:#?}", pattern)
}
};
(elements.len(), tail.is_some())
} else {
unreachable!("{:#?}", &clause.pattern)
};
@ -857,13 +844,12 @@ impl<'a> CodeGenerator<'a> {
format!("__tail_{}", current_clause_index - 1)
};
self.when_ir(
self.when_pattern(
&clause.pattern,
&mut clause_subject_vec,
&mut clause_then_vec,
subject_type,
clause_properties,
scope.clone(),
);
let next_tail = if index == clauses.len() - 1 {
@ -891,8 +877,7 @@ impl<'a> CodeGenerator<'a> {
}
};
#[allow(clippy::bool_to_int_with_if)]
let minus_tail = if has_tail { 1 } else { 0 };
let minus_tail = has_tail as i64;
if current_clause_index as i64 - minus_tail == prev_index {
ir_stack.push(Air::WrapClause { scope });
@ -906,12 +891,11 @@ impl<'a> CodeGenerator<'a> {
});
}
match clause_properties {
ClauseProperties::ListClause { current_index, .. } => {
*current_index = current_clause_index as i64;
}
_ => unreachable!(),
}
let ClauseProperties::ListClause { current_index, .. } = clause_properties else {
unreachable!()
};
*current_index = current_clause_index as i64;
}
ClauseProperties::TupleClause {
original_subject_name,
@ -921,14 +905,14 @@ impl<'a> CodeGenerator<'a> {
let prev_defined_tuple_indices = defined_tuple_indices.clone();
let subject_name = original_subject_name.clone();
self.when_ir(
self.when_pattern(
&clause.pattern,
&mut clause_subject_vec,
&mut clause_then_vec,
subject_type,
clause_properties,
scope.clone(),
);
let current_defined_tuple_indices = match clause_properties {
ClauseProperties::TupleClause {
defined_tuple_indices,
@ -958,78 +942,53 @@ impl<'a> CodeGenerator<'a> {
}
}
fn when_ir(
fn when_pattern(
&mut self,
pattern: &Pattern<PatternConstructor, Arc<Type>>,
pattern_vec: &mut Vec<Air>,
values: &mut Vec<Air>,
pattern_stack: &mut AirStack,
value_stack: AirStack,
tipo: &Type,
clause_properties: &mut ClauseProperties,
scope: Vec<u64>,
) {
match pattern {
Pattern::Int { value, .. } => {
pattern_vec.push(Air::Int {
scope,
value: value.clone(),
});
pattern_stack.integer(value.clone());
pattern_vec.append(values);
pattern_stack.merge_child(value_stack);
}
Pattern::Var { name, .. } => {
pattern_vec.push(Air::Void {
scope: scope.clone(),
});
pattern_vec.push(Air::Let {
scope: scope.clone(),
name: name.clone(),
});
pattern_stack.void();
pattern_vec.push(Air::Var {
scope,
constructor: ValueConstructor::public(
tipo.clone().into(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: clause_properties.original_subject_name().clone(),
variant_name: String::new(),
});
pattern_vec.append(values);
let mut var_stack = pattern_stack.empty_with_scope();
var_stack.local_var(
tipo.clone().into(),
clause_properties.original_subject_name(),
);
pattern_stack.let_assignment(name, var_stack);
pattern_stack.merge_child(value_stack);
}
Pattern::Assign { name, pattern, .. } => {
let mut new_vec = vec![];
new_vec.push(Air::Let {
scope: scope.clone(),
name: name.clone(),
});
new_vec.push(Air::Var {
scope: scope.clone(),
constructor: ValueConstructor::public(
tipo.clone().into(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: clause_properties.original_subject_name().clone(),
variant_name: String::new(),
});
let mut new_stack = pattern_stack.empty_with_scope();
new_vec.append(values);
self.when_ir(
pattern,
pattern_vec,
&mut new_vec,
tipo,
clause_properties,
scope,
new_stack.local_var(
tipo.clone().into(),
clause_properties.original_subject_name(),
);
let mut let_stack = pattern_stack.empty_with_scope();
let_stack.let_assignment(name.clone(), new_stack);
let_stack.merge_child(value_stack);
self.when_pattern(pattern, pattern_stack, let_stack, tipo, clause_properties);
}
Pattern::Discard { .. } => {
pattern_vec.push(Air::Void { scope });
pattern_vec.append(values);
pattern_stack.void();
pattern_stack.merge_child(value_stack);
}
Pattern::List { elements, tail, .. } => {
for element in elements {
@ -1039,20 +998,12 @@ impl<'a> CodeGenerator<'a> {
if let Some(tail) = tail {
builder::check_when_pattern_needs(tail, clause_properties);
}
*clause_properties.needs_constr_var() = false;
pattern_vec.push(Air::Void {
scope: scope.clone(),
});
pattern_stack.void();
self.when_recursive_ir(
pattern,
pattern_vec,
values,
clause_properties,
tipo,
scope,
);
self.expose_elements(pattern, pattern_stack, value_stack, clause_properties, tipo);
}
Pattern::Constructor {
arguments,
@ -1063,10 +1014,7 @@ impl<'a> CodeGenerator<'a> {
*temp_clause_properties.needs_constr_var() = false;
if tipo.is_bool() {
pattern_vec.push(Air::Bool {
scope,
value: constr_name == "True",
});
pattern_stack.bool(constr_name == "True");
} else {
for arg in arguments {
builder::check_when_pattern_needs(&arg.value, &mut temp_clause_properties);
@ -1083,48 +1031,39 @@ impl<'a> CodeGenerator<'a> {
.find(|(_, dt)| &dt.name == constr_name)
.unwrap();
let mut new_vec = vec![Air::Var {
constructor: ValueConstructor::public(
tipo.clone().into(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: temp_clause_properties.clause_var_name().clone(),
scope: scope.clone(),
variant_name: String::new(),
}];
let mut new_stack = pattern_stack.empty_with_scope();
new_stack.local_var(
tipo.clone().into(),
temp_clause_properties.clause_var_name(),
);
// if only one constructor, no need to check
if data_type.constructors.len() > 1 {
// push constructor Index
pattern_vec.push(Air::Int {
value: index.to_string(),
scope: scope.clone(),
});
pattern_stack.integer(index.to_string());
}
if *temp_clause_properties.needs_constr_var() {
self.when_recursive_ir(
self.expose_elements(
pattern,
pattern_vec,
&mut new_vec,
pattern_stack,
new_stack,
clause_properties,
tipo,
scope,
);
} else {
self.when_recursive_ir(
self.expose_elements(
pattern,
pattern_vec,
&mut vec![],
pattern_stack,
AirStack::new(&mut self.id_gen),
clause_properties,
tipo,
scope,
);
}
}
pattern_vec.append(values);
pattern_stack.merge_child(value_stack);
// unify clause properties
*clause_properties.is_complex_clause() = *clause_properties.is_complex_clause()
@ -1137,39 +1076,38 @@ impl<'a> CodeGenerator<'a> {
for elem in elems {
builder::check_when_pattern_needs(elem, clause_properties);
}
*clause_properties.needs_constr_var() = false;
self.when_recursive_ir(
self.expose_elements(
pattern,
pattern_vec,
&mut vec![],
pattern_stack,
AirStack::new(&mut self.id_gen),
clause_properties,
tipo,
scope,
);
pattern_vec.append(values);
pattern_stack.merge_child(value_stack);
}
}
}
fn when_recursive_ir(
fn expose_elements(
&mut self,
pattern: &Pattern<PatternConstructor, Arc<Type>>,
pattern_vec: &mut Vec<Air>,
values: &mut Vec<Air>,
pattern_stack: &mut AirStack,
value_stack: AirStack,
clause_properties: &mut ClauseProperties,
tipo: &Type,
scope: Vec<u64>,
) {
match pattern {
Pattern::Int { .. } => unreachable!(),
Pattern::Var { .. } => unreachable!(),
Pattern::Assign { .. } => todo!("Nested assign not yet implemented"),
Pattern::Discard { .. } => {
pattern_vec.push(Air::Void { scope });
pattern_stack.void();
pattern_vec.append(values);
pattern_stack.merge_child(value_stack);
}
Pattern::List { elements, tail, .. } => {
let mut names = vec![];
@ -1181,7 +1119,6 @@ impl<'a> CodeGenerator<'a> {
element,
&mut nested_pattern,
items_type,
scope.clone(),
*clause_properties.is_final_clause(),
);
@ -1231,14 +1168,14 @@ impl<'a> CodeGenerator<'a> {
Some((tail_var, tail_name))
};
pattern_vec.push(Air::ListExpose {
pattern_stack.push(Air::ListExpose {
scope,
tipo: tipo.clone().into(),
tail_head_names,
tail,
});
} else if !elements.is_empty() {
pattern_vec.push(Air::ListExpose {
pattern_stack.push(Air::ListExpose {
scope,
tipo: tipo.clone().into(),
tail_head_names,
@ -1246,8 +1183,8 @@ impl<'a> CodeGenerator<'a> {
});
}
pattern_vec.append(&mut nested_pattern);
pattern_vec.append(values);
pattern_stack.append(&mut nested_pattern);
pattern_stack.append(value_stack);
}
Pattern::Constructor {
is_record,
@ -1302,7 +1239,6 @@ impl<'a> CodeGenerator<'a> {
}
.into(),
),
scope.clone(),
*clause_properties.is_final_clause(),
);
@ -1315,7 +1251,7 @@ impl<'a> CodeGenerator<'a> {
.collect::<Vec<(String, String, usize)>>();
if !arguments_index.is_empty() {
pattern_vec.push(Air::FieldsExpose {
pattern_stack.push(Air::FieldsExpose {
indices: arguments_index
.iter()
.map(|(label, var_name, index)| {
@ -1346,7 +1282,6 @@ impl<'a> CodeGenerator<'a> {
&item.value,
&mut nested_pattern,
type_map.get(&index).unwrap(),
scope.clone(),
*clause_properties.is_final_clause(),
);
@ -1357,7 +1292,7 @@ impl<'a> CodeGenerator<'a> {
.collect::<Vec<(String, usize)>>();
if !arguments_index.is_empty() {
pattern_vec.push(Air::FieldsExpose {
pattern_stack.push(Air::FieldsExpose {
indices: arguments_index
.iter()
.map(|(name, index)| {
@ -1372,8 +1307,8 @@ impl<'a> CodeGenerator<'a> {
}
}
pattern_vec.append(values);
pattern_vec.append(&mut nested_pattern);
pattern_stack.append(value_stack);
pattern_stack.append(&mut nested_pattern);
}
Pattern::Tuple { elems, .. } => {
let mut names = vec![];
@ -1385,7 +1320,6 @@ impl<'a> CodeGenerator<'a> {
element,
&mut nested_pattern,
&items_type[index],
scope.clone(),
*clause_properties.is_final_clause(),
);
@ -1420,11 +1354,11 @@ impl<'a> CodeGenerator<'a> {
let pattern_type = &tipo.get_inner_types()[index];
pattern_vec.push(Air::Let {
pattern_stack.push(Air::Let {
scope: scope.clone(),
name: new_name.clone(),
});
pattern_vec.push(Air::Var {
pattern_stack.push(Air::Var {
scope: scope.clone(),
constructor: ValueConstructor::public(
pattern_type.clone(),
@ -1447,8 +1381,8 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(),
}
pattern_vec.append(&mut nested_pattern);
pattern_vec.append(values);
pattern_stack.append(&mut nested_pattern);
pattern_stack.append(value_stack);
}
}
}
@ -1458,7 +1392,6 @@ impl<'a> CodeGenerator<'a> {
pattern: &Pattern<PatternConstructor, Arc<Type>>,
pattern_vec: &mut Vec<Air>,
pattern_type: &Arc<Type>,
scope: Vec<u64>,
final_clause: bool,
) -> Option<String> {
match pattern {
@ -1507,7 +1440,7 @@ impl<'a> CodeGenerator<'a> {
inverse: true,
});
self.when_ir(
self.when_pattern(
a,
pattern_vec,
&mut vec![],
@ -1536,7 +1469,7 @@ impl<'a> CodeGenerator<'a> {
inverse: false,
});
self.when_ir(
self.when_pattern(
a,
pattern_vec,
&mut vec![],
@ -1595,7 +1528,7 @@ impl<'a> CodeGenerator<'a> {
final_clause,
};
self.when_ir(
self.when_pattern(
a,
pattern_vec,
&mut vec![],
@ -1620,7 +1553,7 @@ impl<'a> CodeGenerator<'a> {
let mut inner_pattern_vec = vec![];
self.when_ir(
self.when_pattern(
a,
&mut inner_pattern_vec,
&mut vec![],
@ -1656,7 +1589,6 @@ impl<'a> CodeGenerator<'a> {
pattern,
pattern_vec,
pattern_type,
scope.clone(),
final_clause,
);
@ -1960,7 +1892,7 @@ impl<'a> CodeGenerator<'a> {
.constructors
.iter()
.enumerate()
.find(|(_, constr)| &constr.name == constr_name)
.find(|(_, constr)| constr.name == constr_name)
.unwrap();
let constr_name = format!("__{}_{}", constr_name, self.id_gen.next());
@ -2721,7 +2653,7 @@ impl<'a> CodeGenerator<'a> {
.map(|scope| (func_key.clone(), scope.clone()))
})
.filter(|func| {
builder::get_common_ancestor(&func.1, &ir.scope()) == ir.scope()
func.1.common_ancestor(&ir.scope()) == ir.scope()
&& !self.defined_functions.contains_key(&func.0)
&& !self.zero_arg_functions.contains_key(&func.0)
&& !(*dependency_map.get(&func.0).unwrap())
@ -2780,7 +2712,7 @@ impl<'a> CodeGenerator<'a> {
&mut self,
ir_stack: &mut [Air],
func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>,
func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>,
func_index_map: &mut IndexMap<FunctionAccessKey, Scope>,
mut recursion_func_map: IndexMap<FunctionAccessKey, ()>,
in_zero_arg_func: bool,
) {
@ -2871,7 +2803,7 @@ impl<'a> CodeGenerator<'a> {
for item in inner_func_index_map {
if let Some(entry) = func_index_map.get_mut(&item.0) {
*entry = builder::get_common_ancestor(entry, &item.1);
*entry = entry.common_ancestor(&item.1);
} else {
func_index_map.insert(item.0, item.1);
}
@ -2884,10 +2816,10 @@ impl<'a> CodeGenerator<'a> {
&mut self,
ir_stack: &mut [Air],
func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>,
func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>,
func_index_map: &mut IndexMap<FunctionAccessKey, Scope>,
in_zero_arg_func: bool,
) {
let mut to_be_defined_map: IndexMap<FunctionAccessKey, Vec<u64>> = IndexMap::new();
let mut to_be_defined_map: IndexMap<FunctionAccessKey, Scope> = IndexMap::new();
for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() {
match ir {
Air::Var {
@ -2908,10 +2840,12 @@ impl<'a> CodeGenerator<'a> {
let function = *self.functions.get(&non_variant_function_key).unwrap();
let mut func_ir = vec![];
let mut func_ir = AirStack::new(&mut self.id_gen);
self.build(&function.body, &mut func_ir);
let func_ir = func_ir.air;
let param_types = constructor.tipo.arg_types().unwrap();
let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
@ -2955,13 +2889,13 @@ impl<'a> CodeGenerator<'a> {
};
if let Some(scope_prev) = to_be_defined_map.get(&function_key) {
let new_scope = builder::get_common_ancestor(scope, scope_prev);
let new_scope = scope.common_ancestor(scope_prev);
to_be_defined_map.insert(function_key, new_scope);
} else if func_components.get(&function_key).is_some() {
to_be_defined_map.insert(function_key.clone(), scope.to_vec());
to_be_defined_map.insert(function_key.clone(), scope.clone());
} else {
to_be_defined_map.insert(function_key.clone(), scope.to_vec());
to_be_defined_map.insert(function_key.clone(), scope.clone());
let mut func_calls = IndexMap::new();
for ir in func_ir.clone().into_iter() {
@ -3024,10 +2958,12 @@ impl<'a> CodeGenerator<'a> {
}
mono_types = map.into_iter().collect();
let mut func_ir = vec![];
let mut func_ir = AirStack::new(&mut self.id_gen);
self.build(&function.body, &mut func_ir);
let func_ir = func_ir.air;
let (variant_name, _) =
builder::monomorphize(func_ir, mono_types, &tipo);
@ -3078,17 +3014,15 @@ impl<'a> CodeGenerator<'a> {
}
} else {
for func in to_be_defined_map.clone().iter() {
if builder::get_common_ancestor(scope, func.1) == scope.to_vec() {
if scope.common_ancestor(func.1) == scope.clone() {
if let Some(index_scope) = func_index_map.get(func.0) {
if builder::get_common_ancestor(index_scope, func.1)
== scope.to_vec()
{
if index_scope.common_ancestor(func.1) == scope.clone() {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
} else {
to_be_defined_map.insert(
func.0.clone(),
builder::get_common_ancestor(index_scope, func.1),
index_scope.common_ancestor(func.1),
);
}
} else {
@ -3103,17 +3037,15 @@ impl<'a> CodeGenerator<'a> {
let scope = a.scope();
for func in to_be_defined_map.clone().iter() {
if builder::get_common_ancestor(&scope, func.1) == scope.to_vec() {
if scope.common_ancestor(func.1) == scope.clone() {
if let Some(index_scope) = func_index_map.get(func.0) {
if builder::get_common_ancestor(index_scope, func.1)
== scope.to_vec()
{
if index_scope.common_ancestor(func.1) == scope.clone() {
func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0);
} else {
to_be_defined_map.insert(
func.0.clone(),
builder::get_common_ancestor(index_scope, func.1),
index_scope.common_ancestor(func.1),
);
}
} else {
@ -3129,10 +3061,7 @@ impl<'a> CodeGenerator<'a> {
// Still to be defined
for func in to_be_defined_map.clone().iter() {
let index_scope = func_index_map.get(func.0).unwrap();
func_index_map.insert(
func.0.clone(),
builder::get_common_ancestor(func.1, index_scope),
);
func_index_map.insert(func.0.clone(), func.1.common_ancestor(index_scope));
}
}

View File

@ -19,7 +19,7 @@ use crate::{
TypedClause, TypedDataType, UnOp,
},
expr::TypedExpr,
tipo::{PatternConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant},
tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant},
};
use super::{air::Air, scope::Scope, stack::AirStack};
@ -1477,7 +1477,7 @@ pub fn handle_func_dependencies(
handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir);
let mut temp_ir = vec![Air::DefineFunc {
scope: func_scope.to_vec(),
scope: func_scope.clone(),
func_name: dependency.function_name.clone(),
module_name: dependency.module_name.clone(),
params: depend_comp.args.clone(),
@ -1667,105 +1667,93 @@ pub fn replace_opaque_type(t: &mut Arc<Type>, data_types: IndexMap<DataTypeKey,
pub fn handle_clause_guard(
clause_guard: &ClauseGuard<Arc<Type>>,
clause_guard_vec: &mut Vec<Air>,
scope: Vec<u64>,
clause_guard_stack: &mut AirStack,
) {
match clause_guard {
ClauseGuard::Not { value, .. } => {
clause_guard_vec.push(Air::UnOp {
scope: scope.clone(),
op: UnOp::Not,
});
let value_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(value, clause_guard_vec, scope);
handle_clause_guard(value, &mut value_stack);
clause_guard_stack.unop(UnOp::Not, value_stack);
}
ClauseGuard::Equals { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::Eq,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::Eq, left.tipo(), left_stack, right_stack);
}
ClauseGuard::NotEquals { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::NotEq,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::NotEq, left.tipo(), left_stack, right_stack);
}
ClauseGuard::GtInt { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::GtInt,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::GtInt, left.tipo(), left_stack, right_stack);
}
ClauseGuard::GtEqInt { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::GtEqInt,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::GtEqInt, left.tipo(), left_stack, right_stack);
}
ClauseGuard::LtInt { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::LtInt,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::LtInt, left.tipo(), left_stack, right_stack);
}
ClauseGuard::LtEqInt { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::LtEqInt,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::LtEqInt, left.tipo(), left_stack, right_stack);
}
ClauseGuard::Or { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::Or,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::Or, left.tipo(), left_stack, right_stack);
}
ClauseGuard::And { left, right, .. } => {
clause_guard_vec.push(Air::BinOp {
scope: scope.clone(),
name: BinOp::And,
tipo: left.tipo(),
});
handle_clause_guard(left, clause_guard_vec, scope.clone());
handle_clause_guard(right, clause_guard_vec, scope);
let left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack);
clause_guard_stack.binop(BinOp::And, left.tipo(), left_stack, right_stack);
}
ClauseGuard::Var { tipo, name, .. } => {
clause_guard_vec.push(Air::Var {
scope,
constructor: ValueConstructor::public(
tipo.clone(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: name.clone(),
variant_name: String::new(),
});
clause_guard_stack.local_var(tipo.clone(), name);
}
ClauseGuard::Constant(constant) => {
constants_ir(constant, clause_guard_vec);
constants_ir(constant, clause_guard_stack);
}
}
}

View File

@ -518,4 +518,23 @@ impl<'a> AirStack<'a> {
self.merge_child(tuple);
}
pub fn finally(&mut self, value: AirStack) {
self.new_scope();
self.air.push(Air::Finally {
scope: self.scope.clone(),
});
self.merge_child(value);
}
pub fn bool(&mut self, value: bool) {
self.new_scope();
self.air.push(Air::Bool {
scope: self.scope.clone(),
value,
});
}
}