feat: Now opaque types with one constr and one field are converted to inner field type
This commit is contained in:
parent
98d2cb5afc
commit
33d902ba2a
|
@ -164,7 +164,7 @@ pub enum Air {
|
|||
|
||||
RecordAccess {
|
||||
scope: Vec<u64>,
|
||||
index: u64,
|
||||
record_index: u64,
|
||||
tipo: Arc<Type>,
|
||||
},
|
||||
|
||||
|
@ -183,7 +183,7 @@ pub enum Air {
|
|||
TupleIndex {
|
||||
scope: Vec<u64>,
|
||||
tipo: Arc<Type>,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<DataTypeKey, &TypedDataType>,
|
||||
) -> 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<Type>, data_types: HashMap<DataTypeKey, &TypedDataType>) {
|
||||
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<u64, Arc<Type>> = 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 {
|
||||
|
|
|
@ -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<Air>) {
|
||||
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<Air>) -> Term<Name> {
|
||||
|
@ -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)),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue