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 {
|
RecordAccess {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
index: u64,
|
record_index: u64,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ pub enum Air {
|
||||||
TupleIndex {
|
TupleIndex {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
index: usize,
|
tuple_index: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
Todo {
|
Todo {
|
||||||
|
@ -283,7 +283,11 @@ impl Air {
|
||||||
| Air::Todo { tipo, .. }
|
| Air::Todo { tipo, .. }
|
||||||
| Air::ErrorTerm { tipo, .. }
|
| Air::ErrorTerm { tipo, .. }
|
||||||
| Air::Trace { tipo, .. }
|
| Air::Trace { tipo, .. }
|
||||||
| Air::TupleAccessor { tipo, .. } => Some(tipo.clone()),
|
| Air::TupleAccessor { tipo, .. }
|
||||||
|
| Air::Var {
|
||||||
|
constructor: ValueConstructor { tipo, .. },
|
||||||
|
..
|
||||||
|
} => Some(tipo.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1180,6 +1180,31 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
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 {
|
Air::ClauseGuard {
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
|
@ -1218,6 +1243,59 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
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 {
|
Air::Record {
|
||||||
scope,
|
scope,
|
||||||
constr_index,
|
constr_index,
|
||||||
|
@ -1237,10 +1315,9 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Air::RecordAccess {
|
Air::RecordAccess {
|
||||||
scope,
|
scope,
|
||||||
index: record_index,
|
record_index,
|
||||||
tipo,
|
tipo,
|
||||||
} => {
|
} => {
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
|
@ -1249,7 +1326,7 @@ pub fn monomorphize(
|
||||||
|
|
||||||
new_air[index] = Air::RecordAccess {
|
new_air[index] = Air::RecordAccess {
|
||||||
scope,
|
scope,
|
||||||
index: record_index,
|
record_index,
|
||||||
tipo,
|
tipo,
|
||||||
};
|
};
|
||||||
needs_variant = true;
|
needs_variant = true;
|
||||||
|
@ -1277,24 +1354,6 @@ pub fn monomorphize(
|
||||||
indices: new_indices,
|
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 {
|
Air::RecordUpdate {
|
||||||
scope,
|
scope,
|
||||||
highest_index,
|
highest_index,
|
||||||
|
@ -1326,31 +1385,6 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
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>,
|
data_types: &HashMap<DataTypeKey, &TypedDataType>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let data_type = lookup_data_type_by_tipo(data_types.clone(), t);
|
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 {
|
if let Some(data_type) = data_type {
|
||||||
args.len() == 1 && data_type.opaque && data_type.constructors.len() == 1
|
let data_type_args = data_type.constructors[0].arguments.clone();
|
||||||
} else {
|
data_type_args.len() == 1 && data_type.opaque && data_type.constructors.len() == 1
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_opaque_type(t: &mut Arc<Type>, data_types: HashMap<DataTypeKey, &TypedDataType>) {
|
pub fn replace_opaque_type(t: &mut Arc<Type>, data_types: HashMap<DataTypeKey, &TypedDataType>) {
|
||||||
if check_replaceable_opaque_type(t, &data_types) {
|
if check_replaceable_opaque_type(t, &data_types) && matches!(&**t, Type::App { .. }) {
|
||||||
let new_args = t.arg_types();
|
let data_type = lookup_data_type_by_tipo(data_types.clone(), t).unwrap();
|
||||||
let mut new_type = new_args.unwrap()[0].clone();
|
let new_type_fields = data_type.typed_parameters.clone();
|
||||||
replace_opaque_type(&mut new_type, data_types.clone());
|
|
||||||
*t = new_type;
|
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 {
|
} else {
|
||||||
match (**t).clone() {
|
match (**t).clone() {
|
||||||
Type::App {
|
Type::App {
|
||||||
|
|
|
@ -444,7 +444,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
ir_stack.push(Air::RecordAccess {
|
ir_stack.push(Air::RecordAccess {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
index: *index,
|
record_index: *index,
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
ir_stack.push(Air::TupleIndex {
|
ir_stack.push(Air::TupleIndex {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: tuple.tipo(),
|
tipo: tuple.tipo(),
|
||||||
index: *index,
|
tuple_index: *index,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.build_ir(tuple, ir_stack, scope);
|
self.build_ir(tuple, ir_stack, scope);
|
||||||
|
@ -1884,6 +1884,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let mut final_zero_arg_ir = dep_ir;
|
let mut final_zero_arg_ir = dep_ir;
|
||||||
final_zero_arg_ir.extend(funt_comp.ir.clone());
|
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);
|
self.zero_arg_functions.insert(func, final_zero_arg_ir);
|
||||||
|
|
||||||
for (key, val) in defined_functions.into_iter() {
|
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>) {
|
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 {
|
match ir {
|
||||||
Air::Var {
|
Air::Var {
|
||||||
scope,
|
scope,
|
||||||
|
@ -2478,14 +2482,18 @@ impl<'a> CodeGenerator<'a> {
|
||||||
count,
|
count,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Air::TupleIndex { tipo, scope, index } => {
|
Air::TupleIndex {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
tuple_index,
|
||||||
|
} => {
|
||||||
let mut replaced_type = tipo.clone();
|
let mut replaced_type = tipo.clone();
|
||||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
ir_stack[index] = Air::TupleIndex {
|
ir_stack[index] = Air::TupleIndex {
|
||||||
scope,
|
scope,
|
||||||
tipo: replaced_type,
|
tipo: replaced_type,
|
||||||
index,
|
tuple_index,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Air::Todo { tipo, scope, label } => {
|
Air::Todo { tipo, scope, label } => {
|
||||||
|
@ -2528,6 +2536,24 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo: replaced_type,
|
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 {
|
Air::Record {
|
||||||
constr_index,
|
constr_index,
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -2535,7 +2561,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope,
|
scope,
|
||||||
} => {
|
} => {
|
||||||
if check_replaceable_opaque_type(&tipo, self.data_types) {
|
if check_replaceable_opaque_type(&tipo, self.data_types) {
|
||||||
ir_stack.remove(index);
|
indices_to_remove.push(index);
|
||||||
} else {
|
} else {
|
||||||
let mut replaced_type = tipo.clone();
|
let mut replaced_type = tipo.clone();
|
||||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
@ -2549,7 +2575,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::RecordAccess {
|
Air::RecordAccess {
|
||||||
index: record_field_index,
|
record_index,
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
} => {
|
} => {
|
||||||
|
@ -2557,14 +2583,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let record_type = record.tipo();
|
let record_type = record.tipo();
|
||||||
if let Some(record_type) = record_type {
|
if let Some(record_type) = record_type {
|
||||||
if check_replaceable_opaque_type(&record_type, self.data_types) {
|
if check_replaceable_opaque_type(&record_type, self.data_types) {
|
||||||
ir_stack.remove(index);
|
indices_to_remove.push(index);
|
||||||
} else {
|
} else {
|
||||||
let mut replaced_type = tipo.clone();
|
let mut replaced_type = tipo.clone();
|
||||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
ir_stack[index] = Air::RecordAccess {
|
ir_stack[index] = Air::RecordAccess {
|
||||||
scope,
|
scope,
|
||||||
index: record_field_index,
|
record_index,
|
||||||
tipo: replaced_type,
|
tipo: replaced_type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2574,7 +2600,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
ir_stack[index] = Air::RecordAccess {
|
ir_stack[index] = Air::RecordAccess {
|
||||||
scope,
|
scope,
|
||||||
index: record_field_index,
|
record_index,
|
||||||
tipo: replaced_type,
|
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> {
|
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);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
Air::RecordAccess { index, tipo, .. } => {
|
Air::RecordAccess {
|
||||||
|
record_index, tipo, ..
|
||||||
|
} => {
|
||||||
let constr = arg_stack.pop().unwrap();
|
let constr = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
let mut term = apply_wrap(
|
let mut term = apply_wrap(
|
||||||
|
@ -3948,7 +3962,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
constr,
|
constr,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Term::Constant(UplcConstant::Integer(index.into())),
|
Term::Constant(UplcConstant::Integer(record_index.into())),
|
||||||
);
|
);
|
||||||
|
|
||||||
term = convert_data_to_type(term, &tipo);
|
term = convert_data_to_type(term, &tipo);
|
||||||
|
@ -4352,11 +4366,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
Air::TupleIndex { tipo, index, .. } => {
|
Air::TupleIndex {
|
||||||
|
tipo, tuple_index, ..
|
||||||
|
} => {
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
if matches!(tipo.get_uplc_type(), UplcType::Pair(_, _)) {
|
if matches!(tipo.get_uplc_type(), UplcType::Pair(_, _)) {
|
||||||
if index == 0 {
|
if tuple_index == 0 {
|
||||||
term = convert_data_to_type(
|
term = convert_data_to_type(
|
||||||
apply_wrap(
|
apply_wrap(
|
||||||
Term::Builtin(DefaultFunction::FstPair)
|
Term::Builtin(DefaultFunction::FstPair)
|
||||||
|
@ -4387,7 +4403,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}),
|
}),
|
||||||
term,
|
term,
|
||||||
),
|
),
|
||||||
Term::Constant(UplcConstant::Integer(index as i128)),
|
Term::Constant(UplcConstant::Integer(tuple_index as i128)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue