some refactoring and adding assert on lists
This commit is contained in:
parent
d4eec1fe79
commit
fc88028034
|
@ -107,6 +107,11 @@ pub enum Air {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
UnWrapData {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
|
||||||
ListAssert {
|
ListAssert {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
@ -271,6 +276,7 @@ impl Air {
|
||||||
| Air::Assert { scope, .. }
|
| Air::Assert { scope, .. }
|
||||||
| Air::ListAssert { scope, .. }
|
| Air::ListAssert { scope, .. }
|
||||||
| Air::Let { scope, .. }
|
| Air::Let { scope, .. }
|
||||||
|
| Air::UnWrapData { scope, .. }
|
||||||
| Air::When { scope, .. }
|
| Air::When { scope, .. }
|
||||||
| Air::Clause { scope, .. }
|
| Air::Clause { scope, .. }
|
||||||
| Air::ListClause { scope, .. }
|
| Air::ListClause { scope, .. }
|
||||||
|
@ -350,6 +356,7 @@ impl Air {
|
||||||
| Air::BinOp { tipo, .. }
|
| Air::BinOp { tipo, .. }
|
||||||
| Air::Assert { tipo, .. }
|
| Air::Assert { tipo, .. }
|
||||||
| Air::ListAssert { tipo, .. }
|
| Air::ListAssert { tipo, .. }
|
||||||
|
| Air::UnWrapData { tipo, .. }
|
||||||
| Air::When { tipo, .. }
|
| Air::When { tipo, .. }
|
||||||
| Air::Clause { tipo, .. }
|
| Air::Clause { tipo, .. }
|
||||||
| Air::ListClause { tipo, .. }
|
| Air::ListClause { tipo, .. }
|
||||||
|
|
|
@ -14,7 +14,7 @@ use uplc::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
air::Air,
|
air::Air,
|
||||||
ast::{Clause, Constant, DataType, Pattern, Span, TypedArg, TypedDataType},
|
ast::{AssignmentKind, Clause, Constant, DataType, Pattern, Span, TypedArg, TypedDataType},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant},
|
tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant},
|
||||||
};
|
};
|
||||||
|
@ -48,6 +48,12 @@ pub struct FunctionAccessKey {
|
||||||
pub variant_name: String,
|
pub variant_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct AssignmentProperties {
|
||||||
|
pub value_is_data: bool,
|
||||||
|
pub kind: AssignmentKind,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ClauseProperties {
|
pub enum ClauseProperties {
|
||||||
ConstrClause {
|
ConstrClause {
|
||||||
|
@ -1133,8 +1139,15 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO check on assignment if type is needed
|
Air::UnWrapData { scope, tipo } => {
|
||||||
Air::Let { .. } => {}
|
if tipo.is_generic() {
|
||||||
|
let mut tipo = tipo.clone();
|
||||||
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
|
new_air[index] = Air::UnWrapData { scope, tipo };
|
||||||
|
needs_variant = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Air::When {
|
Air::When {
|
||||||
scope,
|
scope,
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -1673,5 +1686,3 @@ pub fn replace_opaque_type(t: &mut Arc<Type>, data_types: IndexMap<DataTypeKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recursive_assert(tipo: &Type, assert_vec: &mut Vec<Air>) {}
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ use uplc::{
|
||||||
ast::{
|
ast::{
|
||||||
builder::{
|
builder::{
|
||||||
self, apply_wrap, choose_list, constr_index_exposer, delayed_choose_list,
|
self, apply_wrap, choose_list, constr_index_exposer, delayed_choose_list,
|
||||||
delayed_if_else, if_else, repeat_tail_list, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD,
|
delayed_if_else, if_else, repeat_tail_list, ASSERT_ON_LIST, CONSTR_FIELDS_EXPOSER,
|
||||||
|
CONSTR_GET_FIELD,
|
||||||
},
|
},
|
||||||
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
||||||
},
|
},
|
||||||
|
@ -26,12 +27,12 @@ use crate::{
|
||||||
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
|
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
|
||||||
get_generics_and_type, handle_func_dependencies_ir, handle_recursion_ir,
|
get_generics_and_type, handle_func_dependencies_ir, handle_recursion_ir,
|
||||||
list_access_to_uplc, lookup_data_type_by_tipo, monomorphize, rearrange_clauses,
|
list_access_to_uplc, lookup_data_type_by_tipo, monomorphize, rearrange_clauses,
|
||||||
recursive_assert, replace_opaque_type, wrap_validator_args, ClauseProperties, DataTypeKey,
|
replace_opaque_type, wrap_validator_args, AssignmentProperties, ClauseProperties,
|
||||||
FuncComponents, FunctionAccessKey,
|
DataTypeKey, FuncComponents, FunctionAccessKey,
|
||||||
},
|
},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
tipo::{
|
tipo::{
|
||||||
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
self, ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
||||||
ValueConstructorVariant,
|
ValueConstructorVariant,
|
||||||
},
|
},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
|
@ -45,6 +46,7 @@ pub struct CodeGenerator<'a> {
|
||||||
module_types: &'a IndexMap<String, TypeInfo>,
|
module_types: &'a IndexMap<String, TypeInfo>,
|
||||||
id_gen: IdGenerator,
|
id_gen: IdGenerator,
|
||||||
needs_field_access: bool,
|
needs_field_access: bool,
|
||||||
|
used_data_assert_on_list: bool,
|
||||||
zero_arg_functions: IndexMap<FunctionAccessKey, Vec<Air>>,
|
zero_arg_functions: IndexMap<FunctionAccessKey, Vec<Air>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +65,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
module_types,
|
module_types,
|
||||||
id_gen: IdGenerator::new(),
|
id_gen: IdGenerator::new(),
|
||||||
needs_field_access: false,
|
needs_field_access: false,
|
||||||
|
used_data_assert_on_list: false,
|
||||||
zero_arg_functions: IndexMap::new(),
|
zero_arg_functions: IndexMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +107,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
term = wrap_validator_args(term, arguments);
|
term = wrap_validator_args(term, arguments);
|
||||||
|
|
||||||
|
term = if wrap_as_validator || self.used_data_assert_on_list {
|
||||||
|
builder::assert_on_list(term)
|
||||||
|
} else {
|
||||||
|
term
|
||||||
|
};
|
||||||
|
|
||||||
let mut program = Program {
|
let mut program = Program {
|
||||||
version: (1, 0, 0),
|
version: (1, 0, 0),
|
||||||
term,
|
term,
|
||||||
|
@ -300,8 +309,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut pattern_vec,
|
&mut pattern_vec,
|
||||||
&mut value_vec,
|
&mut value_vec,
|
||||||
tipo,
|
tipo,
|
||||||
value_is_data,
|
AssignmentProperties {
|
||||||
*kind,
|
value_is_data,
|
||||||
|
kind: *kind,
|
||||||
|
},
|
||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1459,142 +1470,141 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec: &mut Vec<Air>,
|
pattern_vec: &mut Vec<Air>,
|
||||||
value_vec: &mut Vec<Air>,
|
value_vec: &mut Vec<Air>,
|
||||||
tipo: &Type,
|
tipo: &Type,
|
||||||
value_is_data: bool,
|
assignment_properties: AssignmentProperties,
|
||||||
kind: AssignmentKind,
|
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
|
if assignment_properties.value_is_data && !tipo.is_data() {
|
||||||
|
value_vec.insert(
|
||||||
|
0,
|
||||||
|
Air::UnWrapData {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Int { .. } | Pattern::String { .. } => unreachable!(),
|
Pattern::Int { .. } | Pattern::String { .. } => unreachable!(),
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
let mut assert_vec = vec![];
|
pattern_vec.push(Air::Let {
|
||||||
|
name: name.clone(),
|
||||||
if matches!(kind, AssignmentKind::Assert) {
|
scope: scope.clone(),
|
||||||
if value_is_data && !tipo.is_data() {
|
});
|
||||||
recursive_assert(tipo, &mut assert_vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Assert {
|
|
||||||
scope,
|
|
||||||
tipo: tipo.clone().into(),
|
|
||||||
value_is_data,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
pattern_vec.push(Air::Let {
|
|
||||||
name: name.clone(),
|
|
||||||
scope,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern_vec.append(value_vec);
|
pattern_vec.append(value_vec);
|
||||||
pattern_vec.append(&mut assert_vec);
|
|
||||||
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
|
&& assignment_properties.value_is_data
|
||||||
|
&& !tipo.is_data()
|
||||||
|
{
|
||||||
|
let mut assert_vec = vec![];
|
||||||
|
self.recursive_assert_pattern(
|
||||||
|
pattern,
|
||||||
|
&mut assert_vec,
|
||||||
|
value_vec,
|
||||||
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
pattern_vec.append(&mut assert_vec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Pattern::VarUsage { .. } => todo!(),
|
Pattern::VarUsage { .. } => todo!(),
|
||||||
Pattern::Assign { .. } => todo!(),
|
Pattern::Assign { .. } => todo!(),
|
||||||
Pattern::Discard { .. } => {
|
Pattern::Discard { .. } => {
|
||||||
pattern_vec.push(Air::Let {
|
pattern_vec.push(Air::Let {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
scope,
|
scope: scope.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern_vec.append(value_vec);
|
pattern_vec.append(value_vec);
|
||||||
}
|
|
||||||
list @ Pattern::List { .. } => {
|
|
||||||
self.pattern_ir(
|
|
||||||
list,
|
|
||||||
pattern_vec,
|
|
||||||
value_vec,
|
|
||||||
tipo,
|
|
||||||
value_is_data,
|
|
||||||
kind,
|
|
||||||
scope,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Pattern::Constructor {
|
|
||||||
name: constr_name,
|
|
||||||
tipo,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo);
|
|
||||||
|
|
||||||
let (index, _) = data_type
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
.unwrap()
|
&& assignment_properties.value_is_data
|
||||||
.constructors
|
&& !tipo.is_data()
|
||||||
.iter()
|
{
|
||||||
.enumerate()
|
let mut assert_vec = vec![];
|
||||||
.find(|(_, dt)| &dt.name == constr_name)
|
self.recursive_assert_pattern(
|
||||||
.unwrap();
|
pattern,
|
||||||
match kind {
|
&mut assert_vec,
|
||||||
AssignmentKind::Let => {
|
value_vec,
|
||||||
self.pattern_ir(
|
tipo,
|
||||||
pattern,
|
assignment_properties,
|
||||||
pattern_vec,
|
scope,
|
||||||
value_vec,
|
);
|
||||||
tipo,
|
pattern_vec.append(&mut assert_vec);
|
||||||
value_is_data,
|
|
||||||
kind,
|
|
||||||
scope,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
AssignmentKind::Assert => {
|
|
||||||
let name_id = self.id_gen.next();
|
|
||||||
pattern_vec.push(Air::Let {
|
|
||||||
scope: scope.clone(),
|
|
||||||
name: format!("__constr_{}", name_id),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.append(value_vec);
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Assert {
|
|
||||||
scope: scope.clone(),
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
value_is_data,
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
|
||||||
scope: scope.clone(),
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
tipo.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: format!("__constr_{}", name_id),
|
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
|
||||||
|
|
||||||
self.pattern_ir(
|
|
||||||
pattern,
|
|
||||||
pattern_vec,
|
|
||||||
&mut vec![Air::Var {
|
|
||||||
scope: scope.clone(),
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
tipo.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: format!("__constr_{}", name_id),
|
|
||||||
variant_name: String::new(),
|
|
||||||
}],
|
|
||||||
tipo,
|
|
||||||
value_is_data,
|
|
||||||
kind,
|
|
||||||
scope,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
AssignmentKind::Check => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pattern::Tuple { .. } => {
|
list @ Pattern::List { .. } => {
|
||||||
self.pattern_ir(
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
pattern,
|
&& assignment_properties.value_is_data
|
||||||
pattern_vec,
|
&& !tipo.is_data()
|
||||||
value_vec,
|
{
|
||||||
tipo,
|
self.recursive_assert_pattern(
|
||||||
value_is_data,
|
list,
|
||||||
kind,
|
pattern_vec,
|
||||||
scope,
|
value_vec,
|
||||||
);
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.pattern_ir(
|
||||||
|
list,
|
||||||
|
pattern_vec,
|
||||||
|
value_vec,
|
||||||
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constr @ Pattern::Constructor { .. } => {
|
||||||
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
|
&& assignment_properties.value_is_data
|
||||||
|
&& !tipo.is_data()
|
||||||
|
{
|
||||||
|
self.recursive_assert_pattern(
|
||||||
|
constr,
|
||||||
|
pattern_vec,
|
||||||
|
value_vec,
|
||||||
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.pattern_ir(
|
||||||
|
constr,
|
||||||
|
pattern_vec,
|
||||||
|
value_vec,
|
||||||
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tuple @ Pattern::Tuple { .. } => {
|
||||||
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
|
&& assignment_properties.value_is_data
|
||||||
|
&& !tipo.is_data()
|
||||||
|
{
|
||||||
|
self.recursive_assert_pattern(
|
||||||
|
tuple,
|
||||||
|
pattern_vec,
|
||||||
|
value_vec,
|
||||||
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.pattern_ir(
|
||||||
|
tuple,
|
||||||
|
pattern_vec,
|
||||||
|
value_vec,
|
||||||
|
tipo,
|
||||||
|
assignment_properties,
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1605,8 +1615,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec: &mut Vec<Air>,
|
pattern_vec: &mut Vec<Air>,
|
||||||
values: &mut Vec<Air>,
|
values: &mut Vec<Air>,
|
||||||
tipo: &Type,
|
tipo: &Type,
|
||||||
value_is_data: bool,
|
assignment_properties: AssignmentProperties,
|
||||||
kind: AssignmentKind,
|
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match pattern {
|
match pattern {
|
||||||
|
@ -1618,8 +1627,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Discard { .. } => todo!(),
|
Pattern::Discard { .. } => todo!(),
|
||||||
Pattern::List { elements, tail, .. } => {
|
Pattern::List { elements, tail, .. } => {
|
||||||
let mut elements_vec = vec![];
|
let mut elements_vec = vec![];
|
||||||
|
|
||||||
let mut names = vec![];
|
let mut names = vec![];
|
||||||
|
|
||||||
for element in elements {
|
for element in elements {
|
||||||
match element {
|
match element {
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
|
@ -1651,8 +1660,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut elements_vec,
|
&mut elements_vec,
|
||||||
&mut var_vec,
|
&mut var_vec,
|
||||||
&tipo.get_inner_types()[0],
|
&tipo.get_inner_types()[0],
|
||||||
value_is_data,
|
assignment_properties.clone(),
|
||||||
kind,
|
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1668,7 +1676,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(kind, AssignmentKind::Assert) {
|
if matches!(&assignment_properties.kind, AssignmentKind::Assert) {
|
||||||
} else {
|
} else {
|
||||||
pattern_vec.push(Air::ListAccessor {
|
pattern_vec.push(Air::ListAccessor {
|
||||||
names,
|
names,
|
||||||
|
@ -1743,8 +1751,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant_name: String::new(),
|
variant_name: String::new(),
|
||||||
}],
|
}],
|
||||||
tipo,
|
tipo,
|
||||||
value_is_data,
|
assignment_properties.clone(),
|
||||||
kind,
|
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1811,8 +1818,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant_name: String::new(),
|
variant_name: String::new(),
|
||||||
}],
|
}],
|
||||||
tipo,
|
tipo,
|
||||||
value_is_data,
|
assignment_properties.clone(),
|
||||||
kind,
|
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1883,8 +1889,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut elements_vec,
|
&mut elements_vec,
|
||||||
&mut var_vec,
|
&mut var_vec,
|
||||||
&tipo.get_inner_types()[0],
|
&tipo.get_inner_types()[0],
|
||||||
value_is_data,
|
assignment_properties.clone(),
|
||||||
kind,
|
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1903,6 +1908,219 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn recursive_assert_pattern(
|
||||||
|
&mut self,
|
||||||
|
pattern: &Pattern<PatternConstructor, Arc<Type>>,
|
||||||
|
pattern_vec: &mut Vec<Air>,
|
||||||
|
value_vec: &mut Vec<Air>,
|
||||||
|
tipo: &Type,
|
||||||
|
assignment_properties: AssignmentProperties,
|
||||||
|
scope: Vec<u64>,
|
||||||
|
) {
|
||||||
|
match pattern {
|
||||||
|
Pattern::Int { .. } => unreachable!(),
|
||||||
|
Pattern::String { .. } => unreachable!(),
|
||||||
|
Pattern::Var { name, .. } => {
|
||||||
|
self.recursive_assert_tipo(tipo, pattern_vec, name, scope);
|
||||||
|
}
|
||||||
|
Pattern::VarUsage {
|
||||||
|
location,
|
||||||
|
name,
|
||||||
|
tipo,
|
||||||
|
} => todo!(),
|
||||||
|
Pattern::Assign {
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
pattern,
|
||||||
|
} => todo!(),
|
||||||
|
Pattern::Discard { name, location } => todo!(),
|
||||||
|
Pattern::List {
|
||||||
|
location,
|
||||||
|
elements,
|
||||||
|
tail,
|
||||||
|
} => todo!(),
|
||||||
|
Pattern::Constructor {
|
||||||
|
is_record,
|
||||||
|
location,
|
||||||
|
name,
|
||||||
|
arguments,
|
||||||
|
module,
|
||||||
|
constructor,
|
||||||
|
with_spread,
|
||||||
|
tipo,
|
||||||
|
} => todo!(),
|
||||||
|
Pattern::Tuple { location, elems } => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recursive_assert_tipo(
|
||||||
|
&mut self,
|
||||||
|
tipo: &Type,
|
||||||
|
assert_vec: &mut Vec<Air>,
|
||||||
|
name: &str,
|
||||||
|
scope: Vec<u64>,
|
||||||
|
) {
|
||||||
|
if tipo.is_bool()
|
||||||
|
|| tipo.is_bytearray()
|
||||||
|
|| tipo.is_int()
|
||||||
|
|| tipo.is_string()
|
||||||
|
|| tipo.is_void()
|
||||||
|
{
|
||||||
|
} else if tipo.is_map() {
|
||||||
|
self.used_data_assert_on_list = true;
|
||||||
|
let new_id = self.id_gen.next();
|
||||||
|
let id_pair = (self.id_gen.next(), self.id_gen.next());
|
||||||
|
let inner_list_type = &tipo.get_inner_types()[0];
|
||||||
|
let inner_pair_types = inner_list_type.get_inner_types();
|
||||||
|
|
||||||
|
assert_vec.push(Air::Call {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: 2,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Builtin {
|
||||||
|
scope: scope.clone(),
|
||||||
|
func: DefaultFunction::ChooseUnit,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Call {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: 3,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone().into(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: ASSERT_ON_LIST.to_string(),
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone().into(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: name.to_owned(),
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Fn {
|
||||||
|
scope: scope.clone(),
|
||||||
|
params: vec![format!("__pair_{}", new_id)],
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::TupleAccessor {
|
||||||
|
scope: scope.clone(),
|
||||||
|
names: vec![
|
||||||
|
format!("__pair_fst_{}", id_pair.0),
|
||||||
|
format!("__pair_snd_{}", id_pair.1),
|
||||||
|
],
|
||||||
|
tipo: inner_list_type.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.recursive_assert_tipo(
|
||||||
|
&inner_pair_types[0],
|
||||||
|
assert_vec,
|
||||||
|
&format!("__pair_fst_{}", id_pair.0),
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.recursive_assert_tipo(
|
||||||
|
&inner_pair_types[1],
|
||||||
|
assert_vec,
|
||||||
|
&format!("__pair_snd_{}", id_pair.1),
|
||||||
|
scope,
|
||||||
|
);
|
||||||
|
} else if tipo.is_list() {
|
||||||
|
self.used_data_assert_on_list = true;
|
||||||
|
let new_id = self.id_gen.next();
|
||||||
|
let id_pair = (self.id_gen.next(), self.id_gen.next());
|
||||||
|
let inner_list_type = &tipo.get_inner_types()[0];
|
||||||
|
let inner_pair_types = inner_list_type.get_inner_types();
|
||||||
|
|
||||||
|
assert_vec.push(Air::Call {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: 2,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Builtin {
|
||||||
|
scope: scope.clone(),
|
||||||
|
func: DefaultFunction::ChooseUnit,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Call {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: 3,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone().into(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: ASSERT_ON_LIST.to_string(),
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone().into(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: name.to_owned(),
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::Fn {
|
||||||
|
scope: scope.clone(),
|
||||||
|
params: vec![format!("__list_item_{}", new_id)],
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_vec.push(Air::TupleAccessor {
|
||||||
|
scope: scope.clone(),
|
||||||
|
names: vec![
|
||||||
|
format!("__pair_fst_{}", id_pair.0),
|
||||||
|
format!("__pair_snd_{}", id_pair.1),
|
||||||
|
],
|
||||||
|
tipo: inner_list_type.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.recursive_assert_tipo(
|
||||||
|
&inner_pair_types[0],
|
||||||
|
assert_vec,
|
||||||
|
&format!("__pair_fst_{}", id_pair.0),
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.recursive_assert_tipo(
|
||||||
|
&inner_pair_types[1],
|
||||||
|
assert_vec,
|
||||||
|
&format!("__pair_snd_{}", id_pair.1),
|
||||||
|
scope,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn define_ir(&mut self, ir_stack: &mut Vec<Air>) {
|
fn define_ir(&mut self, ir_stack: &mut Vec<Air>) {
|
||||||
let mut func_components = IndexMap::new();
|
let mut func_components = IndexMap::new();
|
||||||
let mut func_index_map = IndexMap::new();
|
let mut func_index_map = IndexMap::new();
|
||||||
|
@ -2760,6 +2978,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo: replaced_type,
|
tipo: replaced_type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Air::UnWrapData { scope, tipo } => {
|
||||||
|
let mut replaced_type = tipo.clone();
|
||||||
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
|
ir_stack[index] = Air::UnWrapData {
|
||||||
|
scope,
|
||||||
|
tipo: replaced_type,
|
||||||
|
};
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3692,6 +3919,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
Air::UnWrapData { scope, tipo } => todo!(),
|
||||||
Air::When {
|
Air::When {
|
||||||
subject_name, tipo, ..
|
subject_name, tipo, ..
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use super::{Constant, Name, Term};
|
||||||
pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
||||||
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
||||||
pub const CONSTR_GET_FIELD: &str = "__constr_get_field";
|
pub const CONSTR_GET_FIELD: &str = "__constr_get_field";
|
||||||
|
pub const ASSERT_ON_LIST: &str = "__assert_on_list";
|
||||||
|
|
||||||
pub fn apply_wrap(function: Term<Name>, arg: Term<Name>) -> Term<Name> {
|
pub fn apply_wrap(function: Term<Name>, arg: Term<Name>) -> Term<Name> {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
|
@ -31,6 +32,108 @@ pub fn final_wrapper(term: Term<Name>) -> Term<Name> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assert_on_list(term: Term<Name>) -> Term<Name> {
|
||||||
|
apply_wrap(
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: apply_wrap(
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: term.into(),
|
||||||
|
},
|
||||||
|
apply_wrap(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
},
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: "list_to_check".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: "check_with".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: delayed_choose_list(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "list_to_check".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Constant(Constant::Unit),
|
||||||
|
apply_wrap(
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::ChooseUnit).force_wrap(),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "check_with".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::HeadList).force_wrap(),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "list_to_check".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
apply_wrap(
|
||||||
|
apply_wrap(
|
||||||
|
apply_wrap(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: ASSERT_ON_LIST.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::TailList).force_wrap(),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "list_to_check".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "check_with".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> {
|
pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
|
|
Loading…
Reference in New Issue