feat: fix up generic type functions to work with the new air tree functions
chore: remove commented code
This commit is contained in:
parent
b3714ca9d0
commit
fd83c9a739
|
@ -2010,12 +2010,18 @@ pub fn special_case_builtin(
|
||||||
|
|
||||||
pub fn get_arg_type_name(tipo: &Type) -> String {
|
pub fn get_arg_type_name(tipo: &Type) -> String {
|
||||||
match tipo {
|
match tipo {
|
||||||
Type::App { name, .. } => name.clone(),
|
Type::App { name, args, .. } => {
|
||||||
|
let inner_args = args.iter().map(|arg| get_arg_type_name(arg)).collect_vec();
|
||||||
|
format!("{}_{}", name, inner_args.join("_"))
|
||||||
|
}
|
||||||
Type::Var { tipo } => match tipo.borrow().clone() {
|
Type::Var { tipo } => match tipo.borrow().clone() {
|
||||||
TypeVar::Link { tipo } => get_arg_type_name(tipo.as_ref()),
|
TypeVar::Link { tipo } => get_arg_type_name(tipo.as_ref()),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
Type::Tuple { .. } => "".to_string(),
|
Type::Tuple { elems } => {
|
||||||
|
let inner_args = elems.iter().map(|arg| get_arg_type_name(arg)).collect_vec();
|
||||||
|
inner_args.join("_")
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ use crate::{
|
||||||
gen_uplc::{
|
gen_uplc::{
|
||||||
air::Air,
|
air::Air,
|
||||||
builder::{
|
builder::{
|
||||||
self as build, AssignmentProperties, ClauseProperties, DataTypeKey, FunctionAccessKey,
|
self as build, get_arg_type_name, AssignmentProperties, ClauseProperties, DataTypeKey,
|
||||||
SpecificClause,
|
FunctionAccessKey, SpecificClause,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gen_uplc2::builder::convert_opaque_type,
|
gen_uplc2::builder::convert_opaque_type,
|
||||||
|
@ -106,7 +106,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
fn build(&mut self, body: &TypedExpr) -> AirTree {
|
fn build(&mut self, body: &TypedExpr) -> AirTree {
|
||||||
match body {
|
match body {
|
||||||
TypedExpr::Int { value, .. } => AirTree::int(value),
|
TypedExpr::UInt { value, .. } => AirTree::int(value),
|
||||||
TypedExpr::String { value, .. } => AirTree::string(value),
|
TypedExpr::String { value, .. } => AirTree::string(value),
|
||||||
TypedExpr::ByteArray { bytes, .. } => AirTree::byte_array(bytes.clone()),
|
TypedExpr::ByteArray { bytes, .. } => AirTree::byte_array(bytes.clone()),
|
||||||
TypedExpr::Sequence { expressions, .. } | TypedExpr::Pipeline { expressions, .. } => {
|
TypedExpr::Sequence { expressions, .. } | TypedExpr::Pipeline { expressions, .. } => {
|
||||||
|
@ -544,7 +544,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
if props.full_check {
|
if props.full_check {
|
||||||
let mut index_map = IndexMap::new();
|
let mut index_map = IndexMap::new();
|
||||||
// let tipo = builder::convert_opaque_type();
|
let tipo = convert_opaque_type(tipo, &self.data_types);
|
||||||
let assignment = AirTree::let_assignment(name, value);
|
let assignment = AirTree::let_assignment(name, value);
|
||||||
let val = AirTree::local_var(name, tipo.clone());
|
let val = AirTree::local_var(name, tipo.clone());
|
||||||
|
|
||||||
|
@ -552,7 +552,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::let_assignment(name, assignment.hoist_over(val))
|
AirTree::let_assignment(name, assignment.hoist_over(val))
|
||||||
} else {
|
} else {
|
||||||
let expect = self.expect_type_assign(
|
let expect = self.expect_type_assign(
|
||||||
tipo,
|
&tipo,
|
||||||
val.clone(),
|
val.clone(),
|
||||||
&mut index_map,
|
&mut index_map,
|
||||||
pattern.location(),
|
pattern.location(),
|
||||||
|
@ -575,14 +575,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
if props.full_check {
|
if props.full_check {
|
||||||
let name = &format!("__discard_expect_{}", name);
|
let name = &format!("__discard_expect_{}", name);
|
||||||
let mut index_map = IndexMap::new();
|
let mut index_map = IndexMap::new();
|
||||||
// let tipo = builder::convert_opaque_type();
|
let tipo = convert_opaque_type(tipo, &self.data_types);
|
||||||
let assignment = AirTree::let_assignment(name, value);
|
let assignment = AirTree::let_assignment(name, value);
|
||||||
let val = AirTree::local_var(name, tipo.clone());
|
let val = AirTree::local_var(name, tipo.clone());
|
||||||
if tipo.is_primitive() {
|
if tipo.is_primitive() {
|
||||||
AirTree::let_assignment(name, assignment.hoist_over(val))
|
AirTree::let_assignment(name, assignment.hoist_over(val))
|
||||||
} else {
|
} else {
|
||||||
let expect = self.expect_type_assign(
|
let expect = self.expect_type_assign(
|
||||||
tipo,
|
&tipo,
|
||||||
val.clone(),
|
val.clone(),
|
||||||
&mut index_map,
|
&mut index_map,
|
||||||
pattern.location(),
|
pattern.location(),
|
||||||
|
@ -1131,15 +1131,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
unreachable!("We need a data type definition fot type {:#?}", tipo)
|
unreachable!("We need a data type definition fot type {:#?}", tipo)
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut tipo = convert_opaque_type();
|
let mut data_type_variant = tipo
|
||||||
|
.get_inner_types()
|
||||||
// for (index, arg) in tipo.arg_types().unwrap().iter().enumerate() {
|
.iter()
|
||||||
// let field_type = arg.clone();
|
.map(|arg| get_arg_type_name(arg))
|
||||||
// type_map.insert(index, field_type);
|
.join("_");
|
||||||
// }
|
|
||||||
|
|
||||||
// TODO calculate the variant name.
|
// TODO calculate the variant name.
|
||||||
let data_type_name = format!("__expect_{}{}", data_type.name, "");
|
let data_type_name = format!("__expect_{}_{}", data_type.name, data_type_variant);
|
||||||
let function = self.code_gen_functions.get(&data_type_name);
|
let function = self.code_gen_functions.get(&data_type_name);
|
||||||
todo!();
|
todo!();
|
||||||
if function.is_none() && defined_data_types.get(&data_type_name).is_none() {
|
if function.is_none() && defined_data_types.get(&data_type_name).is_none() {
|
||||||
|
@ -1152,7 +1151,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let func_var = AirTree::var(
|
let func_var = AirTree::var(
|
||||||
ValueConstructor::public(
|
ValueConstructor::public(
|
||||||
tipo,
|
tipo.clone(),
|
||||||
ValueConstructorVariant::ModuleFn {
|
ValueConstructorVariant::ModuleFn {
|
||||||
name: data_type_name.to_string(),
|
name: data_type_name.to_string(),
|
||||||
field_map: None,
|
field_map: None,
|
||||||
|
@ -1846,7 +1845,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Discard { .. } => AirTree::no_op(),
|
Pattern::Discard { .. } => AirTree::no_op(),
|
||||||
Pattern::List { elements, tail, .. } => {
|
Pattern::List { elements, tail, .. } => {
|
||||||
props.complex_clause = true;
|
props.complex_clause = true;
|
||||||
// let item_name = format!("__list_item_id_{}", self.id_gen.next());
|
|
||||||
let tail_name_base = "__tail".to_string();
|
let tail_name_base = "__tail".to_string();
|
||||||
|
|
||||||
if elements.is_empty() {
|
if elements.is_empty() {
|
||||||
|
@ -1881,18 +1879,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
format!("{}_{}", tail_name_base, index - 1)
|
format!("{}_{}", tail_name_base, index - 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
// let mut clause_properties = ClauseProperties {
|
|
||||||
// clause_var_name: item_name.clone(),
|
|
||||||
// needs_constr_var: false,
|
|
||||||
// complex_clause: false,
|
|
||||||
// original_subject_name: item_name.clone(),
|
|
||||||
// specific_clause: SpecificClause::ListClause {
|
|
||||||
// current_index: index as i64,
|
|
||||||
// defined_tails: vec![],
|
|
||||||
// },
|
|
||||||
// final_clause,
|
|
||||||
// };
|
|
||||||
|
|
||||||
let tail_name = format!("{tail_name_base}_{index}");
|
let tail_name = format!("{tail_name_base}_{index}");
|
||||||
|
|
||||||
if elements.len() - 1 == index {
|
if elements.len() - 1 == index {
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
use crate::builtins::bool;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ast::TypedDataType,
|
||||||
|
builtins::bool,
|
||||||
|
gen_uplc::builder::{lookup_data_type_by_tipo, DataTypeKey},
|
||||||
|
tipo::TypeVar,
|
||||||
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -8,8 +15,183 @@ use crate::{
|
||||||
|
|
||||||
use super::tree::AirTree;
|
use super::tree::AirTree;
|
||||||
|
|
||||||
pub fn convert_opaque_type() -> Arc<Type> {
|
pub fn get_generic_id_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
|
||||||
todo!()
|
let mut generics_ids = vec![];
|
||||||
|
|
||||||
|
if let Some(id) = tipo.get_generic() {
|
||||||
|
generics_ids.push((id, param.clone().into()));
|
||||||
|
return generics_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tipo, param_type) in tipo
|
||||||
|
.get_inner_types()
|
||||||
|
.iter()
|
||||||
|
.zip(param.get_inner_types().iter())
|
||||||
|
{
|
||||||
|
generics_ids.append(&mut get_generic_id_and_type(tipo, param_type));
|
||||||
|
}
|
||||||
|
generics_ids
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_opaque_type(
|
||||||
|
t: &Arc<Type>,
|
||||||
|
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
||||||
|
) -> Arc<Type> {
|
||||||
|
if check_replaceable_opaque_type(t, data_types) && matches!(t.as_ref(), Type::App { .. }) {
|
||||||
|
let data_type = lookup_data_type_by_tipo(data_types, t).unwrap();
|
||||||
|
let new_type_fields = data_type.typed_parameters;
|
||||||
|
|
||||||
|
let mono_types: IndexMap<u64, Arc<Type>>;
|
||||||
|
let mut mono_type_vec = vec![];
|
||||||
|
|
||||||
|
for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) {
|
||||||
|
mono_type_vec.append(&mut get_generic_id_and_type(tipo, ¶m));
|
||||||
|
}
|
||||||
|
mono_types = mono_type_vec.into_iter().collect();
|
||||||
|
|
||||||
|
let generic_type = &data_type.constructors[0].arguments[0].tipo;
|
||||||
|
|
||||||
|
let mono_type = find_and_replace_generics(generic_type, &mono_types);
|
||||||
|
|
||||||
|
convert_opaque_type(&mono_type, data_types)
|
||||||
|
} else {
|
||||||
|
match t.as_ref() {
|
||||||
|
Type::App {
|
||||||
|
public,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
} => {
|
||||||
|
let mut new_args = vec![];
|
||||||
|
for arg in args {
|
||||||
|
let arg = convert_opaque_type(arg, data_types);
|
||||||
|
new_args.push(arg);
|
||||||
|
}
|
||||||
|
Type::App {
|
||||||
|
public: *public,
|
||||||
|
module: module.clone(),
|
||||||
|
name: name.clone(),
|
||||||
|
args: new_args,
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
Type::Fn { args, ret } => {
|
||||||
|
let mut new_args = vec![];
|
||||||
|
for arg in args {
|
||||||
|
let arg = convert_opaque_type(arg, data_types);
|
||||||
|
new_args.push(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ret = convert_opaque_type(ret, data_types);
|
||||||
|
|
||||||
|
Type::Fn {
|
||||||
|
args: new_args,
|
||||||
|
ret,
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
Type::Var { tipo: var_tipo } => {
|
||||||
|
if let TypeVar::Link { tipo } = &var_tipo.borrow().clone() {
|
||||||
|
convert_opaque_type(tipo, data_types)
|
||||||
|
} else {
|
||||||
|
t.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Type::Tuple { elems } => {
|
||||||
|
let mut new_elems = vec![];
|
||||||
|
for arg in elems {
|
||||||
|
let arg = convert_opaque_type(arg, data_types);
|
||||||
|
new_elems.push(arg);
|
||||||
|
}
|
||||||
|
Type::Tuple { elems: new_elems }.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_replaceable_opaque_type(
|
||||||
|
t: &Arc<Type>,
|
||||||
|
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
||||||
|
) -> bool {
|
||||||
|
let data_type = lookup_data_type_by_tipo(data_types, t);
|
||||||
|
|
||||||
|
if let Some(data_type) = data_type {
|
||||||
|
let data_type_args = &data_type.constructors[0].arguments;
|
||||||
|
data_type_args.len() == 1 && data_type.opaque && data_type.constructors.len() == 1
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_and_replace_generics(
|
||||||
|
tipo: &Arc<Type>,
|
||||||
|
mono_types: &IndexMap<u64, Arc<Type>>,
|
||||||
|
) -> Arc<Type> {
|
||||||
|
if let Some(id) = tipo.get_generic() {
|
||||||
|
// If a generic does not have a type we know of
|
||||||
|
// like a None in option then just use same type
|
||||||
|
mono_types.get(&id).unwrap_or(tipo).clone()
|
||||||
|
} else if tipo.is_generic() {
|
||||||
|
match &**tipo {
|
||||||
|
Type::App {
|
||||||
|
args,
|
||||||
|
public,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
} => {
|
||||||
|
let mut new_args = vec![];
|
||||||
|
for arg in args {
|
||||||
|
let arg = find_and_replace_generics(arg, mono_types);
|
||||||
|
new_args.push(arg);
|
||||||
|
}
|
||||||
|
let t = Type::App {
|
||||||
|
args: new_args,
|
||||||
|
public: *public,
|
||||||
|
module: module.clone(),
|
||||||
|
name: name.clone(),
|
||||||
|
};
|
||||||
|
t.into()
|
||||||
|
}
|
||||||
|
Type::Fn { args, ret } => {
|
||||||
|
let mut new_args = vec![];
|
||||||
|
for arg in args {
|
||||||
|
let arg = find_and_replace_generics(arg, mono_types);
|
||||||
|
new_args.push(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ret = find_and_replace_generics(ret, mono_types);
|
||||||
|
|
||||||
|
let t = Type::Fn {
|
||||||
|
args: new_args,
|
||||||
|
ret,
|
||||||
|
};
|
||||||
|
|
||||||
|
t.into()
|
||||||
|
}
|
||||||
|
Type::Tuple { elems } => {
|
||||||
|
let mut new_elems = vec![];
|
||||||
|
for elem in elems {
|
||||||
|
let elem = find_and_replace_generics(elem, mono_types);
|
||||||
|
new_elems.push(elem);
|
||||||
|
}
|
||||||
|
let t = Type::Tuple { elems: new_elems };
|
||||||
|
t.into()
|
||||||
|
}
|
||||||
|
Type::Var { tipo: var_tipo } => {
|
||||||
|
let var_type = var_tipo.as_ref().borrow().clone();
|
||||||
|
|
||||||
|
match var_type {
|
||||||
|
TypeVar::Link { tipo } => {
|
||||||
|
find_and_replace_generics(&tipo, mono_types);
|
||||||
|
tipo
|
||||||
|
}
|
||||||
|
TypeVar::Generic { .. } | TypeVar::Unbound { .. } => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tipo.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constants_ir(literal: &Constant) -> AirTree {
|
pub fn constants_ir(literal: &Constant) -> AirTree {
|
||||||
|
|
Loading…
Reference in New Issue