feat: almost done
Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
parent
709ee914ed
commit
f07a959ab8
|
@ -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),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue