feat: all compiler errors fixed

Co-authored-by: Lucas Rosa <x@rvcas.dev>
This commit is contained in:
Kasey White 2023-03-24 22:54:56 -04:00 committed by Lucas
parent 25ff8acb1e
commit eef34b8f4b
4 changed files with 153 additions and 132 deletions

View File

@ -1,4 +1,4 @@
use std::sync::Arc; use std::{rc::Rc, sync::Arc};
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use itertools::Itertools; use itertools::Itertools;
@ -13,7 +13,7 @@ use uplc::{
use crate::{ use crate::{
ast::{ ast::{
ArgName, AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction, ArgName, AssignmentKind, BinOp, Pattern, TypedClause, TypedDataType, TypedFunction,
TypedValidator, UnOp, TypedValidator, UnOp,
}, },
builtins::bool, builtins::bool,
@ -43,7 +43,7 @@ pub struct CodeGenerator<'a> {
functions: IndexMap<FunctionAccessKey, &'a TypedFunction>, functions: IndexMap<FunctionAccessKey, &'a TypedFunction>,
data_types: IndexMap<DataTypeKey, &'a TypedDataType>, data_types: IndexMap<DataTypeKey, &'a TypedDataType>,
module_types: IndexMap<&'a String, &'a TypeInfo>, module_types: IndexMap<&'a String, &'a TypeInfo>,
id_gen: IdGenerator, id_gen: Rc<IdGenerator>,
needs_field_access: bool, needs_field_access: bool,
used_data_assert_on_list: bool, used_data_assert_on_list: bool,
zero_arg_functions: IndexMap<FunctionAccessKey, Vec<Air>>, zero_arg_functions: IndexMap<FunctionAccessKey, Vec<Air>>,
@ -60,7 +60,7 @@ impl<'a> CodeGenerator<'a> {
functions, functions,
data_types, data_types,
module_types, module_types,
id_gen: IdGenerator::new(), id_gen: IdGenerator::new().into(),
needs_field_access: false, needs_field_access: false,
used_data_assert_on_list: false, used_data_assert_on_list: false,
zero_arg_functions: IndexMap::new(), zero_arg_functions: IndexMap::new(),
@ -71,7 +71,7 @@ impl<'a> CodeGenerator<'a> {
self.needs_field_access = false; self.needs_field_access = false;
self.used_data_assert_on_list = false; self.used_data_assert_on_list = false;
self.zero_arg_functions = IndexMap::new(); self.zero_arg_functions = IndexMap::new();
self.id_gen = IdGenerator::new(); self.id_gen = IdGenerator::new().into();
self.defined_functions = IndexMap::new(); self.defined_functions = IndexMap::new();
} }
@ -84,7 +84,7 @@ impl<'a> CodeGenerator<'a> {
.. ..
}: &TypedValidator, }: &TypedValidator,
) -> Program<Name> { ) -> Program<Name> {
let mut ir_stack = AirStack::new(&mut self.id_gen); let mut ir_stack = AirStack::new(self.id_gen.clone());
self.build(&fun.body, &mut ir_stack); self.build(&fun.body, &mut ir_stack);
@ -104,7 +104,7 @@ impl<'a> CodeGenerator<'a> {
if let Some(other) = other_fun { if let Some(other) = other_fun {
self.reset(); self.reset();
let mut other_ir_stack = AirStack::new(&mut self.id_gen); let mut other_ir_stack = AirStack::new(self.id_gen.clone());
self.build(&other.body, &mut other_ir_stack); self.build(&other.body, &mut other_ir_stack);
@ -136,7 +136,7 @@ impl<'a> CodeGenerator<'a> {
} }
pub fn generate_test(&mut self, test_body: &TypedExpr) -> Program<Name> { pub fn generate_test(&mut self, test_body: &TypedExpr) -> Program<Name> {
let mut ir_stack = AirStack::new(&mut self.id_gen); let mut ir_stack = AirStack::new(self.id_gen.clone());
self.build(test_body, &mut ir_stack); self.build(test_body, &mut ir_stack);
@ -225,7 +225,7 @@ impl<'a> CodeGenerator<'a> {
self.build(body, &mut body_stack); self.build(body, &mut body_stack);
let mut params = args let params = args
.iter() .iter()
.map(|arg| arg.arg_name.get_variable_name().unwrap_or("_").to_string()) .map(|arg| arg.arg_name.get_variable_name().unwrap_or("_").to_string())
.collect(); .collect();
@ -238,7 +238,7 @@ impl<'a> CodeGenerator<'a> {
tipo, tipo,
.. ..
} => { } => {
let stacks = Vec::new(); let mut stacks = Vec::new();
for element in elements { for element in elements {
let mut stack = ir_stack.empty_with_scope(); let mut stack = ir_stack.empty_with_scope();
@ -279,7 +279,7 @@ impl<'a> CodeGenerator<'a> {
unreachable!() unreachable!()
}; };
let stacks = Vec::new(); let mut stacks = Vec::new();
for (arg, func_type) in args.iter().zip(fun_arg_types) { for (arg, func_type) in args.iter().zip(fun_arg_types) {
let mut stack = ir_stack.empty_with_scope(); let mut stack = ir_stack.empty_with_scope();
@ -354,6 +354,8 @@ impl<'a> CodeGenerator<'a> {
} }
self.build(&arg.value, &mut stack); self.build(&arg.value, &mut stack);
stacks.push(stack);
} }
ir_stack.record(tipo.clone(), constr_index, stacks); ir_stack.record(tipo.clone(), constr_index, stacks);
@ -379,6 +381,8 @@ impl<'a> CodeGenerator<'a> {
} }
self.build(&arg.value, &mut stack); self.build(&arg.value, &mut stack);
stacks.push(stack);
} }
ir_stack.builtin(*func, tipo.clone(), stacks); ir_stack.builtin(*func, tipo.clone(), stacks);
@ -406,6 +410,8 @@ impl<'a> CodeGenerator<'a> {
} }
self.build(&arg.value, &mut stack); self.build(&arg.value, &mut stack);
stacks.push(stack);
} }
ir_stack.call(tipo.clone(), fun_stack, stacks); ir_stack.call(tipo.clone(), fun_stack, stacks);
@ -567,7 +573,7 @@ impl<'a> CodeGenerator<'a> {
tipo, tipo,
.. ..
} => { } => {
for (index, branch) in branches.iter().enumerate() { for branch in branches.iter() {
let mut condition_stack = ir_stack.empty_with_scope(); let mut condition_stack = ir_stack.empty_with_scope();
let mut branch_body_stack = ir_stack.empty_with_scope(); let mut branch_body_stack = ir_stack.empty_with_scope();
@ -612,7 +618,7 @@ impl<'a> CodeGenerator<'a> {
variant_name: String::new(), variant_name: String::new(),
}); });
if let Some(func) = func { if let Some(_func) = func {
ir_stack.local_var(tipo.clone(), format!("{module}_{name}")); ir_stack.local_var(tipo.clone(), format!("{module}_{name}"));
} else { } else {
let type_info = self.module_types.get(module_name).unwrap(); let type_info = self.module_types.get(module_name).unwrap();
@ -731,9 +737,10 @@ impl<'a> CodeGenerator<'a> {
builder::handle_clause_guard(clause_guard, &mut clause_guard_condition); builder::handle_clause_guard(clause_guard, &mut clause_guard_condition);
clause_guard_stack.let_assignment(clause_guard_name, clause_guard_condition); clause_guard_stack
.let_assignment(clause_guard_name.clone(), clause_guard_condition);
let condition_stack = ir_stack.empty_with_scope(); let mut condition_stack = ir_stack.empty_with_scope();
condition_stack.bool(true); condition_stack.bool(true);
@ -774,7 +781,7 @@ impl<'a> CodeGenerator<'a> {
clause_pattern_stack, clause_pattern_stack,
); );
} else { } else {
let condition_stack = ir_stack.empty_with_scope(); let mut condition_stack = ir_stack.empty_with_scope();
condition_stack.integer(0.to_string()); condition_stack.integer(0.to_string());
@ -1027,10 +1034,12 @@ impl<'a> CodeGenerator<'a> {
tipo, tipo,
); );
} else { } else {
let value_stack = pattern_stack.empty_with_scope();
self.expose_elements( self.expose_elements(
pattern, pattern,
pattern_stack, pattern_stack,
AirStack::new(&mut self.id_gen), value_stack,
clause_properties, clause_properties,
tipo, tipo,
); );
@ -1053,13 +1062,9 @@ impl<'a> CodeGenerator<'a> {
*clause_properties.needs_constr_var() = false; *clause_properties.needs_constr_var() = false;
self.expose_elements( let temp = pattern_stack.empty_with_scope();
pattern,
pattern_stack, self.expose_elements(pattern, pattern_stack, temp, clause_properties, tipo);
AirStack::new(&mut self.id_gen),
clause_properties,
tipo,
);
pattern_stack.merge_child(value_stack); pattern_stack.merge_child(value_stack);
} }
@ -1313,7 +1318,7 @@ impl<'a> CodeGenerator<'a> {
} }
for (index, name) in previous_defined_names { for (index, name) in previous_defined_names {
let var_stack = pattern_stack.empty_with_scope(); let mut var_stack = pattern_stack.empty_with_scope();
let new_name = names let new_name = names
.iter() .iter()
@ -1359,13 +1364,13 @@ impl<'a> CodeGenerator<'a> {
let new_tail_name = "__tail".to_string(); let new_tail_name = "__tail".to_string();
if elements.is_empty() { if elements.is_empty() {
let void_stack = pattern_stack.empty_with_scope(); let mut void_stack = pattern_stack.empty_with_scope();
void_stack.void(); void_stack.void();
pattern_stack.list_clause_guard( pattern_stack.list_clause_guard(
pattern_type.clone().into(), pattern_type.clone().into(),
item_name, item_name.clone(),
None, None,
false, false,
void_stack, void_stack,
@ -1391,7 +1396,7 @@ impl<'a> CodeGenerator<'a> {
if elements.len() - 1 == index { if elements.len() - 1 == index {
if tail.is_some() { if tail.is_some() {
let elements_stack = pattern_stack.empty_with_scope(); let mut elements_stack = pattern_stack.empty_with_scope();
self.when_pattern( self.when_pattern(
pattern, pattern,
@ -1409,9 +1414,9 @@ impl<'a> CodeGenerator<'a> {
elements_stack, elements_stack,
); );
} else { } else {
let elements_stack = pattern_stack.empty_with_scope(); let mut elements_stack = pattern_stack.empty_with_scope();
let void_stack = pattern_stack.empty_with_scope(); let mut void_stack = pattern_stack.empty_with_scope();
void_stack.void(); void_stack.void();
@ -1440,7 +1445,7 @@ impl<'a> CodeGenerator<'a> {
); );
} }
} else { } else {
let void_stack = pattern_stack.empty_with_scope(); let mut void_stack = pattern_stack.empty_with_scope();
void_stack.void(); void_stack.void();
@ -1457,7 +1462,7 @@ impl<'a> CodeGenerator<'a> {
Some(item_name) Some(item_name)
} }
a @ Pattern::Constructor { pattern @ Pattern::Constructor {
tipo, tipo,
name: constr_name, name: constr_name,
.. ..
@ -1467,19 +1472,7 @@ impl<'a> CodeGenerator<'a> {
let data_type = let data_type =
builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
if data_type.constructors.len() > 1 { let mut when_stack = pattern_stack.empty_with_scope();
if final_clause {
pattern_stack.push(Air::Finally {
scope: scope.clone(),
});
} else {
pattern_stack.push(Air::ClauseGuard {
scope: scope.clone(),
tipo: tipo.clone(),
subject_name: constr_var_name.clone(),
});
}
}
let mut clause_properties = ClauseProperties::ConstrClause { let mut clause_properties = ClauseProperties::ConstrClause {
clause_var_name: constr_var_name.clone(), clause_var_name: constr_var_name.clone(),
@ -1489,11 +1482,31 @@ impl<'a> CodeGenerator<'a> {
final_clause, final_clause,
}; };
self.when_pattern(a, pattern_stack, &mut vec![], tipo, &mut clause_properties); self.when_pattern(
pattern,
&mut when_stack,
pattern_stack.empty_with_scope(),
tipo,
&mut clause_properties,
);
if data_type.constructors.len() > 1 {
if final_clause {
pattern_stack.finally(when_stack);
} else {
let empty_stack = pattern_stack.empty_with_scope();
pattern_stack.clause_guard(
constr_var_name.clone(),
tipo.clone(),
when_stack,
empty_stack,
);
}
}
Some(constr_var_name) Some(constr_var_name)
} }
a @ Pattern::Tuple { elems, .. } => { a @ Pattern::Tuple { .. } => {
let item_name = format!("__tuple_item_id_{}", self.id_gen.next()); let item_name = format!("__tuple_item_id_{}", self.id_gen.next());
let mut clause_properties = ClauseProperties::TupleClause { let mut clause_properties = ClauseProperties::TupleClause {
@ -1505,12 +1518,12 @@ impl<'a> CodeGenerator<'a> {
final_clause, final_clause,
}; };
let mut inner_pattern_vec = vec![]; let mut inner_pattern_stack = pattern_stack.empty_with_scope();
self.when_pattern( self.when_pattern(
a, a,
&mut inner_pattern_vec, &mut inner_pattern_stack,
&mut vec![], pattern_stack.empty_with_scope(),
pattern_type, pattern_type,
&mut clause_properties, &mut clause_properties,
); );
@ -1523,17 +1536,14 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(), _ => unreachable!(),
}; };
pattern_stack.push(Air::TupleClause { pattern_stack.tuple_clause(
scope, pattern_type.clone().into(),
tipo: pattern_type.clone(), clause_properties.original_subject_name(),
indices: defined_indices, defined_indices,
predefined_indices: IndexSet::new(), IndexSet::new(),
subject_name: clause_properties.original_subject_name().to_string(), false,
count: elems.len(), inner_pattern_stack,
complex_clause: false, );
});
pattern_stack.append(&mut inner_pattern_vec);
Some(item_name) Some(item_name)
} }
@ -1545,22 +1555,10 @@ impl<'a> CodeGenerator<'a> {
final_clause, final_clause,
); );
pattern_stack.push(Air::Let { let mut var_stack = pattern_stack.empty_with_scope();
scope: scope.clone(), var_stack.local_var(pattern_type.clone().into(), inner_name.clone().unwrap());
name: name.clone(),
});
pattern_stack.push(Air::Var { pattern_stack.let_assignment(name, var_stack);
scope,
constructor: ValueConstructor::public(
pattern_type.clone(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: inner_name.clone().unwrap(),
variant_name: String::new(),
});
inner_name inner_name
} }
@ -1579,7 +1577,7 @@ impl<'a> CodeGenerator<'a> {
tipo: &Type, tipo: &Type,
assignment_properties: AssignmentProperties, assignment_properties: AssignmentProperties,
) { ) {
let value_stack = if assignment_properties.value_type.is_data() let mut value_stack = if assignment_properties.value_type.is_data()
&& !tipo.is_data() && !tipo.is_data()
&& !pattern.is_discard() && !pattern.is_discard()
{ {
@ -1893,13 +1891,18 @@ impl<'a> CodeGenerator<'a> {
.filter_map(|(tuple_index, item)| { .filter_map(|(tuple_index, item)| {
let mut nested_stack = pattern_stack.empty_with_scope(); let mut nested_stack = pattern_stack.empty_with_scope();
self.extract_arg_name( let name = self
.extract_arg_name(
item, item,
&mut nested_stack, &mut nested_stack,
type_map.get(&tuple_index).unwrap(), type_map.get(&tuple_index).unwrap(),
&assignment_properties, &assignment_properties,
) )
.map(|name| (name, tuple_index)) .map(|name| (name, tuple_index));
stacks.merge(nested_stack);
name
}) })
.sorted_by(|item1, item2| item1.1.cmp(&item2.1)) .sorted_by(|item1, item2| item1.1.cmp(&item2.1))
.collect::<Vec<(String, usize)>>(); .collect::<Vec<(String, usize)>>();
@ -1929,7 +1932,7 @@ impl<'a> CodeGenerator<'a> {
pattern_stack.let_assignment("_", value_stack); pattern_stack.let_assignment("_", value_stack);
} }
pattern_stack.merge_child(value_stack); pattern_stack.merge_child(stacks);
} }
} }
} }
@ -2000,7 +2003,7 @@ impl<'a> CodeGenerator<'a> {
format!("__tail_{}", self.id_gen.next()) format!("__tail_{}", self.id_gen.next())
}; };
self.expect_type(&inner_list_type, &mut tail_stack, &name); self.expect_type(inner_list_type, &mut tail_stack, &name);
names.push(name); names.push(name);
@ -2268,14 +2271,14 @@ impl<'a> CodeGenerator<'a> {
let mut local_var_stack = expect_stack.empty_with_scope(); let mut local_var_stack = expect_stack.empty_with_scope();
local_var_stack.local_var(tipo, name); local_var_stack.local_var(tipo.clone(), name);
let names = new_id_list let names = new_id_list
.iter() .iter()
.map(|(index, id)| format!("__tuple_index_{index}_{id}")) .map(|(index, id)| format!("__tuple_index_{index}_{id}"))
.collect(); .collect();
expect_stack.tuple_accessor(tipo, names, true, local_var_stack); expect_stack.tuple_accessor(tipo.clone(), names, true, local_var_stack);
for (index, name) in new_id_list for (index, name) in new_id_list
.into_iter() .into_iter()
@ -2290,7 +2293,7 @@ impl<'a> CodeGenerator<'a> {
let new_id = self.id_gen.next(); let new_id = self.id_gen.next();
// START HERE // START HERE
let mut arg_stack = expect_stack.empty_with_scope();
let mut clause_stack = expect_stack.empty_with_scope(); let mut clause_stack = expect_stack.empty_with_scope();
let mut when_stack = expect_stack.empty_with_scope(); let mut when_stack = expect_stack.empty_with_scope();
let mut trace_stack = expect_stack.empty_with_scope(); let mut trace_stack = expect_stack.empty_with_scope();
@ -2311,10 +2314,12 @@ impl<'a> CodeGenerator<'a> {
}) })
.collect_vec(); .collect_vec();
arg_stack = if !arg_indices.is_empty() { let mut arg_stack = expect_stack.empty_with_scope();
arg_stack.local_var(tipo, name);
let field_expose_stack = expect_stack.empty_with_scope(); let mut arg_stack = if !arg_indices.is_empty() {
arg_stack.local_var(tipo.clone(), name);
let mut field_expose_stack = expect_stack.empty_with_scope();
field_expose_stack.integer(index.to_string()); 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);
@ -2325,13 +2330,18 @@ impl<'a> CodeGenerator<'a> {
arg_stack arg_stack
}; };
for (index, name, tipo) in arg_indices { for (_index, name, tipo) in arg_indices {
self.expect_type(&tipo, &mut arg_stack, &name); self.expect_type(&tipo, &mut arg_stack, &name);
} }
arg_stack.void(); arg_stack.void();
clause_stack.clause(tipo, format!("__subject_{new_id}"), false, arg_stack); clause_stack.clause(
tipo.clone(),
format!("__subject_{new_id}"),
false,
arg_stack,
);
} }
trace_stack.trace(tipo.clone()); trace_stack.trace(tipo.clone());
@ -2340,10 +2350,10 @@ impl<'a> CodeGenerator<'a> {
trace_stack.error(tipo.clone()); trace_stack.error(tipo.clone());
subject_stack.local_var(tipo, name); subject_stack.local_var(tipo.clone(), name);
when_stack.when( when_stack.when(
tipo, tipo.clone(),
format!("__subject_{new_id}"), format!("__subject_{new_id}"),
subject_stack, subject_stack,
clause_stack, clause_stack,
@ -2371,7 +2381,7 @@ impl<'a> CodeGenerator<'a> {
let mut value_stack = nested_pattern_stack.empty_with_scope(); let mut value_stack = nested_pattern_stack.empty_with_scope();
value_stack.local_var(tipo.clone().into(), list_name); value_stack.local_var(tipo.clone().into(), list_name.clone());
if matches!(assignment_properties.kind, AssignmentKind::Expect) if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data() && assignment_properties.value_type.is_data()
@ -2406,7 +2416,7 @@ impl<'a> CodeGenerator<'a> {
let mut local_var_stack = nested_pattern_stack.empty_with_scope(); let mut local_var_stack = nested_pattern_stack.empty_with_scope();
local_var_stack.local_var(tipo.clone(), constr_name); local_var_stack.local_var(tipo.clone(), constr_name.clone());
if matches!(assignment_properties.kind, AssignmentKind::Expect) if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data() && assignment_properties.value_type.is_data()
@ -2437,7 +2447,7 @@ impl<'a> CodeGenerator<'a> {
let mut local_var_stack = nested_pattern_stack.empty_with_scope(); let mut local_var_stack = nested_pattern_stack.empty_with_scope();
local_var_stack.local_var(tipo.clone().into(), tuple_name); local_var_stack.local_var(tipo.clone().into(), tuple_name.clone());
if matches!(assignment_properties.kind, AssignmentKind::Expect) if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data() && assignment_properties.value_type.is_data()
@ -2795,7 +2805,7 @@ 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 = AirStack::new(&mut self.id_gen); let mut func_ir = AirStack::new(self.id_gen.clone());
self.build(&function.body, &mut func_ir); self.build(&function.body, &mut func_ir);
@ -2913,7 +2923,7 @@ impl<'a> CodeGenerator<'a> {
} }
mono_types = map.into_iter().collect(); mono_types = map.into_iter().collect();
let mut func_ir = AirStack::new(&mut self.id_gen); let mut func_ir = AirStack::new(self.id_gen.clone());
self.build(&function.body, &mut func_ir); self.build(&function.body, &mut func_ir);

View File

@ -1671,15 +1671,15 @@ pub fn handle_clause_guard(
) { ) {
match clause_guard { match clause_guard {
ClauseGuard::Not { value, .. } => { ClauseGuard::Not { value, .. } => {
let value_stack = clause_guard_stack.empty_with_scope(); let mut value_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(value, &mut value_stack); handle_clause_guard(value, &mut value_stack);
clause_guard_stack.unop(UnOp::Not, value_stack); clause_guard_stack.unop(UnOp::Not, value_stack);
} }
ClauseGuard::Equals { left, right, .. } => { ClauseGuard::Equals { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1687,8 +1687,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::Eq, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::Eq, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::NotEquals { left, right, .. } => { ClauseGuard::NotEquals { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1696,8 +1696,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::NotEq, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::NotEq, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::GtInt { left, right, .. } => { ClauseGuard::GtInt { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1705,8 +1705,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::GtInt, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::GtInt, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::GtEqInt { left, right, .. } => { ClauseGuard::GtEqInt { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1714,8 +1714,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::GtEqInt, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::GtEqInt, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::LtInt { left, right, .. } => { ClauseGuard::LtInt { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1723,8 +1723,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::LtInt, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::LtInt, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::LtEqInt { left, right, .. } => { ClauseGuard::LtEqInt { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1732,8 +1732,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::LtEqInt, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::LtEqInt, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::Or { left, right, .. } => { ClauseGuard::Or { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);
@ -1741,8 +1741,8 @@ pub fn handle_clause_guard(
clause_guard_stack.binop(BinOp::Or, left.tipo(), left_stack, right_stack); clause_guard_stack.binop(BinOp::Or, left.tipo(), left_stack, right_stack);
} }
ClauseGuard::And { left, right, .. } => { ClauseGuard::And { left, right, .. } => {
let left_stack = clause_guard_stack.empty_with_scope(); let mut left_stack = clause_guard_stack.empty_with_scope();
let right_stack = clause_guard_stack.empty_with_scope(); let mut right_stack = clause_guard_stack.empty_with_scope();
handle_clause_guard(left, &mut left_stack); handle_clause_guard(left, &mut left_stack);
handle_clause_guard(right, &mut right_stack); handle_clause_guard(right, &mut right_stack);

View File

@ -10,7 +10,14 @@ impl Scope {
self.0.is_empty() self.0.is_empty()
} }
pub fn replace(&mut self, pattern: &Scope, replacement: Scope) { pub fn replace(&mut self, pattern: &Scope, mut replacement: Scope) {
if pattern.is_empty() {
replacement.0.extend(self.0.iter());
self.0 = replacement.0;
return;
}
let mut result = Vec::new(); let mut result = Vec::new();
let mut index = 0; let mut index = 0;
@ -36,7 +43,7 @@ impl Scope {
} }
if no_matches { if no_matches {
replacement.0.extend(self.0); replacement.0.extend(self.0.iter());
self.0 = replacement.0; self.0 = replacement.0;
} else { } else {
self.0 = result; self.0 = result;

View File

@ -1,4 +1,4 @@
use std::sync::Arc; use std::{rc::Rc, sync::Arc};
use indexmap::IndexSet; use indexmap::IndexSet;
use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction}; use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction};
@ -12,15 +12,15 @@ use crate::{
use super::{air::Air, scope::Scope}; use super::{air::Air, scope::Scope};
/// A builder for [`Air`]. /// A builder for [`Air`].
pub struct AirStack<'a> { pub struct AirStack {
pub id_gen: &'a mut IdGenerator, pub id_gen: Rc<IdGenerator>,
pub scope: Scope, pub scope: Scope,
pub air: Vec<Air>, pub air: Vec<Air>,
} }
impl<'a> AirStack<'a> { impl AirStack {
/// Create a new [`AirStack`] with an [`IdGenerator`] /// Create a new [`AirStack`] with an [`IdGenerator`]
pub fn new(id_gen: &'a mut IdGenerator) -> Self { pub fn new(id_gen: Rc<IdGenerator>) -> Self {
AirStack { AirStack {
id_gen, id_gen,
scope: Scope::default(), scope: Scope::default(),
@ -29,7 +29,7 @@ impl<'a> AirStack<'a> {
} }
/// Create a new [`AirStack`] with an [`IdGenerator`] and [`Scope`]. /// Create a new [`AirStack`] with an [`IdGenerator`] and [`Scope`].
pub fn with_scope(id_gen: &'a mut IdGenerator, scope: Scope) -> Self { pub fn with_scope(id_gen: Rc<IdGenerator>, scope: Scope) -> Self {
AirStack { AirStack {
id_gen, id_gen,
scope, scope,
@ -39,7 +39,7 @@ impl<'a> AirStack<'a> {
/// Create a new empty [`AirStack`] with the current stack's scope. /// Create a new empty [`AirStack`] with the current stack's scope.
pub fn empty_with_scope(&mut self) -> Self { pub fn empty_with_scope(&mut self) -> Self {
AirStack::with_scope(&mut self.id_gen, self.scope.clone()) AirStack::with_scope(self.id_gen.clone(), self.scope.clone())
} }
/// Increment the [`Scope`] /// Increment the [`Scope`]
@ -266,7 +266,7 @@ impl<'a> AirStack<'a> {
self.air.push(Air::Call { self.air.push(Air::Call {
scope: self.scope.clone(), scope: self.scope.clone(),
count: 2, count: 2,
tipo, tipo: tipo.clone(),
}); });
self.local_var(tipo.clone(), EXPECT_ON_LIST); self.local_var(tipo.clone(), EXPECT_ON_LIST);
@ -389,6 +389,8 @@ impl<'a> AirStack<'a> {
) { ) {
self.new_scope(); self.new_scope();
let count = tipo.get_inner_types().len();
self.air.push(Air::TupleClause { self.air.push(Air::TupleClause {
scope: self.scope.clone(), scope: self.scope.clone(),
subject_name: subject_name.to_string(), subject_name: subject_name.to_string(),
@ -396,7 +398,7 @@ impl<'a> AirStack<'a> {
predefined_indices, predefined_indices,
complex_clause, complex_clause,
tipo, tipo,
count: tipo.get_inner_types().len(), count,
}); });
self.merge_child(body); self.merge_child(body);
@ -434,7 +436,7 @@ impl<'a> AirStack<'a> {
self.air.push(Air::Builtin { self.air.push(Air::Builtin {
scope: self.scope.clone(), scope: self.scope.clone(),
func: DefaultFunction::ChooseUnit, func: DefaultFunction::ChooseUnit,
tipo: tipo.clone(), tipo,
count: DefaultFunction::ChooseUnit.arity(), count: DefaultFunction::ChooseUnit.arity(),
}); });
@ -490,6 +492,8 @@ impl<'a> AirStack<'a> {
scope: self.scope.clone(), scope: self.scope.clone(),
constr_index: tag, constr_index: tag,
}); });
self.merge_child(value);
} }
pub fn expect_bool(&mut self, is_true: bool, value: AirStack) { pub fn expect_bool(&mut self, is_true: bool, value: AirStack) {
@ -590,7 +594,7 @@ impl<'a> AirStack<'a> {
} }
pub fn clause_guard( pub fn clause_guard(
&self, &mut self,
subject_name: impl ToString, subject_name: impl ToString,
tipo: Arc<Type>, tipo: Arc<Type>,
condition_stack: AirStack, condition_stack: AirStack,
@ -629,7 +633,7 @@ impl<'a> AirStack<'a> {
} }
pub fn list_clause_guard( pub fn list_clause_guard(
&self, &mut self,
tipo: Arc<Type>, tipo: Arc<Type>,
tail_name: impl ToString, tail_name: impl ToString,
next_tail_name: Option<String>, next_tail_name: Option<String>,