From 33d902ba2a6a6716daafade5c4f2561ab8bc8cdd Mon Sep 17 00:00:00 2001 From: Kasey White Date: Tue, 17 Jan 2023 02:30:56 -0500 Subject: [PATCH] feat: Now opaque types with one constr and one field are converted to inner field type --- crates/aiken-lang/src/air.rs | 10 +- crates/aiken-lang/src/builder.rs | 160 ++++++++++++++++++++----------- crates/aiken-lang/src/uplc.rs | 82 +++++++++------- 3 files changed, 158 insertions(+), 94 deletions(-) diff --git a/crates/aiken-lang/src/air.rs b/crates/aiken-lang/src/air.rs index fb34068a..3ecb4648 100644 --- a/crates/aiken-lang/src/air.rs +++ b/crates/aiken-lang/src/air.rs @@ -164,7 +164,7 @@ pub enum Air { RecordAccess { scope: Vec, - index: u64, + record_index: u64, tipo: Arc, }, @@ -183,7 +183,7 @@ pub enum Air { TupleIndex { scope: Vec, tipo: Arc, - index: usize, + tuple_index: usize, }, Todo { @@ -283,7 +283,11 @@ impl Air { | Air::Todo { tipo, .. } | Air::ErrorTerm { tipo, .. } | Air::Trace { tipo, .. } - | Air::TupleAccessor { tipo, .. } => Some(tipo.clone()), + | Air::TupleAccessor { tipo, .. } + | Air::Var { + constructor: ValueConstructor { tipo, .. }, + .. + } => Some(tipo.clone()), _ => None, } } diff --git a/crates/aiken-lang/src/builder.rs b/crates/aiken-lang/src/builder.rs index c13d6b67..5dee5025 100644 --- a/crates/aiken-lang/src/builder.rs +++ b/crates/aiken-lang/src/builder.rs @@ -1180,6 +1180,31 @@ pub fn monomorphize( needs_variant = true; } } + Air::TupleClause { + scope, + tipo, + indices, + predefined_indices, + subject_name, + count, + complex_clause, + } => { + if tipo.is_generic() { + let mut tipo = tipo.clone(); + find_generics_to_replace(&mut tipo, &generic_types); + + new_air[index] = Air::TupleClause { + scope, + tipo, + indices, + predefined_indices, + subject_name, + count, + complex_clause, + }; + needs_variant = true; + } + } Air::ClauseGuard { tipo, scope, @@ -1218,6 +1243,59 @@ pub fn monomorphize( needs_variant = true; } } + Air::Tuple { scope, tipo, count } => { + if tipo.is_generic() { + let mut tipo = tipo.clone(); + find_generics_to_replace(&mut tipo, &generic_types); + + new_air[index] = Air::Tuple { scope, tipo, count }; + needs_variant = true; + } + } + Air::TupleIndex { + scope, + tipo, + tuple_index, + } => { + if tipo.is_generic() { + let mut tipo = tipo.clone(); + find_generics_to_replace(&mut tipo, &generic_types); + + new_air[index] = Air::TupleIndex { + scope, + tipo, + tuple_index, + }; + needs_variant = true; + } + } + Air::Todo { scope, label, tipo } => { + if tipo.is_generic() { + let mut tipo = tipo.clone(); + find_generics_to_replace(&mut tipo, &generic_types); + + new_air[index] = Air::Todo { scope, tipo, label }; + needs_variant = true; + } + } + Air::ErrorTerm { scope, label, tipo } => { + if tipo.is_generic() { + let mut tipo = tipo.clone(); + find_generics_to_replace(&mut tipo, &generic_types); + + new_air[index] = Air::ErrorTerm { scope, tipo, label }; + needs_variant = true; + } + } + Air::Trace { scope, text, tipo } => { + if tipo.is_generic() { + let mut tipo = tipo.clone(); + find_generics_to_replace(&mut tipo, &generic_types); + + new_air[index] = Air::Trace { scope, tipo, text }; + needs_variant = true; + } + } Air::Record { scope, constr_index, @@ -1237,10 +1315,9 @@ pub fn monomorphize( needs_variant = true; } } - Air::RecordAccess { scope, - index: record_index, + record_index, tipo, } => { if tipo.is_generic() { @@ -1249,7 +1326,7 @@ pub fn monomorphize( new_air[index] = Air::RecordAccess { scope, - index: record_index, + record_index, tipo, }; needs_variant = true; @@ -1277,24 +1354,6 @@ pub fn monomorphize( indices: new_indices, }; } - Air::Tuple { scope, tipo, count } => { - if tipo.is_generic() { - let mut tipo = tipo.clone(); - find_generics_to_replace(&mut tipo, &generic_types); - - new_air[index] = Air::Tuple { scope, count, tipo }; - needs_variant = true; - } - } - Air::Todo { scope, label, tipo } => { - if tipo.is_generic() { - let mut tipo = tipo.clone(); - find_generics_to_replace(&mut tipo, &generic_types); - - new_air[index] = Air::Todo { scope, label, tipo }; - needs_variant = true; - } - } Air::RecordUpdate { scope, highest_index, @@ -1326,31 +1385,6 @@ pub fn monomorphize( needs_variant = true; } } - Air::TupleClause { - scope, - tipo, - indices, - predefined_indices, - subject_name, - count, - complex_clause, - } => { - if tipo.is_generic() { - let mut tipo = tipo.clone(); - find_generics_to_replace(&mut tipo, &generic_types); - - new_air[index] = Air::TupleClause { - scope, - tipo, - indices, - predefined_indices, - subject_name, - count, - complex_clause, - }; - needs_variant = true; - } - } _ => {} } } @@ -1515,24 +1549,34 @@ pub fn check_replaceable_opaque_type( data_types: &HashMap, ) -> bool { let data_type = lookup_data_type_by_tipo(data_types.clone(), t); - let args = t.arg_types(); - if let Some(args) = args { - if let Some(data_type) = data_type { - args.len() == 1 && data_type.opaque && data_type.constructors.len() == 1 - } else { - false - } + + if let Some(data_type) = data_type { + let data_type_args = data_type.constructors[0].arguments.clone(); + data_type_args.len() == 1 && data_type.opaque && data_type.constructors.len() == 1 } else { false } } pub fn replace_opaque_type(t: &mut Arc, data_types: HashMap) { - if check_replaceable_opaque_type(t, &data_types) { - let new_args = t.arg_types(); - let mut new_type = new_args.unwrap()[0].clone(); - replace_opaque_type(&mut new_type, data_types.clone()); - *t = new_type; + if check_replaceable_opaque_type(t, &data_types) && matches!(&**t, Type::App { .. }) { + let data_type = lookup_data_type_by_tipo(data_types.clone(), t).unwrap(); + let new_type_fields = data_type.typed_parameters.clone(); + + let mut generics_type_map: HashMap> = HashMap::new(); + + for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) { + let mut map = generics_type_map.into_iter().collect_vec(); + map.append(&mut get_generics_and_type(tipo, ¶m)); + generics_type_map = map.into_iter().collect(); + } + + let mut generic_type = data_type.constructors[0].arguments[0].tipo.clone(); + + find_generics_to_replace(&mut generic_type, &generics_type_map); + + replace_opaque_type(&mut generic_type, data_types.clone()); + *t = generic_type; } else { match (**t).clone() { Type::App { diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index ab117a0f..aa09ae4e 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -444,7 +444,7 @@ impl<'a> CodeGenerator<'a> { ir_stack.push(Air::RecordAccess { scope: scope.clone(), - index: *index, + record_index: *index, tipo: tipo.clone(), }); @@ -583,7 +583,7 @@ impl<'a> CodeGenerator<'a> { ir_stack.push(Air::TupleIndex { scope: scope.clone(), tipo: tuple.tipo(), - index: *index, + tuple_index: *index, }); self.build_ir(tuple, ir_stack, scope); @@ -1884,6 +1884,9 @@ impl<'a> CodeGenerator<'a> { let mut final_zero_arg_ir = dep_ir; final_zero_arg_ir.extend(funt_comp.ir.clone()); + + self.convert_opaque_type_to_inner_ir(&mut final_zero_arg_ir); + self.zero_arg_functions.insert(func, final_zero_arg_ir); for (key, val) in defined_functions.into_iter() { @@ -2270,7 +2273,8 @@ impl<'a> CodeGenerator<'a> { } fn convert_opaque_type_to_inner_ir(&mut self, ir_stack: &mut Vec) { - for (index, ir) in ir_stack.clone().into_iter().enumerate().rev() { + let mut indices_to_remove = vec![]; + for (index, ir) in ir_stack.clone().into_iter().enumerate() { match ir { Air::Var { scope, @@ -2478,14 +2482,18 @@ impl<'a> CodeGenerator<'a> { count, }; } - Air::TupleIndex { tipo, scope, index } => { + Air::TupleIndex { + tipo, + scope, + tuple_index, + } => { let mut replaced_type = tipo.clone(); replace_opaque_type(&mut replaced_type, self.data_types.clone()); ir_stack[index] = Air::TupleIndex { scope, tipo: replaced_type, - index, + tuple_index, }; } Air::Todo { tipo, scope, label } => { @@ -2528,6 +2536,24 @@ impl<'a> CodeGenerator<'a> { tipo: replaced_type, }; } + Air::RecordUpdate { + highest_index, + indices, + scope, + } => { + let mut new_indices = vec![]; + for (ind, tipo) in indices { + let mut replaced_type = tipo.clone(); + replace_opaque_type(&mut replaced_type, self.data_types.clone()); + new_indices.push((ind, replaced_type)); + } + + ir_stack[index] = Air::RecordUpdate { + scope, + indices: new_indices, + highest_index, + }; + } Air::Record { constr_index, tipo, @@ -2535,7 +2561,7 @@ impl<'a> CodeGenerator<'a> { scope, } => { if check_replaceable_opaque_type(&tipo, self.data_types) { - ir_stack.remove(index); + indices_to_remove.push(index); } else { let mut replaced_type = tipo.clone(); replace_opaque_type(&mut replaced_type, self.data_types.clone()); @@ -2549,7 +2575,7 @@ impl<'a> CodeGenerator<'a> { } } Air::RecordAccess { - index: record_field_index, + record_index, tipo, scope, } => { @@ -2557,14 +2583,14 @@ impl<'a> CodeGenerator<'a> { let record_type = record.tipo(); if let Some(record_type) = record_type { if check_replaceable_opaque_type(&record_type, self.data_types) { - ir_stack.remove(index); + indices_to_remove.push(index); } else { let mut replaced_type = tipo.clone(); replace_opaque_type(&mut replaced_type, self.data_types.clone()); ir_stack[index] = Air::RecordAccess { scope, - index: record_field_index, + record_index, tipo: replaced_type, }; } @@ -2574,7 +2600,7 @@ impl<'a> CodeGenerator<'a> { ir_stack[index] = Air::RecordAccess { scope, - index: record_field_index, + record_index, tipo: replaced_type, }; } @@ -2621,27 +2647,13 @@ impl<'a> CodeGenerator<'a> { }; } } - Air::RecordUpdate { - highest_index, - indices, - scope, - } => { - let mut new_indices = vec![]; - for (ind, tipo) in indices { - let mut replaced_type = tipo.clone(); - replace_opaque_type(&mut replaced_type, self.data_types.clone()); - new_indices.push((ind, replaced_type)); - } - - ir_stack[index] = Air::RecordUpdate { - scope, - indices: new_indices, - highest_index, - }; - } _ => {} } } + + for index in indices_to_remove.into_iter().rev() { + ir_stack.remove(index); + } } fn uplc_code_gen(&mut self, ir_stack: &mut Vec) -> Term { @@ -3931,7 +3943,9 @@ impl<'a> CodeGenerator<'a> { arg_stack.push(term); } - Air::RecordAccess { index, tipo, .. } => { + Air::RecordAccess { + record_index, tipo, .. + } => { let constr = arg_stack.pop().unwrap(); let mut term = apply_wrap( @@ -3948,7 +3962,7 @@ impl<'a> CodeGenerator<'a> { constr, ), ), - Term::Constant(UplcConstant::Integer(index.into())), + Term::Constant(UplcConstant::Integer(record_index.into())), ); term = convert_data_to_type(term, &tipo); @@ -4352,11 +4366,13 @@ impl<'a> CodeGenerator<'a> { arg_stack.push(term); } - Air::TupleIndex { tipo, index, .. } => { + Air::TupleIndex { + tipo, tuple_index, .. + } => { let mut term = arg_stack.pop().unwrap(); if matches!(tipo.get_uplc_type(), UplcType::Pair(_, _)) { - if index == 0 { + if tuple_index == 0 { term = convert_data_to_type( apply_wrap( Term::Builtin(DefaultFunction::FstPair) @@ -4387,7 +4403,7 @@ impl<'a> CodeGenerator<'a> { }), term, ), - Term::Constant(UplcConstant::Integer(index as i128)), + Term::Constant(UplcConstant::Integer(tuple_index as i128)), ); }