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

View File

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