feat: refactor handle_each_clause
fix expect type ordering on constr type checking
This commit is contained in:
parent
f07a959ab8
commit
77afa76163
|
@ -712,56 +712,39 @@ impl<'a> CodeGenerator<'a> {
|
||||||
subject_type: &Arc<Type>,
|
subject_type: &Arc<Type>,
|
||||||
) {
|
) {
|
||||||
for (index, clause) in clauses.iter().enumerate() {
|
for (index, clause) in clauses.iter().enumerate() {
|
||||||
// scope per clause is different
|
|
||||||
let mut scope = scope.clone();
|
|
||||||
scope.push(self.id_gen.next());
|
|
||||||
|
|
||||||
// holds when clause pattern Air
|
// holds when clause pattern Air
|
||||||
let mut clause_subject_vec = vec![];
|
let mut clause_pattern_stack = ir_stack.empty_with_scope();
|
||||||
let mut clause_then_vec = vec![];
|
let mut clause_then_stack = ir_stack.empty_with_scope();
|
||||||
|
|
||||||
// reset complex clause setting per clause back to default
|
// reset complex clause setting per clause back to default
|
||||||
*clause_properties.is_complex_clause() = false;
|
*clause_properties.is_complex_clause() = false;
|
||||||
|
|
||||||
let mut clause_scope = scope.clone();
|
self.build(&clause.then, &mut clause_then_stack);
|
||||||
clause_scope.push(self.id_gen.next());
|
|
||||||
|
|
||||||
self.build(&clause.then, &mut clause_then_vec);
|
|
||||||
|
|
||||||
if let Some(clause_guard) = &clause.guard {
|
if let Some(clause_guard) = &clause.guard {
|
||||||
let mut clause_guard_vec = vec![];
|
let mut clause_guard_stack = ir_stack.empty_with_scope();
|
||||||
|
let mut clause_guard_condition = ir_stack.empty_with_scope();
|
||||||
|
|
||||||
*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();
|
builder::handle_clause_guard(clause_guard, &mut clause_guard_condition);
|
||||||
clause_guard_scope.push(self.id_gen.next());
|
|
||||||
|
|
||||||
clause_guard_vec.push(Air::Let {
|
clause_guard_stack.let_assignment(clause_guard_name, clause_guard_condition);
|
||||||
scope: clause_guard_scope.clone(),
|
|
||||||
name: clause_guard_name.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
builder::handle_clause_guard(
|
let condition_stack = ir_stack.empty_with_scope();
|
||||||
clause_guard,
|
|
||||||
&mut clause_guard_vec,
|
condition_stack.bool(true);
|
||||||
clause_guard_scope.clone(),
|
|
||||||
|
clause_guard_stack.clause_guard(
|
||||||
|
clause_guard_name,
|
||||||
|
bool(),
|
||||||
|
condition_stack,
|
||||||
|
clause_then_stack,
|
||||||
);
|
);
|
||||||
|
|
||||||
clause_guard_vec.push(Air::ClauseGuard {
|
clause_then_stack = clause_guard_stack;
|
||||||
scope: clause_guard_scope.clone(),
|
|
||||||
subject_name: clause_guard_name,
|
|
||||||
tipo: bool(),
|
|
||||||
});
|
|
||||||
|
|
||||||
clause_guard_vec.push(Air::Bool {
|
|
||||||
scope: clause_guard_scope.clone(),
|
|
||||||
value: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
clause_guard_vec.append(&mut clause_then_vec);
|
|
||||||
clause_then_vec = clause_guard_vec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match clause_properties {
|
match clause_properties {
|
||||||
|
@ -771,13 +754,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} => {
|
} => {
|
||||||
let subject_name = original_subject_name.clone();
|
let subject_name = original_subject_name.clone();
|
||||||
|
|
||||||
let mut clause_scope = scope.clone();
|
|
||||||
clause_scope.push(self.id_gen.next());
|
|
||||||
|
|
||||||
self.when_pattern(
|
self.when_pattern(
|
||||||
&clause.pattern,
|
&clause.pattern,
|
||||||
&mut clause_subject_vec,
|
&mut clause_pattern_stack,
|
||||||
&mut clause_then_vec,
|
clause_then_stack,
|
||||||
subject_type,
|
subject_type,
|
||||||
clause_properties,
|
clause_properties,
|
||||||
);
|
);
|
||||||
|
@ -787,35 +767,33 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
if let Some(data_type) = data_type {
|
if let Some(data_type) = data_type {
|
||||||
if data_type.constructors.len() > 1 {
|
if data_type.constructors.len() > 1 {
|
||||||
ir_stack.push(Air::Clause {
|
ir_stack.clause(
|
||||||
scope,
|
subject_type.clone(),
|
||||||
tipo: subject_type.clone(),
|
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
|
||||||
subject_name,
|
subject_name,
|
||||||
});
|
*clause_properties.is_complex_clause(),
|
||||||
|
clause_pattern_stack,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
ir_stack.push(Air::Clause {
|
let condition_stack = ir_stack.empty_with_scope();
|
||||||
scope: scope.clone(),
|
|
||||||
tipo: subject_type.clone(),
|
condition_stack.integer(0.to_string());
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
|
||||||
|
condition_stack.merge_child(clause_pattern_stack);
|
||||||
|
|
||||||
|
ir_stack.clause(
|
||||||
|
subject_type.clone(),
|
||||||
subject_name,
|
subject_name,
|
||||||
});
|
*clause_properties.is_complex_clause(),
|
||||||
|
condition_stack,
|
||||||
let mut scope = scope;
|
);
|
||||||
scope.push(self.id_gen.next());
|
|
||||||
|
|
||||||
ir_stack.push(Air::Int {
|
|
||||||
scope,
|
|
||||||
value: "0".to_string(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ir_stack.push(Air::Clause {
|
ir_stack.clause(
|
||||||
scope: scope.clone(),
|
subject_type.clone(),
|
||||||
tipo: subject_type.clone(),
|
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
|
||||||
subject_name,
|
subject_name,
|
||||||
});
|
*clause_properties.is_complex_clause(),
|
||||||
|
clause_pattern_stack,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClauseProperties::ListClause {
|
ClauseProperties::ListClause {
|
||||||
|
@ -846,8 +824,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.when_pattern(
|
self.when_pattern(
|
||||||
&clause.pattern,
|
&clause.pattern,
|
||||||
&mut clause_subject_vec,
|
&mut clause_pattern_stack,
|
||||||
&mut clause_then_vec,
|
clause_then_stack,
|
||||||
subject_type,
|
subject_type,
|
||||||
clause_properties,
|
clause_properties,
|
||||||
);
|
);
|
||||||
|
@ -861,11 +839,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
elements.len()
|
elements.len()
|
||||||
} else if let Pattern::Assign { pattern, .. } = &clauses[index + 1].pattern
|
} else if let Pattern::Assign { pattern, .. } = &clauses[index + 1].pattern
|
||||||
{
|
{
|
||||||
if let Pattern::List { elements, .. } = pattern.as_ref() {
|
let Pattern::List { elements, .. } = pattern.as_ref() else {
|
||||||
elements.len()
|
|
||||||
} else {
|
|
||||||
unreachable!("{:#?}", pattern)
|
unreachable!("{:#?}", pattern)
|
||||||
}
|
};
|
||||||
|
elements.len()
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
@ -880,15 +857,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let minus_tail = has_tail as i64;
|
let minus_tail = has_tail as i64;
|
||||||
|
|
||||||
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.wrap_clause();
|
||||||
} else {
|
} else {
|
||||||
ir_stack.push(Air::ListClause {
|
ir_stack.list_clause(
|
||||||
scope,
|
subject_type.clone(),
|
||||||
tipo: subject_type.clone(),
|
subject_name,
|
||||||
tail_name: subject_name,
|
next_tail,
|
||||||
next_tail_name: next_tail,
|
*clause_properties.is_complex_clause(),
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
clause_pattern_stack,
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ClauseProperties::ListClause { current_index, .. } = clause_properties else {
|
let ClauseProperties::ListClause { current_index, .. } = clause_properties else {
|
||||||
|
@ -907,8 +884,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.when_pattern(
|
self.when_pattern(
|
||||||
&clause.pattern,
|
&clause.pattern,
|
||||||
&mut clause_subject_vec,
|
&mut clause_pattern_stack,
|
||||||
&mut clause_then_vec,
|
clause_then_stack,
|
||||||
subject_type,
|
subject_type,
|
||||||
clause_properties,
|
clause_properties,
|
||||||
);
|
);
|
||||||
|
@ -926,19 +903,16 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
ir_stack.push(Air::TupleClause {
|
ir_stack.tuple_clause(
|
||||||
scope,
|
subject_type.clone(),
|
||||||
tipo: subject_type.clone(),
|
|
||||||
indices: indices_to_define,
|
|
||||||
predefined_indices: prev_defined_tuple_indices,
|
|
||||||
subject_name,
|
subject_name,
|
||||||
count: subject_type.get_inner_types().len(),
|
indices_to_define,
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
prev_defined_tuple_indices,
|
||||||
});
|
*clause_properties.is_complex_clause(),
|
||||||
|
clause_pattern_stack,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_stack.append(&mut clause_subject_vec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2358,25 +2332,27 @@ impl<'a> CodeGenerator<'a> {
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
for (index, name, tipo) in arg_indices {
|
|
||||||
self.expect_type(&tipo, &mut arg_stack, &name);
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_stack = if !arg_indices.is_empty() {
|
arg_stack = if !arg_indices.is_empty() {
|
||||||
arg_stack.local_var(tipo, name);
|
arg_stack.local_var(tipo, name);
|
||||||
|
|
||||||
let field_expose_stack = expect_stack.empty_with_scope();
|
let field_expose_stack = expect_stack.empty_with_scope();
|
||||||
|
field_expose_stack.integer(index.to_string());
|
||||||
|
|
||||||
field_expose_stack.fields_expose(arg_indices.clone(), true, arg_stack);
|
field_expose_stack.fields_expose(arg_indices.clone(), true, arg_stack);
|
||||||
|
|
||||||
field_expose_stack
|
field_expose_stack
|
||||||
} else {
|
} else {
|
||||||
|
arg_stack.integer(index.to_string());
|
||||||
arg_stack
|
arg_stack
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (index, name, tipo) in arg_indices {
|
||||||
|
self.expect_type(&tipo, &mut arg_stack, &name);
|
||||||
|
}
|
||||||
|
|
||||||
arg_stack.void();
|
arg_stack.void();
|
||||||
|
|
||||||
clause_stack.clause(tipo, format!("__subject_{new_id}"), index, false, arg_stack);
|
clause_stack.clause(tipo, format!("__subject_{new_id}"), false, arg_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_stack.trace(tipo.clone());
|
trace_stack.trace(tipo.clone());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use indexmap::IndexSet;
|
||||||
use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction};
|
use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -341,7 +342,6 @@ impl<'a> AirStack<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
subject_name: impl ToString,
|
subject_name: impl ToString,
|
||||||
tag: usize,
|
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
body: AirStack,
|
body: AirStack,
|
||||||
) {
|
) {
|
||||||
|
@ -354,11 +354,62 @@ impl<'a> AirStack<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.integer(tag.to_string());
|
self.merge_child(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_clause(
|
||||||
|
&mut self,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tail_name: impl ToString,
|
||||||
|
next_tail_name: Option<String>,
|
||||||
|
complex_clause: bool,
|
||||||
|
body: AirStack,
|
||||||
|
) {
|
||||||
|
self.new_scope();
|
||||||
|
|
||||||
|
self.air.push(Air::ListClause {
|
||||||
|
scope: self.scope.clone(),
|
||||||
|
tail_name: tail_name.to_string(),
|
||||||
|
next_tail_name,
|
||||||
|
complex_clause,
|
||||||
|
tipo,
|
||||||
|
});
|
||||||
|
|
||||||
self.merge_child(body);
|
self.merge_child(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tuple_clause(
|
||||||
|
&mut self,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
subject_name: impl ToString,
|
||||||
|
indices: IndexSet<(usize, String)>,
|
||||||
|
predefined_indices: IndexSet<(usize, String)>,
|
||||||
|
complex_clause: bool,
|
||||||
|
body: AirStack,
|
||||||
|
) {
|
||||||
|
self.new_scope();
|
||||||
|
|
||||||
|
self.air.push(Air::TupleClause {
|
||||||
|
scope: self.scope.clone(),
|
||||||
|
subject_name: subject_name.to_string(),
|
||||||
|
indices,
|
||||||
|
predefined_indices,
|
||||||
|
complex_clause,
|
||||||
|
tipo,
|
||||||
|
count: tipo.get_inner_types().len(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.merge_child(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wrap_clause(&mut self) {
|
||||||
|
self.new_scope();
|
||||||
|
|
||||||
|
self.air.push(Air::WrapClause {
|
||||||
|
scope: self.scope.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn trace(&mut self, tipo: Arc<Type>) {
|
pub fn trace(&mut self, tipo: Arc<Type>) {
|
||||||
self.new_scope();
|
self.new_scope();
|
||||||
|
|
||||||
|
@ -537,4 +588,24 @@ impl<'a> AirStack<'a> {
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn clause_guard(
|
||||||
|
&self,
|
||||||
|
subject_name: impl ToString,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
condition_stack: AirStack,
|
||||||
|
clause_then_stack: AirStack,
|
||||||
|
) {
|
||||||
|
self.new_scope();
|
||||||
|
|
||||||
|
self.air.push(Air::ClauseGuard {
|
||||||
|
scope: self.scope.clone(),
|
||||||
|
subject_name: subject_name.to_string(),
|
||||||
|
tipo,
|
||||||
|
});
|
||||||
|
|
||||||
|
self.merge_child(condition_stack);
|
||||||
|
|
||||||
|
self.merge_child(clause_then_stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue