in progress: working on taking special opaque types and converting them to their inner type
This commit is contained in:
parent
0da4560792
commit
98d2cb5afc
|
@ -158,7 +158,7 @@ pub enum Air {
|
||||||
Record {
|
Record {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
constr_index: usize,
|
constr_index: usize,
|
||||||
constr_type: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -262,4 +262,29 @@ impl Air {
|
||||||
| Air::TupleClause { scope, .. } => scope.to_vec(),
|
| Air::TupleClause { scope, .. } => scope.to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tipo(&self) -> Option<Arc<Type>> {
|
||||||
|
match self {
|
||||||
|
Air::List { tipo, .. }
|
||||||
|
| Air::ListAccessor { tipo, .. }
|
||||||
|
| Air::ListExpose { tipo, .. }
|
||||||
|
| Air::Builtin { tipo, .. }
|
||||||
|
| Air::BinOp { tipo, .. }
|
||||||
|
| Air::When { tipo, .. }
|
||||||
|
| Air::Clause { tipo, .. }
|
||||||
|
| Air::ListClause { tipo, .. }
|
||||||
|
| Air::TupleClause { tipo, .. }
|
||||||
|
| Air::ClauseGuard { tipo, .. }
|
||||||
|
| Air::ListClauseGuard { tipo, .. }
|
||||||
|
| Air::Record { tipo, .. }
|
||||||
|
| Air::RecordAccess { tipo, .. }
|
||||||
|
| Air::Tuple { tipo, .. }
|
||||||
|
| Air::TupleIndex { tipo, .. }
|
||||||
|
| Air::Todo { tipo, .. }
|
||||||
|
| Air::ErrorTerm { tipo, .. }
|
||||||
|
| Air::Trace { tipo, .. }
|
||||||
|
| Air::TupleAccessor { tipo, .. } => Some(tipo.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use uplc::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
air::Air,
|
air::Air,
|
||||||
ast::{Clause, Constant, Pattern, Span, TypedArg},
|
ast::{Clause, Constant, DataType, Pattern, Span, TypedArg, TypedDataType},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant},
|
tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant},
|
||||||
};
|
};
|
||||||
|
@ -1221,16 +1221,16 @@ pub fn monomorphize(
|
||||||
Air::Record {
|
Air::Record {
|
||||||
scope,
|
scope,
|
||||||
constr_index,
|
constr_index,
|
||||||
constr_type,
|
tipo,
|
||||||
count,
|
count,
|
||||||
} => {
|
} => {
|
||||||
if constr_type.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut constr_type = constr_type.clone();
|
let mut tipo = tipo.clone();
|
||||||
find_generics_to_replace(&mut constr_type, &generic_types);
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
new_air[index] = Air::Record {
|
new_air[index] = Air::Record {
|
||||||
scope,
|
scope,
|
||||||
constr_type,
|
tipo,
|
||||||
constr_index,
|
constr_index,
|
||||||
count,
|
count,
|
||||||
};
|
};
|
||||||
|
@ -1475,3 +1475,119 @@ pub fn handle_recursion_ir(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lookup_data_type_by_tipo(
|
||||||
|
data_types: HashMap<DataTypeKey, &TypedDataType>,
|
||||||
|
tipo: &Type,
|
||||||
|
) -> Option<DataType<Arc<Type>>> {
|
||||||
|
match tipo {
|
||||||
|
Type::Fn { ret, .. } => match ret.as_ref() {
|
||||||
|
Type::App { module, name, .. } => {
|
||||||
|
let data_type_key = DataTypeKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
defined_type: name.clone(),
|
||||||
|
};
|
||||||
|
data_types.get(&data_type_key).map(|item| (*item).clone())
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
Type::App { module, name, .. } => {
|
||||||
|
let data_type_key = DataTypeKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
defined_type: name.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
data_types.get(&data_type_key).map(|item| (*item).clone())
|
||||||
|
}
|
||||||
|
Type::Var { tipo } => {
|
||||||
|
if let TypeVar::Link { tipo } = &*tipo.borrow() {
|
||||||
|
lookup_data_type_by_tipo(data_types, tipo)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_replaceable_opaque_type(
|
||||||
|
t: &Arc<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
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
|
} else {
|
||||||
|
match (**t).clone() {
|
||||||
|
Type::App {
|
||||||
|
public,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
} => {
|
||||||
|
let mut new_args = vec![];
|
||||||
|
for arg in args {
|
||||||
|
let mut new_arg_type = arg.clone();
|
||||||
|
replace_opaque_type(&mut new_arg_type, data_types.clone());
|
||||||
|
new_args.push(new_arg_type);
|
||||||
|
}
|
||||||
|
*t = Type::App {
|
||||||
|
public,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
args: new_args,
|
||||||
|
}
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
Type::Fn { args, ret } => {
|
||||||
|
let mut new_args = vec![];
|
||||||
|
for arg in args {
|
||||||
|
let mut new_arg_type = arg.clone();
|
||||||
|
replace_opaque_type(&mut new_arg_type, data_types.clone());
|
||||||
|
new_args.push(new_arg_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_ret = ret;
|
||||||
|
replace_opaque_type(&mut new_ret, data_types.clone());
|
||||||
|
|
||||||
|
*t = Type::Fn {
|
||||||
|
args: new_args,
|
||||||
|
ret: new_ret,
|
||||||
|
}
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
Type::Var { tipo } => {
|
||||||
|
if let TypeVar::Link { tipo } = &*tipo.borrow() {
|
||||||
|
let mut new_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut new_type, data_types.clone());
|
||||||
|
*t = new_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Type::Tuple { elems } => {
|
||||||
|
let mut new_elems = vec![];
|
||||||
|
for arg in elems {
|
||||||
|
let mut new_arg_type = arg.clone();
|
||||||
|
replace_opaque_type(&mut new_arg_type, data_types.clone());
|
||||||
|
new_elems.push(new_arg_type);
|
||||||
|
}
|
||||||
|
*t = Type::Tuple { elems: new_elems }.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::{
|
||||||
vec,
|
vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::tipo::TypeVar;
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
|
@ -23,13 +22,14 @@ use uplc::{
|
||||||
use crate::{
|
use crate::{
|
||||||
air::Air,
|
air::Air,
|
||||||
ast::{
|
ast::{
|
||||||
ArgName, AssignmentKind, BinOp, Clause, DataType, Pattern, Span, TypedArg, TypedDataType,
|
ArgName, AssignmentKind, BinOp, Clause, Pattern, Span, TypedArg, TypedDataType,
|
||||||
TypedFunction, UnOp,
|
TypedFunction, UnOp,
|
||||||
},
|
},
|
||||||
builder::{
|
builder::{
|
||||||
check_when_pattern_needs, constants_ir, convert_constants_to_data, convert_data_to_type,
|
check_replaceable_opaque_type, check_when_pattern_needs, constants_ir,
|
||||||
convert_type_to_data, get_common_ancestor, get_generics_and_type, handle_func_deps_ir,
|
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
|
||||||
handle_recursion_ir, list_access_to_uplc, monomorphize, rearrange_clauses,
|
get_generics_and_type, handle_func_deps_ir, handle_recursion_ir, list_access_to_uplc,
|
||||||
|
lookup_data_type_by_tipo, monomorphize, rearrange_clauses, replace_opaque_type,
|
||||||
wrap_validator_args, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
|
wrap_validator_args, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
|
||||||
},
|
},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
|
@ -83,6 +83,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.define_ir(&mut ir_stack);
|
self.define_ir(&mut ir_stack);
|
||||||
|
|
||||||
|
self.convert_opaque_type_to_inner_ir(&mut ir_stack);
|
||||||
|
|
||||||
let mut term = self.uplc_code_gen(&mut ir_stack);
|
let mut term = self.uplc_code_gen(&mut ir_stack);
|
||||||
|
|
||||||
if self.needs_field_access {
|
if self.needs_field_access {
|
||||||
|
@ -210,7 +212,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
TypedExpr::Call {
|
TypedExpr::Call {
|
||||||
fun, args, tipo, ..
|
fun, args, tipo, ..
|
||||||
} => {
|
} => {
|
||||||
if let Some(data_type) = self.lookup_data_type_by_tipo(tipo) {
|
if let Some(data_type) = lookup_data_type_by_tipo(self.data_types.clone(), tipo) {
|
||||||
if let TypedExpr::Var { constructor, .. } = &**fun {
|
if let TypedExpr::Var { constructor, .. } = &**fun {
|
||||||
if let ValueConstructorVariant::Record {
|
if let ValueConstructorVariant::Record {
|
||||||
name: constr_name, ..
|
name: constr_name, ..
|
||||||
|
@ -226,7 +228,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
ir_stack.push(Air::Record {
|
ir_stack.push(Air::Record {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
constr_index,
|
constr_index,
|
||||||
constr_type: constructor.tipo.clone(),
|
tipo: constructor.tipo.clone(),
|
||||||
count: args.len(),
|
count: args.len(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -841,7 +843,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find data type definition
|
// find data type definition
|
||||||
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
|
||||||
|
|
||||||
let (index, _) = data_type
|
let (index, _) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
|
@ -1017,7 +1019,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
|
||||||
|
|
||||||
let (_, constructor_type) = data_type
|
let (_, constructor_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
|
@ -1335,7 +1337,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} => {
|
} => {
|
||||||
let id = self.id_gen.next();
|
let id = self.id_gen.next();
|
||||||
let constr_var_name = format!("{constr_name}_{id}");
|
let constr_var_name = format!("{constr_name}_{id}");
|
||||||
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
|
||||||
|
|
||||||
if data_type.constructors.len() > 1 {
|
if data_type.constructors.len() > 1 {
|
||||||
pattern_vec.push(Air::ClauseGuard {
|
pattern_vec.push(Air::ClauseGuard {
|
||||||
|
@ -1448,7 +1450,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type = self.lookup_data_type_by_tipo(tipo);
|
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo);
|
||||||
|
|
||||||
let (index, _) = data_type
|
let (index, _) = data_type
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -1601,7 +1603,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
|
||||||
let (_, constructor_type) = data_type
|
let (_, constructor_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -2260,13 +2262,388 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Still to be defined
|
// Still to be defined
|
||||||
for func in to_be_defined_map.clone().iter() {
|
for func in to_be_defined_map.clone().iter() {
|
||||||
let index_scope = func_index_map.get(func.0).unwrap();
|
let index_scope = func_index_map.get(func.0).unwrap();
|
||||||
func_index_map.insert(func.0.clone(), get_common_ancestor(func.1, index_scope));
|
func_index_map.insert(func.0.clone(), get_common_ancestor(func.1, index_scope));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
match ir {
|
||||||
|
Air::Var {
|
||||||
|
scope,
|
||||||
|
constructor,
|
||||||
|
name,
|
||||||
|
variant_name,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = constructor.tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Var {
|
||||||
|
scope,
|
||||||
|
constructor: ValueConstructor {
|
||||||
|
public: constructor.public,
|
||||||
|
variant: constructor.variant,
|
||||||
|
tipo: replaced_type,
|
||||||
|
},
|
||||||
|
name,
|
||||||
|
variant_name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::List {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
count,
|
||||||
|
tail,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::List {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
count,
|
||||||
|
tail,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::ListAccessor {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
names,
|
||||||
|
tail,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::ListAccessor {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
names,
|
||||||
|
tail,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::ListExpose {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
tail_head_names,
|
||||||
|
tail,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::ListExpose {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
tail_head_names,
|
||||||
|
tail,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::Builtin { tipo, scope, func } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Builtin {
|
||||||
|
scope,
|
||||||
|
func,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::BinOp {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
name,
|
||||||
|
count,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::BinOp {
|
||||||
|
scope,
|
||||||
|
name,
|
||||||
|
count,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::When {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
subject_name,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::When {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
subject_name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::Clause {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
subject_name,
|
||||||
|
complex_clause,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Clause {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
subject_name,
|
||||||
|
complex_clause,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::ListClause {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
complex_clause,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::ListClause {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
complex_clause,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::TupleClause {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
indices,
|
||||||
|
predefined_indices,
|
||||||
|
subject_name,
|
||||||
|
count,
|
||||||
|
complex_clause,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::TupleClause {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
indices,
|
||||||
|
predefined_indices,
|
||||||
|
subject_name,
|
||||||
|
count,
|
||||||
|
complex_clause,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::ClauseGuard {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
subject_name,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::ClauseGuard {
|
||||||
|
scope,
|
||||||
|
subject_name,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::ListClauseGuard {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
|
} => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::ListClauseGuard {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::Tuple { tipo, scope, count } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Tuple {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::TupleIndex { tipo, scope, 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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::Todo { tipo, scope, label } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Todo {
|
||||||
|
scope,
|
||||||
|
label,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::ErrorTerm { tipo, scope, label } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::ErrorTerm {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
label,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::Trace { tipo, scope, text } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Trace {
|
||||||
|
scope,
|
||||||
|
text,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::TupleAccessor { tipo, scope, names } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::TupleAccessor {
|
||||||
|
scope,
|
||||||
|
names,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Air::Record {
|
||||||
|
constr_index,
|
||||||
|
tipo,
|
||||||
|
count,
|
||||||
|
scope,
|
||||||
|
} => {
|
||||||
|
if check_replaceable_opaque_type(&tipo, self.data_types) {
|
||||||
|
ir_stack.remove(index);
|
||||||
|
} else {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::Record {
|
||||||
|
scope,
|
||||||
|
constr_index,
|
||||||
|
tipo: replaced_type,
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Air::RecordAccess {
|
||||||
|
index: record_field_index,
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
} => {
|
||||||
|
let record = ir_stack[index + 1].clone();
|
||||||
|
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);
|
||||||
|
} 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,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} 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,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Air::FieldsExpose {
|
||||||
|
count,
|
||||||
|
indices,
|
||||||
|
scope,
|
||||||
|
} => {
|
||||||
|
let record = ir_stack[index + 1].clone();
|
||||||
|
let record_type = record.tipo();
|
||||||
|
if let Some(record_type) = record_type {
|
||||||
|
if check_replaceable_opaque_type(&record_type, self.data_types) {
|
||||||
|
ir_stack[index] = Air::Lam {
|
||||||
|
scope,
|
||||||
|
name: indices[0].1.clone(),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
let mut new_indices = vec![];
|
||||||
|
for (ind, name, tipo) in indices {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
new_indices.push((ind, name, replaced_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_stack[index] = Air::FieldsExpose {
|
||||||
|
scope,
|
||||||
|
indices: new_indices,
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut new_indices = vec![];
|
||||||
|
for (ind, name, tipo) in indices {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
new_indices.push((ind, name, replaced_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_stack[index] = Air::FieldsExpose {
|
||||||
|
scope,
|
||||||
|
indices: new_indices,
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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> {
|
||||||
let mut arg_stack: Vec<Term<Name>> = vec![];
|
let mut arg_stack: Vec<Term<Name>> = vec![];
|
||||||
|
|
||||||
|
@ -2342,8 +2719,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} else if constructor.tipo.is_void() {
|
} else if constructor.tipo.is_void() {
|
||||||
arg_stack.push(Term::Constant(UplcConstant::Unit));
|
arg_stack.push(Term::Constant(UplcConstant::Unit));
|
||||||
} else {
|
} else {
|
||||||
let data_type =
|
let data_type = lookup_data_type_by_tipo(
|
||||||
self.lookup_data_type_by_tipo(&constructor.tipo).unwrap();
|
self.data_types.clone(),
|
||||||
|
&constructor.tipo,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let (constr_index, _) = data_type
|
let (constr_index, _) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
|
@ -3503,7 +3883,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
Air::Record {
|
Air::Record {
|
||||||
constr_index,
|
constr_index,
|
||||||
constr_type,
|
tipo,
|
||||||
count,
|
count,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
@ -3518,10 +3898,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
term = apply_wrap(
|
term = apply_wrap(
|
||||||
apply_wrap(
|
apply_wrap(
|
||||||
Term::Builtin(DefaultFunction::MkCons).force_wrap(),
|
Term::Builtin(DefaultFunction::MkCons).force_wrap(),
|
||||||
convert_type_to_data(
|
convert_type_to_data(arg.clone(), &tipo.arg_types().unwrap()[index]),
|
||||||
arg.clone(),
|
|
||||||
&constr_type.arg_types().unwrap()[index],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
term,
|
term,
|
||||||
);
|
);
|
||||||
|
@ -4272,35 +4649,4 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_data_type_by_tipo(&self, tipo: &Type) -> Option<&&DataType<Arc<Type>>> {
|
|
||||||
match tipo {
|
|
||||||
Type::Fn { ret, .. } => match ret.as_ref() {
|
|
||||||
Type::App { module, name, .. } => {
|
|
||||||
let data_type_key = DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
};
|
|
||||||
self.data_types.get(&data_type_key)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
Type::App { module, name, .. } => {
|
|
||||||
let data_type_key = DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.data_types.get(&data_type_key)
|
|
||||||
}
|
|
||||||
Type::Var { tipo } => {
|
|
||||||
if let TypeVar::Link { tipo } = &*tipo.borrow() {
|
|
||||||
self.lookup_data_type_by_tipo(tipo)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue