From f07a959ab8c3749ee9de93960f06a5082fc50772 Mon Sep 17 00:00:00 2001 From: rvcas Date: Thu, 23 Mar 2023 23:06:02 -0400 Subject: [PATCH] feat: almost done Co-authored-by: Kasey White --- crates/aiken-lang/src/gen_uplc.rs | 413 +++++++++------------- crates/aiken-lang/src/gen_uplc/builder.rs | 142 ++++---- crates/aiken-lang/src/gen_uplc/stack.rs | 19 + 3 files changed, 255 insertions(+), 319 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 9d15eb51..aed1c743 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -35,7 +35,7 @@ use builder::{ AssignmentProperties, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey, }; -use self::stack::AirStack; +use self::{scope::Scope, stack::AirStack}; #[derive(Clone)] pub struct CodeGenerator<'a> { @@ -456,19 +456,20 @@ impl<'a> CodeGenerator<'a> { let constr_var = format!("__constr_name_{}", self.id_gen.next()); let subject_tipo = subject.tipo(); + if clauses.len() <= 1 { - let mut value_vec: Vec = vec![]; - let mut pattern_vec: Vec = vec![]; - let mut subject_vec: Vec = vec![]; + let mut value_stack = ir_stack.empty_with_scope(); + let mut pattern_stack = ir_stack.empty_with_scope(); + let mut subject_stack = ir_stack.empty_with_scope(); - self.build(&clauses[0].then, &mut value_vec); + self.build(&clauses[0].then, &mut value_stack); - self.build(subject, &mut subject_vec); + self.build(subject, &mut subject_stack); self.assignment( &clauses[0].pattern, - &mut pattern_vec, - &mut subject_vec, + &mut pattern_stack, + subject_stack, &subject_tipo, AssignmentProperties { value_type: clauses[0].then.tipo(), @@ -476,10 +477,10 @@ impl<'a> CodeGenerator<'a> { }, ); - ir_stack.append(&mut pattern_vec); - ir_stack.append(&mut value_vec); + pattern_stack.merge_child(value_stack); + ir_stack.merge_child(pattern_stack); } else { - // HERE TODO + // TODO: go over rearrange clauses let clauses = if subject_tipo.is_list() { builder::rearrange_clauses(clauses.clone()) } else { @@ -487,7 +488,7 @@ impl<'a> CodeGenerator<'a> { }; if let Some((last_clause, clauses)) = clauses.split_last() { - let mut pattern_vec = vec![]; + let mut pattern_stack = ir_stack.empty_with_scope(); let mut clause_properties = ClauseProperties::init( &subject_tipo, @@ -496,7 +497,7 @@ impl<'a> CodeGenerator<'a> { ); self.handle_each_clause( - &mut pattern_vec, + &mut pattern_stack, &mut clause_properties, clauses, &subject_tipo, @@ -504,75 +505,59 @@ impl<'a> CodeGenerator<'a> { let last_pattern = &last_clause.pattern; - let mut final_scope = scope.clone(); + let mut final_pattern_stack = ir_stack.empty_with_scope(); + let mut final_clause_stack = ir_stack.empty_with_scope(); + let mut finally_stack = ir_stack.empty_with_scope(); - final_scope.push(self.id_gen.next()); - - if !matches!(last_pattern, Pattern::Tuple { .. }) { - pattern_vec.push(Air::Finally { - scope: final_scope.clone(), - }); - } - - let mut final_clause_vec = vec![]; - - self.build(&last_clause.then, &mut final_clause_vec); + self.build(&last_clause.then, &mut final_clause_stack); *clause_properties.is_final_clause() = true; - self.when_ir( + self.when_pattern( last_pattern, - &mut pattern_vec, - &mut final_clause_vec, + &mut final_pattern_stack, + final_clause_stack, &subject_tipo, &mut clause_properties, - final_scope, ); - if *clause_properties.needs_constr_var() { - ir_stack.push(Air::Let { - scope: scope.clone(), - name: constr_var.clone(), - }); - let mut subject_scope = scope.clone(); - subject_scope.push(self.id_gen.next()); - - self.build(subject, ir_stack); - - let mut scope = scope; - scope.push(self.id_gen.next()); - - ir_stack.push(Air::When { - scope: scope.clone(), - subject_name, - tipo: subject_tipo.clone(), - }); - - ir_stack.push(Air::Var { - scope, - constructor: ValueConstructor::public( - subject_tipo, - ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - ), - name: constr_var, - variant_name: String::new(), - }) + if !matches!(last_pattern, Pattern::Tuple { .. }) { + finally_stack.finally(final_pattern_stack); } else { - ir_stack.push(Air::When { - scope: scope.clone(), - subject_name, - tipo: subject_tipo, - }); - - let mut scope = scope; - scope.push(self.id_gen.next()); - - self.build(subject, ir_stack); + finally_stack.merge(final_pattern_stack); } - ir_stack.append(&mut pattern_vec); + if *clause_properties.needs_constr_var() { + let mut subject_stack = ir_stack.empty_with_scope(); + + self.build(subject, &mut subject_stack); + + ir_stack.let_assignment(constr_var.clone(), subject_stack); + + let mut var_stack = ir_stack.empty_with_scope(); + + var_stack.local_var(subject_tipo.clone(), constr_var); + + ir_stack.when( + subject_tipo, + subject_name, + var_stack, + pattern_stack, + finally_stack, + ); + } else { + let mut subject_stack = ir_stack.empty_with_scope(); + + self.build(subject, &mut subject_stack); + + ir_stack.when( + subject_tipo, + subject_name, + subject_stack, + pattern_stack, + finally_stack, + ); + } } } } @@ -649,7 +634,6 @@ impl<'a> CodeGenerator<'a> { TypedExpr::RecordUpdate { spread, args, tipo, .. } => { - let mut update_ir = vec![]; let mut index_types = vec![]; let mut highest_index = 0; @@ -722,7 +706,7 @@ impl<'a> CodeGenerator<'a> { fn handle_each_clause( &mut self, - ir_stack: &mut Vec, + ir_stack: &mut AirStack, clause_properties: &mut ClauseProperties, clauses: &[TypedClause], subject_type: &Arc, @@ -746,7 +730,9 @@ impl<'a> CodeGenerator<'a> { if let Some(clause_guard) = &clause.guard { let mut clause_guard_vec = vec![]; + *clause_properties.is_complex_clause() = true; + let clause_guard_name = format!("__clause_guard_{}", self.id_gen.next()); let mut clause_guard_scope = scope.clone(); @@ -787,13 +773,13 @@ impl<'a> CodeGenerator<'a> { let mut clause_scope = scope.clone(); clause_scope.push(self.id_gen.next()); - self.when_ir( + + self.when_pattern( &clause.pattern, &mut clause_subject_vec, &mut clause_then_vec, subject_type, clause_properties, - clause_scope, ); let data_type = @@ -814,6 +800,7 @@ impl<'a> CodeGenerator<'a> { complex_clause: *clause_properties.is_complex_clause(), subject_name, }); + let mut scope = scope; scope.push(self.id_gen.next()); @@ -840,11 +827,11 @@ impl<'a> CodeGenerator<'a> { if let Pattern::List { elements, tail, .. } = &clause.pattern { (elements.len(), tail.is_some()) } else if let Pattern::Assign { pattern, .. } = &clause.pattern { - if let Pattern::List { elements, tail, .. } = pattern.as_ref() { - (elements.len(), tail.is_some()) - } else { + let Pattern::List { elements, tail, .. } = pattern.as_ref() else { unreachable!("{:#?}", pattern) - } + }; + + (elements.len(), tail.is_some()) } else { unreachable!("{:#?}", &clause.pattern) }; @@ -857,13 +844,12 @@ impl<'a> CodeGenerator<'a> { format!("__tail_{}", current_clause_index - 1) }; - self.when_ir( + self.when_pattern( &clause.pattern, &mut clause_subject_vec, &mut clause_then_vec, subject_type, clause_properties, - scope.clone(), ); let next_tail = if index == clauses.len() - 1 { @@ -891,8 +877,7 @@ impl<'a> CodeGenerator<'a> { } }; - #[allow(clippy::bool_to_int_with_if)] - let minus_tail = if has_tail { 1 } else { 0 }; + let minus_tail = has_tail as i64; if current_clause_index as i64 - minus_tail == prev_index { ir_stack.push(Air::WrapClause { scope }); @@ -906,12 +891,11 @@ impl<'a> CodeGenerator<'a> { }); } - match clause_properties { - ClauseProperties::ListClause { current_index, .. } => { - *current_index = current_clause_index as i64; - } - _ => unreachable!(), - } + let ClauseProperties::ListClause { current_index, .. } = clause_properties else { + unreachable!() + }; + + *current_index = current_clause_index as i64; } ClauseProperties::TupleClause { original_subject_name, @@ -921,14 +905,14 @@ impl<'a> CodeGenerator<'a> { let prev_defined_tuple_indices = defined_tuple_indices.clone(); let subject_name = original_subject_name.clone(); - self.when_ir( + self.when_pattern( &clause.pattern, &mut clause_subject_vec, &mut clause_then_vec, subject_type, clause_properties, - scope.clone(), ); + let current_defined_tuple_indices = match clause_properties { ClauseProperties::TupleClause { defined_tuple_indices, @@ -958,78 +942,53 @@ impl<'a> CodeGenerator<'a> { } } - fn when_ir( + fn when_pattern( &mut self, pattern: &Pattern>, - pattern_vec: &mut Vec, - values: &mut Vec, + pattern_stack: &mut AirStack, + value_stack: AirStack, tipo: &Type, clause_properties: &mut ClauseProperties, - scope: Vec, ) { match pattern { Pattern::Int { value, .. } => { - pattern_vec.push(Air::Int { - scope, - value: value.clone(), - }); + pattern_stack.integer(value.clone()); - pattern_vec.append(values); + pattern_stack.merge_child(value_stack); } Pattern::Var { name, .. } => { - pattern_vec.push(Air::Void { - scope: scope.clone(), - }); - pattern_vec.push(Air::Let { - scope: scope.clone(), - name: name.clone(), - }); + pattern_stack.void(); - pattern_vec.push(Air::Var { - scope, - constructor: ValueConstructor::public( - tipo.clone().into(), - ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - ), - name: clause_properties.original_subject_name().clone(), - variant_name: String::new(), - }); - pattern_vec.append(values); + let mut var_stack = pattern_stack.empty_with_scope(); + + var_stack.local_var( + tipo.clone().into(), + clause_properties.original_subject_name(), + ); + + pattern_stack.let_assignment(name, var_stack); + + pattern_stack.merge_child(value_stack); } Pattern::Assign { name, pattern, .. } => { - let mut new_vec = vec![]; - new_vec.push(Air::Let { - scope: scope.clone(), - name: name.clone(), - }); - new_vec.push(Air::Var { - scope: scope.clone(), - constructor: ValueConstructor::public( - tipo.clone().into(), - ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - ), - name: clause_properties.original_subject_name().clone(), - variant_name: String::new(), - }); + let mut new_stack = pattern_stack.empty_with_scope(); - new_vec.append(values); - - self.when_ir( - pattern, - pattern_vec, - &mut new_vec, - tipo, - clause_properties, - scope, + new_stack.local_var( + tipo.clone().into(), + clause_properties.original_subject_name(), ); + + let mut let_stack = pattern_stack.empty_with_scope(); + + let_stack.let_assignment(name.clone(), new_stack); + + let_stack.merge_child(value_stack); + + self.when_pattern(pattern, pattern_stack, let_stack, tipo, clause_properties); } Pattern::Discard { .. } => { - pattern_vec.push(Air::Void { scope }); - pattern_vec.append(values); + pattern_stack.void(); + pattern_stack.merge_child(value_stack); } Pattern::List { elements, tail, .. } => { for element in elements { @@ -1039,20 +998,12 @@ impl<'a> CodeGenerator<'a> { if let Some(tail) = tail { builder::check_when_pattern_needs(tail, clause_properties); } + *clause_properties.needs_constr_var() = false; - pattern_vec.push(Air::Void { - scope: scope.clone(), - }); + pattern_stack.void(); - self.when_recursive_ir( - pattern, - pattern_vec, - values, - clause_properties, - tipo, - scope, - ); + self.expose_elements(pattern, pattern_stack, value_stack, clause_properties, tipo); } Pattern::Constructor { arguments, @@ -1063,10 +1014,7 @@ impl<'a> CodeGenerator<'a> { *temp_clause_properties.needs_constr_var() = false; if tipo.is_bool() { - pattern_vec.push(Air::Bool { - scope, - value: constr_name == "True", - }); + pattern_stack.bool(constr_name == "True"); } else { for arg in arguments { builder::check_when_pattern_needs(&arg.value, &mut temp_clause_properties); @@ -1083,48 +1031,39 @@ impl<'a> CodeGenerator<'a> { .find(|(_, dt)| &dt.name == constr_name) .unwrap(); - let mut new_vec = vec![Air::Var { - constructor: ValueConstructor::public( - tipo.clone().into(), - ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - ), - name: temp_clause_properties.clause_var_name().clone(), - scope: scope.clone(), - variant_name: String::new(), - }]; + let mut new_stack = pattern_stack.empty_with_scope(); + + new_stack.local_var( + tipo.clone().into(), + temp_clause_properties.clause_var_name(), + ); // if only one constructor, no need to check if data_type.constructors.len() > 1 { // push constructor Index - pattern_vec.push(Air::Int { - value: index.to_string(), - scope: scope.clone(), - }); + pattern_stack.integer(index.to_string()); } if *temp_clause_properties.needs_constr_var() { - self.when_recursive_ir( + self.expose_elements( pattern, - pattern_vec, - &mut new_vec, + pattern_stack, + new_stack, clause_properties, tipo, - scope, ); } else { - self.when_recursive_ir( + self.expose_elements( pattern, - pattern_vec, - &mut vec![], + pattern_stack, + AirStack::new(&mut self.id_gen), clause_properties, tipo, - scope, ); } } - pattern_vec.append(values); + + pattern_stack.merge_child(value_stack); // unify clause properties *clause_properties.is_complex_clause() = *clause_properties.is_complex_clause() @@ -1137,39 +1076,38 @@ impl<'a> CodeGenerator<'a> { for elem in elems { builder::check_when_pattern_needs(elem, clause_properties); } + *clause_properties.needs_constr_var() = false; - self.when_recursive_ir( + self.expose_elements( pattern, - pattern_vec, - &mut vec![], + pattern_stack, + AirStack::new(&mut self.id_gen), clause_properties, tipo, - scope, ); - pattern_vec.append(values); + pattern_stack.merge_child(value_stack); } } } - fn when_recursive_ir( + fn expose_elements( &mut self, pattern: &Pattern>, - pattern_vec: &mut Vec, - values: &mut Vec, + pattern_stack: &mut AirStack, + value_stack: AirStack, clause_properties: &mut ClauseProperties, tipo: &Type, - scope: Vec, ) { match pattern { Pattern::Int { .. } => unreachable!(), Pattern::Var { .. } => unreachable!(), Pattern::Assign { .. } => todo!("Nested assign not yet implemented"), Pattern::Discard { .. } => { - pattern_vec.push(Air::Void { scope }); + pattern_stack.void(); - pattern_vec.append(values); + pattern_stack.merge_child(value_stack); } Pattern::List { elements, tail, .. } => { let mut names = vec![]; @@ -1181,7 +1119,6 @@ impl<'a> CodeGenerator<'a> { element, &mut nested_pattern, items_type, - scope.clone(), *clause_properties.is_final_clause(), ); @@ -1231,14 +1168,14 @@ impl<'a> CodeGenerator<'a> { Some((tail_var, tail_name)) }; - pattern_vec.push(Air::ListExpose { + pattern_stack.push(Air::ListExpose { scope, tipo: tipo.clone().into(), tail_head_names, tail, }); } else if !elements.is_empty() { - pattern_vec.push(Air::ListExpose { + pattern_stack.push(Air::ListExpose { scope, tipo: tipo.clone().into(), tail_head_names, @@ -1246,8 +1183,8 @@ impl<'a> CodeGenerator<'a> { }); } - pattern_vec.append(&mut nested_pattern); - pattern_vec.append(values); + pattern_stack.append(&mut nested_pattern); + pattern_stack.append(value_stack); } Pattern::Constructor { is_record, @@ -1302,7 +1239,6 @@ impl<'a> CodeGenerator<'a> { } .into(), ), - scope.clone(), *clause_properties.is_final_clause(), ); @@ -1315,7 +1251,7 @@ impl<'a> CodeGenerator<'a> { .collect::>(); if !arguments_index.is_empty() { - pattern_vec.push(Air::FieldsExpose { + pattern_stack.push(Air::FieldsExpose { indices: arguments_index .iter() .map(|(label, var_name, index)| { @@ -1346,7 +1282,6 @@ impl<'a> CodeGenerator<'a> { &item.value, &mut nested_pattern, type_map.get(&index).unwrap(), - scope.clone(), *clause_properties.is_final_clause(), ); @@ -1357,7 +1292,7 @@ impl<'a> CodeGenerator<'a> { .collect::>(); if !arguments_index.is_empty() { - pattern_vec.push(Air::FieldsExpose { + pattern_stack.push(Air::FieldsExpose { indices: arguments_index .iter() .map(|(name, index)| { @@ -1372,8 +1307,8 @@ impl<'a> CodeGenerator<'a> { } } - pattern_vec.append(values); - pattern_vec.append(&mut nested_pattern); + pattern_stack.append(value_stack); + pattern_stack.append(&mut nested_pattern); } Pattern::Tuple { elems, .. } => { let mut names = vec![]; @@ -1385,7 +1320,6 @@ impl<'a> CodeGenerator<'a> { element, &mut nested_pattern, &items_type[index], - scope.clone(), *clause_properties.is_final_clause(), ); @@ -1420,11 +1354,11 @@ impl<'a> CodeGenerator<'a> { let pattern_type = &tipo.get_inner_types()[index]; - pattern_vec.push(Air::Let { + pattern_stack.push(Air::Let { scope: scope.clone(), name: new_name.clone(), }); - pattern_vec.push(Air::Var { + pattern_stack.push(Air::Var { scope: scope.clone(), constructor: ValueConstructor::public( pattern_type.clone(), @@ -1447,8 +1381,8 @@ impl<'a> CodeGenerator<'a> { _ => unreachable!(), } - pattern_vec.append(&mut nested_pattern); - pattern_vec.append(values); + pattern_stack.append(&mut nested_pattern); + pattern_stack.append(value_stack); } } } @@ -1458,7 +1392,6 @@ impl<'a> CodeGenerator<'a> { pattern: &Pattern>, pattern_vec: &mut Vec, pattern_type: &Arc, - scope: Vec, final_clause: bool, ) -> Option { match pattern { @@ -1507,7 +1440,7 @@ impl<'a> CodeGenerator<'a> { inverse: true, }); - self.when_ir( + self.when_pattern( a, pattern_vec, &mut vec![], @@ -1536,7 +1469,7 @@ impl<'a> CodeGenerator<'a> { inverse: false, }); - self.when_ir( + self.when_pattern( a, pattern_vec, &mut vec![], @@ -1595,7 +1528,7 @@ impl<'a> CodeGenerator<'a> { final_clause, }; - self.when_ir( + self.when_pattern( a, pattern_vec, &mut vec![], @@ -1620,7 +1553,7 @@ impl<'a> CodeGenerator<'a> { let mut inner_pattern_vec = vec![]; - self.when_ir( + self.when_pattern( a, &mut inner_pattern_vec, &mut vec![], @@ -1656,7 +1589,6 @@ impl<'a> CodeGenerator<'a> { pattern, pattern_vec, pattern_type, - scope.clone(), final_clause, ); @@ -1960,7 +1892,7 @@ impl<'a> CodeGenerator<'a> { .constructors .iter() .enumerate() - .find(|(_, constr)| &constr.name == constr_name) + .find(|(_, constr)| constr.name == constr_name) .unwrap(); let constr_name = format!("__{}_{}", constr_name, self.id_gen.next()); @@ -2721,7 +2653,7 @@ impl<'a> CodeGenerator<'a> { .map(|scope| (func_key.clone(), scope.clone())) }) .filter(|func| { - builder::get_common_ancestor(&func.1, &ir.scope()) == ir.scope() + func.1.common_ancestor(&ir.scope()) == ir.scope() && !self.defined_functions.contains_key(&func.0) && !self.zero_arg_functions.contains_key(&func.0) && !(*dependency_map.get(&func.0).unwrap()) @@ -2780,7 +2712,7 @@ impl<'a> CodeGenerator<'a> { &mut self, ir_stack: &mut [Air], func_components: &mut IndexMap, - func_index_map: &mut IndexMap>, + func_index_map: &mut IndexMap, mut recursion_func_map: IndexMap, in_zero_arg_func: bool, ) { @@ -2871,7 +2803,7 @@ impl<'a> CodeGenerator<'a> { for item in inner_func_index_map { if let Some(entry) = func_index_map.get_mut(&item.0) { - *entry = builder::get_common_ancestor(entry, &item.1); + *entry = entry.common_ancestor(&item.1); } else { func_index_map.insert(item.0, item.1); } @@ -2884,10 +2816,10 @@ impl<'a> CodeGenerator<'a> { &mut self, ir_stack: &mut [Air], func_components: &mut IndexMap, - func_index_map: &mut IndexMap>, + func_index_map: &mut IndexMap, in_zero_arg_func: bool, ) { - let mut to_be_defined_map: IndexMap> = IndexMap::new(); + let mut to_be_defined_map: IndexMap = IndexMap::new(); for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() { match ir { Air::Var { @@ -2908,10 +2840,12 @@ impl<'a> CodeGenerator<'a> { let function = *self.functions.get(&non_variant_function_key).unwrap(); - let mut func_ir = vec![]; + let mut func_ir = AirStack::new(&mut self.id_gen); self.build(&function.body, &mut func_ir); + let func_ir = func_ir.air; + let param_types = constructor.tipo.arg_types().unwrap(); let mut mono_types: IndexMap> = IndexMap::new(); @@ -2955,13 +2889,13 @@ impl<'a> CodeGenerator<'a> { }; if let Some(scope_prev) = to_be_defined_map.get(&function_key) { - let new_scope = builder::get_common_ancestor(scope, scope_prev); + let new_scope = scope.common_ancestor(scope_prev); to_be_defined_map.insert(function_key, new_scope); } else if func_components.get(&function_key).is_some() { - to_be_defined_map.insert(function_key.clone(), scope.to_vec()); + to_be_defined_map.insert(function_key.clone(), scope.clone()); } else { - to_be_defined_map.insert(function_key.clone(), scope.to_vec()); + to_be_defined_map.insert(function_key.clone(), scope.clone()); let mut func_calls = IndexMap::new(); for ir in func_ir.clone().into_iter() { @@ -3024,10 +2958,12 @@ impl<'a> CodeGenerator<'a> { } mono_types = map.into_iter().collect(); - let mut func_ir = vec![]; + let mut func_ir = AirStack::new(&mut self.id_gen); self.build(&function.body, &mut func_ir); + let func_ir = func_ir.air; + let (variant_name, _) = builder::monomorphize(func_ir, mono_types, &tipo); @@ -3078,17 +3014,15 @@ impl<'a> CodeGenerator<'a> { } } else { for func in to_be_defined_map.clone().iter() { - if builder::get_common_ancestor(scope, func.1) == scope.to_vec() { + if scope.common_ancestor(func.1) == scope.clone() { if let Some(index_scope) = func_index_map.get(func.0) { - if builder::get_common_ancestor(index_scope, func.1) - == scope.to_vec() - { + if index_scope.common_ancestor(func.1) == scope.clone() { func_index_map.insert(func.0.clone(), scope.clone()); to_be_defined_map.shift_remove(func.0); } else { to_be_defined_map.insert( func.0.clone(), - builder::get_common_ancestor(index_scope, func.1), + index_scope.common_ancestor(func.1), ); } } else { @@ -3103,17 +3037,15 @@ impl<'a> CodeGenerator<'a> { let scope = a.scope(); for func in to_be_defined_map.clone().iter() { - if builder::get_common_ancestor(&scope, func.1) == scope.to_vec() { + if scope.common_ancestor(func.1) == scope.clone() { if let Some(index_scope) = func_index_map.get(func.0) { - if builder::get_common_ancestor(index_scope, func.1) - == scope.to_vec() - { + if index_scope.common_ancestor(func.1) == scope.clone() { func_index_map.insert(func.0.clone(), scope.clone()); to_be_defined_map.shift_remove(func.0); } else { to_be_defined_map.insert( func.0.clone(), - builder::get_common_ancestor(index_scope, func.1), + index_scope.common_ancestor(func.1), ); } } else { @@ -3129,10 +3061,7 @@ impl<'a> CodeGenerator<'a> { // Still to be defined for func in to_be_defined_map.clone().iter() { let index_scope = func_index_map.get(func.0).unwrap(); - func_index_map.insert( - func.0.clone(), - builder::get_common_ancestor(func.1, index_scope), - ); + func_index_map.insert(func.0.clone(), func.1.common_ancestor(index_scope)); } } diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index fbd7014f..82c7f393 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -19,7 +19,7 @@ use crate::{ TypedClause, TypedDataType, UnOp, }, expr::TypedExpr, - tipo::{PatternConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant}, + tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant}, }; use super::{air::Air, scope::Scope, stack::AirStack}; @@ -1477,7 +1477,7 @@ pub fn handle_func_dependencies( handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir); let mut temp_ir = vec![Air::DefineFunc { - scope: func_scope.to_vec(), + scope: func_scope.clone(), func_name: dependency.function_name.clone(), module_name: dependency.module_name.clone(), params: depend_comp.args.clone(), @@ -1667,105 +1667,93 @@ pub fn replace_opaque_type(t: &mut Arc, data_types: IndexMap>, - clause_guard_vec: &mut Vec, - scope: Vec, + clause_guard_stack: &mut AirStack, ) { match clause_guard { ClauseGuard::Not { value, .. } => { - clause_guard_vec.push(Air::UnOp { - scope: scope.clone(), - op: UnOp::Not, - }); + let value_stack = clause_guard_stack.empty_with_scope(); - handle_clause_guard(value, clause_guard_vec, scope); + handle_clause_guard(value, &mut value_stack); + + clause_guard_stack.unop(UnOp::Not, value_stack); } ClauseGuard::Equals { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::Eq, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::Eq, left.tipo(), left_stack, right_stack); } ClauseGuard::NotEquals { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::NotEq, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::NotEq, left.tipo(), left_stack, right_stack); } ClauseGuard::GtInt { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::GtInt, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::GtInt, left.tipo(), left_stack, right_stack); } ClauseGuard::GtEqInt { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::GtEqInt, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::GtEqInt, left.tipo(), left_stack, right_stack); } ClauseGuard::LtInt { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::LtInt, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::LtInt, left.tipo(), left_stack, right_stack); } ClauseGuard::LtEqInt { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::LtEqInt, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::LtEqInt, left.tipo(), left_stack, right_stack); } ClauseGuard::Or { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::Or, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::Or, left.tipo(), left_stack, right_stack); } ClauseGuard::And { left, right, .. } => { - clause_guard_vec.push(Air::BinOp { - scope: scope.clone(), - name: BinOp::And, - tipo: left.tipo(), - }); - handle_clause_guard(left, clause_guard_vec, scope.clone()); - handle_clause_guard(right, clause_guard_vec, scope); + let left_stack = clause_guard_stack.empty_with_scope(); + let right_stack = clause_guard_stack.empty_with_scope(); + + handle_clause_guard(left, &mut left_stack); + handle_clause_guard(right, &mut right_stack); + + clause_guard_stack.binop(BinOp::And, left.tipo(), left_stack, right_stack); } ClauseGuard::Var { tipo, name, .. } => { - clause_guard_vec.push(Air::Var { - scope, - constructor: ValueConstructor::public( - tipo.clone(), - ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - ), - name: name.clone(), - variant_name: String::new(), - }); + clause_guard_stack.local_var(tipo.clone(), name); } ClauseGuard::Constant(constant) => { - constants_ir(constant, clause_guard_vec); + constants_ir(constant, clause_guard_stack); } } } diff --git a/crates/aiken-lang/src/gen_uplc/stack.rs b/crates/aiken-lang/src/gen_uplc/stack.rs index 4046fb36..d29f96f9 100644 --- a/crates/aiken-lang/src/gen_uplc/stack.rs +++ b/crates/aiken-lang/src/gen_uplc/stack.rs @@ -518,4 +518,23 @@ impl<'a> AirStack<'a> { self.merge_child(tuple); } + + pub fn finally(&mut self, value: AirStack) { + self.new_scope(); + + self.air.push(Air::Finally { + scope: self.scope.clone(), + }); + + self.merge_child(value); + } + + pub fn bool(&mut self, value: bool) { + self.new_scope(); + + self.air.push(Air::Bool { + scope: self.scope.clone(), + value, + }); + } }