feat: refactor some methods and modules

* move uplc::ast::builder to uplc::builder
* rename aiken_lang::uplc to aiken_lang::gen_uplc
* move aiken_lang::air and aiken_lang::builder to aiken_lang::gen_uplc
  as submodules

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
rvcas 2023-03-21 17:12:01 -04:00 committed by Lucas
parent 2d77ec1a6a
commit 3e6f688e2d
13 changed files with 354 additions and 304 deletions

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
ast::{Arg, ArgName, CallArg, Function, ModuleKind, Span, TypedDataType, TypedFunction, UnOp}, ast::{Arg, ArgName, CallArg, Function, ModuleKind, Span, TypedDataType, TypedFunction, UnOp},
builder::{DataTypeKey, FunctionAccessKey},
expr::TypedExpr, expr::TypedExpr,
gen_uplc::builder::{DataTypeKey, FunctionAccessKey},
tipo::{ tipo::{
fields::FieldMap, Type, TypeConstructor, TypeInfo, TypeVar, ValueConstructor, fields::FieldMap, Type, TypeConstructor, TypeInfo, TypeVar, ValueConstructor,
ValueConstructorVariant, ValueConstructorVariant,

View File

@ -3,13 +3,8 @@ use std::sync::Arc;
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use itertools::Itertools; use itertools::Itertools;
use uplc::{ use uplc::{
ast::{ ast::{Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType},
builder::{ builder::{ASSERT_ON_LIST, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD, CONSTR_INDEX_EXPOSER},
self, assert_on_list, final_wrapper, repeat_tail_list, ASSERT_ON_LIST,
CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD, CONSTR_INDEX_EXPOSER,
},
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
},
builtins::DefaultFunction, builtins::DefaultFunction,
machine::cost_model::ExBudget, machine::cost_model::ExBudget,
optimize::aiken_optimize_and_intern, optimize::aiken_optimize_and_intern,
@ -17,19 +12,10 @@ use uplc::{
}; };
use crate::{ use crate::{
air::Air,
ast::{ ast::{
ArgName, AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction, ArgName, AssignmentKind, BinOp, Pattern, Span, TypedClause, TypedDataType, TypedFunction,
TypedValidator, UnOp, TypedValidator, UnOp,
}, },
builder::{
check_replaceable_opaque_type, check_when_pattern_needs, constants_ir,
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
get_generic_id_and_type, handle_clause_guard, handle_func_dependencies_ir,
handle_recursion_ir, list_access_to_uplc, lookup_data_type_by_tipo, monomorphize,
rearrange_clauses, replace_opaque_type, wrap_as_multi_validator, wrap_validator_args,
AssignmentProperties, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
},
builtins::bool, builtins::bool,
expr::TypedExpr, expr::TypedExpr,
tipo::{ tipo::{
@ -39,6 +25,15 @@ use crate::{
IdGenerator, IdGenerator,
}; };
pub mod air;
pub mod builder;
pub mod stack;
use air::Air;
use builder::{
AssignmentProperties, ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
};
#[derive(Clone)] #[derive(Clone)]
pub struct CodeGenerator<'a> { pub struct CodeGenerator<'a> {
defined_functions: IndexMap<FunctionAccessKey, ()>, defined_functions: IndexMap<FunctionAccessKey, ()>,
@ -98,9 +93,9 @@ impl<'a> CodeGenerator<'a> {
let mut term = self.uplc_code_gen(&mut ir_stack); let mut term = self.uplc_code_gen(&mut ir_stack);
// Wrap the validator body if ifThenElse term unit error // Wrap the validator body if ifThenElse term unit error
term = final_wrapper(term); term = term.final_wrapper();
term = wrap_validator_args(term, &fun.arguments); term = builder::wrap_validator_args(term, &fun.arguments);
if let Some(other) = other_fun { if let Some(other) = other_fun {
self.reset(); self.reset();
@ -117,9 +112,9 @@ impl<'a> CodeGenerator<'a> {
let other_term = self.uplc_code_gen(&mut other_ir_stack); let other_term = self.uplc_code_gen(&mut other_ir_stack);
let other_term = final_wrapper(other_term); let other_term = other_term.final_wrapper();
let other_term = wrap_validator_args(other_term, &other.arguments); let other_term = builder::wrap_validator_args(other_term, &other.arguments);
let (spend, mint) = if other.arguments.len() > fun.arguments.len() { let (spend, mint) = if other.arguments.len() > fun.arguments.len() {
(other_term, term) (other_term, term)
@ -127,11 +122,11 @@ impl<'a> CodeGenerator<'a> {
(term, other_term) (term, other_term)
}; };
term = wrap_as_multi_validator(spend, mint); term = builder::wrap_as_multi_validator(spend, mint);
self.needs_field_access = true; self.needs_field_access = true;
} }
term = wrap_validator_args(term, params); term = builder::wrap_validator_args(term, params);
self.finalize(term, true) self.finalize(term, true)
} }
@ -153,17 +148,16 @@ impl<'a> CodeGenerator<'a> {
fn finalize(&mut self, term: Term<Name>, wrap_as_validator: bool) -> Program<Name> { fn finalize(&mut self, term: Term<Name>, wrap_as_validator: bool) -> Program<Name> {
let mut term = if wrap_as_validator || self.used_data_assert_on_list { let mut term = if wrap_as_validator || self.used_data_assert_on_list {
assert_on_list(term) term.assert_on_list()
} else { } else {
term term
}; };
if self.needs_field_access { if self.needs_field_access {
term = builder::constr_get_field(term); term = term
.constr_get_field()
term = builder::constr_fields_exposer(term); .constr_fields_exposer()
.constr_index_exposer();
term = builder::constr_index_exposer(term);
} }
let mut program = Program { let mut program = Program {
@ -214,7 +208,7 @@ impl<'a> CodeGenerator<'a> {
constructor, name, .. constructor, name, ..
} => match &constructor.variant { } => match &constructor.variant {
ValueConstructorVariant::ModuleConstant { literal, .. } => { ValueConstructorVariant::ModuleConstant { literal, .. } => {
constants_ir(literal, ir_stack, scope); builder::constants_ir(literal, ir_stack, scope);
} }
ValueConstructorVariant::ModuleFn { ValueConstructorVariant::ModuleFn {
builtin: Some(builtin), builtin: Some(builtin),
@ -290,7 +284,7 @@ impl<'a> CodeGenerator<'a> {
name: constr_name, .. name: constr_name, ..
} => { } => {
if let Some(data_type) = if let Some(data_type) =
lookup_data_type_by_tipo(self.data_types.clone(), tipo) builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo)
{ {
let (constr_index, _) = data_type let (constr_index, _) = data_type
.constructors .constructors
@ -370,7 +364,7 @@ impl<'a> CodeGenerator<'a> {
.. ..
} => { } => {
if let Some(data_type) = if let Some(data_type) =
lookup_data_type_by_tipo(self.data_types.clone(), tipo) builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo)
{ {
let (constr_index, _) = data_type let (constr_index, _) = data_type
.constructors .constructors
@ -507,7 +501,7 @@ impl<'a> CodeGenerator<'a> {
value_scope.push(self.id_gen.next()); value_scope.push(self.id_gen.next());
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
self.build_ir(value, &mut value_vec, value_scope); self.build_ir(value, &mut value_vec, value_scope);
@ -558,7 +552,7 @@ impl<'a> CodeGenerator<'a> {
} else { } else {
// HERE TODO // HERE TODO
let clauses = if subject_tipo.is_list() { let clauses = if subject_tipo.is_list() {
rearrange_clauses(clauses.clone()) builder::rearrange_clauses(clauses.clone())
} else { } else {
clauses.clone() clauses.clone()
}; };
@ -762,7 +756,7 @@ impl<'a> CodeGenerator<'a> {
} }
} }
ModuleValueConstructor::Constant { literal, .. } => { ModuleValueConstructor::Constant { literal, .. } => {
constants_ir(literal, ir_stack, scope); builder::constants_ir(literal, ir_stack, scope);
} }
}, },
TypedExpr::RecordUpdate { TypedExpr::RecordUpdate {
@ -897,7 +891,7 @@ impl<'a> CodeGenerator<'a> {
name: clause_guard_name.clone(), name: clause_guard_name.clone(),
}); });
handle_clause_guard( builder::handle_clause_guard(
clause_guard, clause_guard,
&mut clause_guard_vec, &mut clause_guard_vec,
clause_guard_scope.clone(), clause_guard_scope.clone(),
@ -936,7 +930,8 @@ impl<'a> CodeGenerator<'a> {
clause_scope, clause_scope,
); );
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), subject_type); let data_type =
builder::lookup_data_type_by_tipo(self.data_types.clone(), subject_type);
if let Some(data_type) = data_type { if let Some(data_type) = data_type {
if data_type.constructors.len() > 1 { if data_type.constructors.len() > 1 {
@ -1172,11 +1167,11 @@ impl<'a> CodeGenerator<'a> {
} }
Pattern::List { elements, tail, .. } => { Pattern::List { elements, tail, .. } => {
for element in elements { for element in elements {
check_when_pattern_needs(element, clause_properties); builder::check_when_pattern_needs(element, clause_properties);
} }
if let Some(tail) = tail { if let Some(tail) = tail {
check_when_pattern_needs(tail, clause_properties); builder::check_when_pattern_needs(tail, clause_properties);
} }
*clause_properties.needs_constr_var() = false; *clause_properties.needs_constr_var() = false;
@ -1208,12 +1203,12 @@ impl<'a> CodeGenerator<'a> {
}); });
} else { } else {
for arg in arguments { for arg in arguments {
check_when_pattern_needs(&arg.value, &mut temp_clause_properties); builder::check_when_pattern_needs(&arg.value, &mut temp_clause_properties);
} }
// find data type definition // find data type definition
let data_type = let data_type =
lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
let (index, _) = data_type let (index, _) = data_type
.constructors .constructors
@ -1274,7 +1269,7 @@ impl<'a> CodeGenerator<'a> {
} }
Pattern::Tuple { elems, .. } => { Pattern::Tuple { elems, .. } => {
for elem in elems { for elem in elems {
check_when_pattern_needs(elem, clause_properties); builder::check_when_pattern_needs(elem, clause_properties);
} }
*clause_properties.needs_constr_var() = false; *clause_properties.needs_constr_var() = false;
@ -1396,7 +1391,8 @@ impl<'a> CodeGenerator<'a> {
tipo, tipo,
.. ..
} => { } => {
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); let data_type =
builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
let (_, constructor_type) = data_type let (_, constructor_type) = data_type
.constructors .constructors
@ -1708,7 +1704,8 @@ 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 = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); let data_type =
builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
if data_type.constructors.len() > 1 { if data_type.constructors.len() > 1 {
if final_clause { if final_clause {
@ -2144,7 +2141,8 @@ impl<'a> CodeGenerator<'a> {
pattern_vec.append(values); pattern_vec.append(values);
} else { } else {
let data_type = let data_type =
lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo)
.unwrap();
let (index, _) = data_type let (index, _) = data_type
.constructors .constructors
@ -2355,7 +2353,8 @@ impl<'a> CodeGenerator<'a> {
PatternConstructor::Record { field_map, .. } => field_map.clone().unwrap(), PatternConstructor::Record { field_map, .. } => field_map.clone().unwrap(),
}; };
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); let data_type =
builder::lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
let (index, data_type_constr) = data_type let (index, data_type_constr) = data_type
.constructors .constructors
@ -2539,7 +2538,7 @@ impl<'a> CodeGenerator<'a> {
scope: Vec<u64>, scope: Vec<u64>,
) { ) {
let mut tipo = tipo.clone().into(); let mut tipo = tipo.clone().into();
replace_opaque_type(&mut tipo, self.data_types.clone()); builder::replace_opaque_type(&mut tipo, self.data_types.clone());
if tipo.is_bool() if tipo.is_bool()
|| tipo.is_bytearray() || tipo.is_bytearray()
@ -2753,7 +2752,8 @@ impl<'a> CodeGenerator<'a> {
); );
} }
} else { } else {
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), &tipo).unwrap(); let data_type =
builder::lookup_data_type_by_tipo(self.data_types.clone(), &tipo).unwrap();
let new_id = self.id_gen.next(); let new_id = self.id_gen.next();
assert_vec.push(Air::Builtin { assert_vec.push(Air::Builtin {
@ -3096,7 +3096,7 @@ impl<'a> CodeGenerator<'a> {
if !function_component.args.is_empty() { if !function_component.args.is_empty() {
// deal with function dependencies // deal with function dependencies
handle_func_dependencies_ir( builder::handle_func_dependencies_ir(
&mut dep_ir, &mut dep_ir,
function_component, function_component,
&function_definitions, &function_definitions,
@ -3112,7 +3112,7 @@ impl<'a> CodeGenerator<'a> {
let mut defined_functions = IndexMap::new(); let mut defined_functions = IndexMap::new();
// deal with function dependencies in zero arg functions // deal with function dependencies in zero arg functions
handle_func_dependencies_ir( builder::handle_func_dependencies_ir(
&mut dep_ir, &mut dep_ir,
function_component, function_component,
&function_definitions, &function_definitions,
@ -3141,7 +3141,7 @@ impl<'a> CodeGenerator<'a> {
let funt_comp = function_definitions.get(&func.0).unwrap(); let funt_comp = function_definitions.get(&func.0).unwrap();
let func_scope = func_index_map.get(&func.0).unwrap(); let func_scope = func_index_map.get(&func.0).unwrap();
handle_func_dependencies_ir( builder::handle_func_dependencies_ir(
&mut dep_ir, &mut dep_ir,
funt_comp, funt_comp,
&function_definitions, &function_definitions,
@ -3170,7 +3170,7 @@ impl<'a> CodeGenerator<'a> {
.map(|scope| (func_key.clone(), scope.clone())) .map(|scope| (func_key.clone(), scope.clone()))
}) })
.filter(|func| { .filter(|func| {
get_common_ancestor(&func.1, &ir.scope()) == ir.scope() builder::get_common_ancestor(&func.1, &ir.scope()) == ir.scope()
&& !self.defined_functions.contains_key(&func.0) && !self.defined_functions.contains_key(&func.0)
&& !self.zero_arg_functions.contains_key(&func.0) && !self.zero_arg_functions.contains_key(&func.0)
&& !(*dependency_map.get(&func.0).unwrap()) && !(*dependency_map.get(&func.0).unwrap())
@ -3194,7 +3194,11 @@ impl<'a> CodeGenerator<'a> {
// zero arg functions are not recursive // zero arg functions are not recursive
if !func_comp.args.is_empty() { if !func_comp.args.is_empty() {
let mut recursion_ir = vec![]; let mut recursion_ir = vec![];
handle_recursion_ir(&function_access_key, &func_comp, &mut recursion_ir); builder::handle_recursion_ir(
&function_access_key,
&func_comp,
&mut recursion_ir,
);
full_func_ir.push(Air::DefineFunc { full_func_ir.push(Air::DefineFunc {
scope: scopes.clone(), scope: scopes.clone(),
@ -3316,7 +3320,7 @@ impl<'a> CodeGenerator<'a> {
for item in inner_func_index_map { for item in inner_func_index_map {
if let Some(entry) = func_index_map.get_mut(&item.0) { if let Some(entry) = func_index_map.get_mut(&item.0) {
*entry = get_common_ancestor(entry, &item.1); *entry = builder::get_common_ancestor(entry, &item.1);
} else { } else {
func_index_map.insert(item.0, item.1); func_index_map.insert(item.0, item.1);
} }
@ -3366,20 +3370,25 @@ impl<'a> CodeGenerator<'a> {
if arg.tipo.is_generic() { if arg.tipo.is_generic() {
let param_type = &param_types[index]; let param_type = &param_types[index];
map.append(&mut get_generic_id_and_type(&arg.tipo, param_type)); map.append(&mut builder::get_generic_id_and_type(
&arg.tipo, param_type,
));
} }
} }
if function.return_type.is_generic() { if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo { if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut get_generic_id_and_type(&function.return_type, ret)) map.append(&mut builder::get_generic_id_and_type(
&function.return_type,
ret,
))
} }
} }
mono_types = map.into_iter().collect(); mono_types = map.into_iter().collect();
let (variant_name, func_ir) = let (variant_name, func_ir) =
monomorphize(func_ir, mono_types, &constructor.tipo); builder::monomorphize(func_ir, mono_types, &constructor.tipo);
let function_key = FunctionAccessKey { let function_key = FunctionAccessKey {
module_name: module.clone(), module_name: module.clone(),
@ -3395,7 +3404,7 @@ impl<'a> CodeGenerator<'a> {
}; };
if let Some(scope_prev) = to_be_defined_map.get(&function_key) { if let Some(scope_prev) = to_be_defined_map.get(&function_key) {
let new_scope = get_common_ancestor(scope, scope_prev); let new_scope = builder::get_common_ancestor(scope, scope_prev);
to_be_defined_map.insert(function_key, new_scope); to_be_defined_map.insert(function_key, new_scope);
} else if func_components.get(&function_key).is_some() { } else if func_components.get(&function_key).is_some() {
@ -3448,7 +3457,7 @@ impl<'a> CodeGenerator<'a> {
if arg.tipo.is_generic() { if arg.tipo.is_generic() {
let param_type = &param_types[index]; let param_type = &param_types[index];
map.append(&mut get_generic_id_and_type( map.append(&mut builder::get_generic_id_and_type(
&arg.tipo, param_type, &arg.tipo, param_type,
)); ));
} }
@ -3456,7 +3465,7 @@ impl<'a> CodeGenerator<'a> {
if function.return_type.is_generic() { if function.return_type.is_generic() {
if let Type::Fn { ret, .. } = &*constructor.tipo { if let Type::Fn { ret, .. } = &*constructor.tipo {
map.append(&mut get_generic_id_and_type( map.append(&mut builder::get_generic_id_and_type(
&function.return_type, &function.return_type,
ret, ret,
)) ))
@ -3469,7 +3478,7 @@ impl<'a> CodeGenerator<'a> {
self.build_ir(&function.body, &mut func_ir, scope.to_vec()); self.build_ir(&function.body, &mut func_ir, scope.to_vec());
let (variant_name, _) = let (variant_name, _) =
monomorphize(func_ir, mono_types, &tipo); builder::monomorphize(func_ir, mono_types, &tipo);
func_calls.insert( func_calls.insert(
FunctionAccessKey { FunctionAccessKey {
@ -3518,15 +3527,17 @@ impl<'a> CodeGenerator<'a> {
} }
} else { } else {
for func in to_be_defined_map.clone().iter() { for func in to_be_defined_map.clone().iter() {
if get_common_ancestor(scope, func.1) == scope.to_vec() { if builder::get_common_ancestor(scope, func.1) == scope.to_vec() {
if let Some(index_scope) = func_index_map.get(func.0) { if let Some(index_scope) = func_index_map.get(func.0) {
if get_common_ancestor(index_scope, func.1) == scope.to_vec() { if builder::get_common_ancestor(index_scope, func.1)
== scope.to_vec()
{
func_index_map.insert(func.0.clone(), scope.clone()); func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0); to_be_defined_map.shift_remove(func.0);
} else { } else {
to_be_defined_map.insert( to_be_defined_map.insert(
func.0.clone(), func.0.clone(),
get_common_ancestor(index_scope, func.1), builder::get_common_ancestor(index_scope, func.1),
); );
} }
} else { } else {
@ -3541,15 +3552,17 @@ impl<'a> CodeGenerator<'a> {
let scope = a.scope(); let scope = a.scope();
for func in to_be_defined_map.clone().iter() { for func in to_be_defined_map.clone().iter() {
if get_common_ancestor(&scope, func.1) == scope.to_vec() { if builder::get_common_ancestor(&scope, func.1) == scope.to_vec() {
if let Some(index_scope) = func_index_map.get(func.0) { if let Some(index_scope) = func_index_map.get(func.0) {
if get_common_ancestor(index_scope, func.1) == scope.to_vec() { if builder::get_common_ancestor(index_scope, func.1)
== scope.to_vec()
{
func_index_map.insert(func.0.clone(), scope.clone()); func_index_map.insert(func.0.clone(), scope.clone());
to_be_defined_map.shift_remove(func.0); to_be_defined_map.shift_remove(func.0);
} else { } else {
to_be_defined_map.insert( to_be_defined_map.insert(
func.0.clone(), func.0.clone(),
get_common_ancestor(index_scope, func.1), builder::get_common_ancestor(index_scope, func.1),
); );
} }
} else { } else {
@ -3565,7 +3578,10 @@ 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(),
builder::get_common_ancestor(func.1, index_scope),
);
} }
} }
@ -3580,7 +3596,7 @@ impl<'a> CodeGenerator<'a> {
variant_name, variant_name,
} => { } => {
let mut replaced_type = constructor.tipo.clone(); let mut replaced_type = constructor.tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Var { ir_stack[index] = Air::Var {
scope, scope,
@ -3600,7 +3616,7 @@ impl<'a> CodeGenerator<'a> {
tail, tail,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::List { ir_stack[index] = Air::List {
scope, scope,
@ -3617,7 +3633,7 @@ impl<'a> CodeGenerator<'a> {
check_last_item, check_last_item,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::ListAccessor { ir_stack[index] = Air::ListAccessor {
scope, scope,
@ -3634,7 +3650,7 @@ impl<'a> CodeGenerator<'a> {
tail, tail,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::ListExpose { ir_stack[index] = Air::ListExpose {
scope, scope,
@ -3650,7 +3666,7 @@ impl<'a> CodeGenerator<'a> {
count, count,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Builtin { ir_stack[index] = Air::Builtin {
scope, scope,
@ -3666,7 +3682,7 @@ impl<'a> CodeGenerator<'a> {
count, count,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::BinOp { ir_stack[index] = Air::BinOp {
scope, scope,
@ -3681,7 +3697,7 @@ impl<'a> CodeGenerator<'a> {
subject_name, subject_name,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::When { ir_stack[index] = Air::When {
scope, scope,
@ -3696,7 +3712,7 @@ impl<'a> CodeGenerator<'a> {
complex_clause, complex_clause,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Clause { ir_stack[index] = Air::Clause {
scope, scope,
@ -3713,7 +3729,7 @@ impl<'a> CodeGenerator<'a> {
complex_clause, complex_clause,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::ListClause { ir_stack[index] = Air::ListClause {
scope, scope,
@ -3733,7 +3749,7 @@ impl<'a> CodeGenerator<'a> {
complex_clause, complex_clause,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::TupleClause { ir_stack[index] = Air::TupleClause {
scope, scope,
@ -3751,7 +3767,7 @@ impl<'a> CodeGenerator<'a> {
subject_name, subject_name,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::ClauseGuard { ir_stack[index] = Air::ClauseGuard {
scope, scope,
@ -3767,7 +3783,7 @@ impl<'a> CodeGenerator<'a> {
inverse, inverse,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::ListClauseGuard { ir_stack[index] = Air::ListClauseGuard {
scope, scope,
@ -3779,7 +3795,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::Tuple { tipo, scope, count } => { Air::Tuple { tipo, scope, count } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Tuple { ir_stack[index] = Air::Tuple {
scope, scope,
@ -3793,7 +3809,7 @@ impl<'a> CodeGenerator<'a> {
tuple_index, tuple_index,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::TupleIndex { ir_stack[index] = Air::TupleIndex {
scope, scope,
@ -3803,7 +3819,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::ErrorTerm { tipo, scope } => { Air::ErrorTerm { tipo, scope } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::ErrorTerm { ir_stack[index] = Air::ErrorTerm {
scope, scope,
@ -3812,7 +3828,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::Trace { tipo, scope } => { Air::Trace { tipo, scope } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Trace { ir_stack[index] = Air::Trace {
scope, scope,
@ -3826,7 +3842,7 @@ impl<'a> CodeGenerator<'a> {
check_last_item, check_last_item,
} => { } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::TupleAccessor { ir_stack[index] = Air::TupleAccessor {
scope, scope,
@ -3844,7 +3860,7 @@ impl<'a> CodeGenerator<'a> {
let mut new_indices = vec![]; let mut new_indices = vec![];
for (ind, tipo) in indices { for (ind, tipo) in indices {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
new_indices.push((ind, replaced_type)); new_indices.push((ind, replaced_type));
} }
@ -3861,11 +3877,11 @@ impl<'a> CodeGenerator<'a> {
count, count,
scope, scope,
} => { } => {
if check_replaceable_opaque_type(&tipo, &self.data_types) { if builder::check_replaceable_opaque_type(&tipo, &self.data_types) {
indices_to_remove.push(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()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Record { ir_stack[index] = Air::Record {
scope, scope,
@ -3883,11 +3899,14 @@ impl<'a> CodeGenerator<'a> {
let record = ir_stack[index + 1].clone(); let record = ir_stack[index + 1].clone();
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 builder::check_replaceable_opaque_type(&record_type, &self.data_types) {
indices_to_remove.push(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()); builder::replace_opaque_type(
&mut replaced_type,
self.data_types.clone(),
);
ir_stack[index] = Air::RecordAccess { ir_stack[index] = Air::RecordAccess {
scope, scope,
@ -3897,7 +3916,7 @@ impl<'a> CodeGenerator<'a> {
} }
} else { } else {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::RecordAccess { ir_stack[index] = Air::RecordAccess {
scope, scope,
@ -3914,7 +3933,7 @@ impl<'a> CodeGenerator<'a> {
let record = ir_stack[index + 1].clone(); let record = ir_stack[index + 1].clone();
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 builder::check_replaceable_opaque_type(&record_type, &self.data_types) {
ir_stack[index] = Air::Let { ir_stack[index] = Air::Let {
scope, scope,
name: indices[0].1.clone(), name: indices[0].1.clone(),
@ -3923,7 +3942,10 @@ impl<'a> CodeGenerator<'a> {
let mut new_indices = vec![]; let mut new_indices = vec![];
for (ind, name, tipo) in indices { for (ind, name, tipo) in indices {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(
&mut replaced_type,
self.data_types.clone(),
);
new_indices.push((ind, name, replaced_type)); new_indices.push((ind, name, replaced_type));
} }
@ -3937,7 +3959,10 @@ impl<'a> CodeGenerator<'a> {
let mut new_indices = vec![]; let mut new_indices = vec![];
for (ind, name, tipo) in indices { for (ind, name, tipo) in indices {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(
&mut replaced_type,
self.data_types.clone(),
);
new_indices.push((ind, name, replaced_type)); new_indices.push((ind, name, replaced_type));
} }
@ -3950,7 +3975,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::Call { scope, count, tipo } => { Air::Call { scope, count, tipo } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::Call { ir_stack[index] = Air::Call {
scope, scope,
@ -3960,7 +3985,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::If { scope, tipo } => { Air::If { scope, tipo } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::If { ir_stack[index] = Air::If {
scope, scope,
@ -3969,7 +3994,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::UnWrapData { scope, tipo } => { Air::UnWrapData { scope, tipo } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::UnWrapData { ir_stack[index] = Air::UnWrapData {
scope, scope,
@ -3978,7 +4003,7 @@ impl<'a> CodeGenerator<'a> {
} }
Air::WrapData { scope, tipo } => { Air::WrapData { scope, tipo } => {
let mut replaced_type = tipo.clone(); let mut replaced_type = tipo.clone();
replace_opaque_type(&mut replaced_type, self.data_types.clone()); builder::replace_opaque_type(&mut replaced_type, self.data_types.clone());
ir_stack[index] = Air::WrapData { ir_stack[index] = Air::WrapData {
scope, scope,
@ -4064,7 +4089,7 @@ impl<'a> CodeGenerator<'a> {
} else if constructor.tipo.is_void() { } else if constructor.tipo.is_void() {
arg_stack.push(Term::Constant(UplcConstant::Unit.into())); arg_stack.push(Term::Constant(UplcConstant::Unit.into()));
} else { } else {
let data_type = lookup_data_type_by_tipo( let data_type = builder::lookup_data_type_by_tipo(
self.data_types.clone(), self.data_types.clone(),
&constructor.tipo, &constructor.tipo,
) )
@ -4121,8 +4146,8 @@ impl<'a> CodeGenerator<'a> {
} }
} }
let convert_keys = convert_constants_to_data(convert_keys); let convert_keys = builder::convert_constants_to_data(convert_keys);
let convert_values = convert_constants_to_data(convert_values); let convert_values = builder::convert_constants_to_data(convert_values);
Term::Constant( Term::Constant(
UplcConstant::ProtoList( UplcConstant::ProtoList(
@ -4146,7 +4171,7 @@ impl<'a> CodeGenerator<'a> {
Term::Constant( Term::Constant(
UplcConstant::ProtoList( UplcConstant::ProtoList(
UplcType::Data, UplcType::Data,
convert_constants_to_data(constants), builder::convert_constants_to_data(constants),
) )
.into(), .into(),
) )
@ -4166,7 +4191,7 @@ impl<'a> CodeGenerator<'a> {
let list_item = if tipo.is_map() { let list_item = if tipo.is_map() {
arg arg
} else { } else {
convert_type_to_data(arg, &list_type) builder::convert_type_to_data(arg, &list_type)
}; };
term = Term::mk_cons().apply(list_item).apply(term); term = Term::mk_cons().apply(list_item).apply(term);
} }
@ -4198,7 +4223,7 @@ impl<'a> CodeGenerator<'a> {
.take(names.len()) .take(names.len())
.collect_vec(); .collect_vec();
term = list_access_to_uplc( term = builder::list_access_to_uplc(
&names, &names,
&id_list, &id_list,
tail, tail,
@ -4230,7 +4255,7 @@ impl<'a> CodeGenerator<'a> {
let head_list = if tipo.is_map() { let head_list = if tipo.is_map() {
Term::head_list().apply(Term::var(tail_var)) Term::head_list().apply(Term::var(tail_var))
} else { } else {
convert_data_to_type( builder::convert_data_to_type(
Term::head_list().apply(Term::var(tail_var)), Term::head_list().apply(Term::var(tail_var)),
&tipo.get_inner_types()[0], &tipo.get_inner_types()[0],
) )
@ -4282,8 +4307,10 @@ impl<'a> CodeGenerator<'a> {
let name = format!("{function_name}{variant_name}"); let name = format!("{function_name}{variant_name}");
if text == &name || text == &name_module { if text == &name || text == &name_module {
let mut term = self.uplc_code_gen(&mut ir.clone()); let mut term = self.uplc_code_gen(&mut ir.clone());
term = builder::constr_get_field(term); term = term
term = builder::constr_fields_exposer(term); .constr_get_field()
.constr_fields_exposer()
.constr_index_exposer();
let mut program: Program<Name> = Program { let mut program: Program<Name> = Program {
version: (1, 0, 0), version: (1, 0, 0),
@ -4342,7 +4369,7 @@ impl<'a> CodeGenerator<'a> {
term = term.apply(Term::var(temp_var.clone())); term = term.apply(Term::var(temp_var.clone()));
} }
term = convert_data_to_type(term, &tipo); term = builder::convert_data_to_type(term, &tipo);
if count == 0 { if count == 0 {
term = term.lambda(temp_var); term = term.lambda(temp_var);
@ -4593,14 +4620,14 @@ impl<'a> CodeGenerator<'a> {
Air::UnWrapData { tipo, .. } => { Air::UnWrapData { tipo, .. } => {
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
term = convert_data_to_type(term, &tipo); term = builder::convert_data_to_type(term, &tipo);
arg_stack.push(term); arg_stack.push(term);
} }
Air::WrapData { tipo, .. } => { Air::WrapData { tipo, .. } => {
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
term = convert_type_to_data(term, &tipo); term = builder::convert_type_to_data(term, &tipo);
arg_stack.push(term); arg_stack.push(term);
} }
@ -4870,7 +4897,7 @@ impl<'a> CodeGenerator<'a> {
for (index, arg) in arg_vec.iter().enumerate().rev() { for (index, arg) in arg_vec.iter().enumerate().rev() {
term = Term::mk_cons() term = Term::mk_cons()
.apply(convert_type_to_data( .apply(builder::convert_type_to_data(
arg.clone(), arg.clone(),
&tipo.arg_types().unwrap()[index], &tipo.arg_types().unwrap()[index],
)) ))
@ -4910,7 +4937,7 @@ impl<'a> CodeGenerator<'a> {
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(constr)) .apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(constr))
.apply(Term::integer(record_index.into())); .apply(Term::integer(record_index.into()));
term = convert_data_to_type(term, &tipo); term = builder::convert_data_to_type(term, &tipo);
arg_stack.push(term); arg_stack.push(term);
} }
@ -4937,7 +4964,7 @@ impl<'a> CodeGenerator<'a> {
let inner_types = indices.iter().cloned().map(|item| item.2).collect_vec(); let inner_types = indices.iter().cloned().map(|item| item.2).collect_vec();
term = if !indices.is_empty() { term = if !indices.is_empty() {
list_access_to_uplc( builder::list_access_to_uplc(
&names, &names,
&id_list, &id_list,
false, false,
@ -4972,7 +4999,7 @@ impl<'a> CodeGenerator<'a> {
let tuple_sub_types = tipo.get_inner_types(); let tuple_sub_types = tipo.get_inner_types();
if constants.len() == args.len() { if constants.len() == args.len() {
let data_constants = convert_constants_to_data(constants); let data_constants = builder::convert_constants_to_data(constants);
if count == 2 { if count == 2 {
let term = Term::Constant( let term = Term::Constant(
@ -4993,15 +5020,21 @@ impl<'a> CodeGenerator<'a> {
} }
} else if count == 2 { } else if count == 2 {
let term = Term::mk_pair_data() let term = Term::mk_pair_data()
.apply(convert_type_to_data(args[0].clone(), &tuple_sub_types[0])) .apply(builder::convert_type_to_data(
.apply(convert_type_to_data(args[1].clone(), &tuple_sub_types[1])); args[0].clone(),
&tuple_sub_types[0],
))
.apply(builder::convert_type_to_data(
args[1].clone(),
&tuple_sub_types[1],
));
arg_stack.push(term); arg_stack.push(term);
} else { } else {
let mut term = Term::empty_list(); let mut term = Term::empty_list();
for (arg, tipo) in args.into_iter().zip(tuple_sub_types.into_iter()).rev() { for (arg, tipo) in args.into_iter().zip(tuple_sub_types.into_iter()).rev() {
term = Term::mk_cons() term = Term::mk_cons()
.apply(convert_type_to_data(arg, &tipo)) .apply(builder::convert_type_to_data(arg, &tipo))
.apply(term); .apply(term);
} }
arg_stack.push(term); arg_stack.push(term);
@ -5044,7 +5077,7 @@ impl<'a> CodeGenerator<'a> {
if let Some((tipo, arg)) = args.get(&current_index) { if let Some((tipo, arg)) = args.get(&current_index) {
term = Term::mk_cons() term = Term::mk_cons()
.apply(convert_type_to_data(arg.clone(), tipo)) .apply(builder::convert_type_to_data(arg.clone(), tipo))
.apply(term); .apply(term);
} else { } else {
term = Term::mk_cons() term = Term::mk_cons()
@ -5112,19 +5145,19 @@ impl<'a> CodeGenerator<'a> {
if matches!(tipo.get_uplc_type(), UplcType::Pair(_, _)) { if matches!(tipo.get_uplc_type(), UplcType::Pair(_, _)) {
if tuple_index == 0 { if tuple_index == 0 {
term = convert_data_to_type( term = builder::convert_data_to_type(
Term::fst_pair().apply(term), Term::fst_pair().apply(term),
&tipo.get_inner_types()[0], &tipo.get_inner_types()[0],
); );
} else { } else {
term = convert_data_to_type( term = builder::convert_data_to_type(
Term::snd_pair().apply(term), Term::snd_pair().apply(term),
&tipo.get_inner_types()[1], &tipo.get_inner_types()[1],
); );
} }
} else { } else {
self.needs_field_access = true; self.needs_field_access = true;
term = convert_data_to_type( term = builder::convert_data_to_type(
Term::var(CONSTR_GET_FIELD) Term::var(CONSTR_GET_FIELD)
.apply(term) .apply(term)
.apply(Term::integer(tuple_index.into())), .apply(Term::integer(tuple_index.into())),
@ -5148,12 +5181,12 @@ impl<'a> CodeGenerator<'a> {
if names.len() == 2 { if names.len() == 2 {
term = term term = term
.lambda(names[1].clone()) .lambda(names[1].clone())
.apply(convert_data_to_type( .apply(builder::convert_data_to_type(
Term::snd_pair().apply(Term::var(format!("__tuple_{list_id}"))), Term::snd_pair().apply(Term::var(format!("__tuple_{list_id}"))),
&inner_types[1], &inner_types[1],
)) ))
.lambda(names[0].clone()) .lambda(names[0].clone())
.apply(convert_data_to_type( .apply(builder::convert_data_to_type(
Term::fst_pair().apply(Term::var(format!("__tuple_{list_id}"))), Term::fst_pair().apply(Term::var(format!("__tuple_{list_id}"))),
&inner_types[0], &inner_types[0],
)) ))
@ -5167,7 +5200,7 @@ impl<'a> CodeGenerator<'a> {
id_list.push(self.id_gen.next()); id_list.push(self.id_gen.next());
} }
term = list_access_to_uplc( term = builder::list_access_to_uplc(
&names, &names,
&id_list, &id_list,
false, false,
@ -5219,16 +5252,19 @@ impl<'a> CodeGenerator<'a> {
Term::snd_pair() Term::snd_pair()
}; };
term = term.lambda(name).apply(convert_data_to_type( term = term.lambda(name).apply(builder::convert_data_to_type(
builtin.apply(Term::var(subject_name.clone())), builtin.apply(Term::var(subject_name.clone())),
&tuple_types[*index].clone(), &tuple_types[*index].clone(),
)); ));
} }
} else { } else {
for (index, name) in indices.iter() { for (index, name) in indices.iter() {
term = term.lambda(name.clone()).apply(convert_data_to_type( term = term
Term::head_list() .lambda(name.clone())
.apply(repeat_tail_list(Term::var(subject_name.clone()), *index)), .apply(builder::convert_data_to_type(
Term::head_list().apply(
Term::var(subject_name.clone()).repeat_tail_list(*index),
),
&tuple_types[*index].clone(), &tuple_types[*index].clone(),
)); ));
} }

View File

@ -1,11 +1,12 @@
use crate::{
ast::{BinOp, UnOp},
tipo::{Type, ValueConstructor},
IdGenerator,
};
use indexmap::IndexSet; use indexmap::IndexSet;
use std::sync::Arc; use std::sync::Arc;
use uplc::builtins::DefaultFunction; use uplc::builtins::DefaultFunction;
use crate::{
ast::{BinOp, UnOp},
tipo::{Type, ValueConstructor},
};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Air { pub enum Air {
// Primitives // Primitives
@ -408,63 +409,3 @@ impl Air {
} }
} }
} }
pub struct AirEnv<'a> {
pub id_gen: &'a mut IdGenerator,
pub scope: Vec<u64>,
pub air: Vec<Air>,
}
impl<'a> AirEnv<'a> {
pub fn new(id_gen: &'a mut IdGenerator) -> Self {
AirEnv {
id_gen,
scope: vec![0],
air: vec![],
}
}
pub fn new_with_scope(id_gen: &'a mut IdGenerator, scope: Vec<u64>) -> Self {
AirEnv {
id_gen,
scope,
air: vec![],
}
}
pub fn merge(mut self, other: AirEnv) -> Self {
self.air.extend(other.air.into_iter());
self
}
pub fn int(self, value: String) -> Self {
let mut air = self.air.clone();
air.push(Air::Int {
scope: self.scope.clone(),
value,
});
AirEnv {
id_gen: self.id_gen,
scope: self.scope,
air,
}
}
pub fn string(mut self, value: String) -> Self {
self.air.push(Air::String {
scope: self.scope.clone(),
value,
});
self
}
pub fn byte_array(mut self, bytes: Vec<u8>) -> Self {
self.air.push(Air::ByteArray {
scope: self.scope.clone(),
bytes,
});
self
}
// pub fn sequence(mut self, expressions: AirEnv) -> Self {}
}

View File

@ -3,10 +3,8 @@ use std::{rc::Rc, sync::Arc};
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use itertools::Itertools; use itertools::Itertools;
use uplc::{ use uplc::{
ast::{ ast::{Constant as UplcConstant, Name, Term, Type as UplcType},
builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER}, builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER},
Constant as UplcConstant, Name, Term, Type as UplcType,
},
builtins::DefaultFunction, builtins::DefaultFunction,
machine::{ machine::{
runtime::{convert_constr_to_tag, ANY_TAG}, runtime::{convert_constr_to_tag, ANY_TAG},
@ -16,7 +14,6 @@ use uplc::{
}; };
use crate::{ use crate::{
air::Air,
ast::{ ast::{
AssignmentKind, BinOp, ClauseGuard, Constant, DataType, Pattern, Span, TypedArg, AssignmentKind, BinOp, ClauseGuard, Constant, DataType, Pattern, Span, TypedArg,
TypedClause, TypedDataType, UnOp, TypedClause, TypedDataType, UnOp,
@ -25,6 +22,8 @@ use crate::{
tipo::{PatternConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant}, tipo::{PatternConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant},
}; };
use super::air::Air;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FuncComponents { pub struct FuncComponents {
pub ir: Vec<Air>, pub ir: Vec<Air>,

View File

@ -0,0 +1,68 @@
use crate::IdGenerator;
use super::air::Air;
pub struct AirStack<'a> {
pub id_gen: &'a mut IdGenerator,
pub scope: Vec<u64>,
pub air: Vec<Air>,
}
impl<'a> AirStack<'a> {
pub fn new(id_gen: &'a mut IdGenerator) -> Self {
AirStack {
id_gen,
scope: vec![0],
air: vec![],
}
}
pub fn with_scope(id_gen: &'a mut IdGenerator, scope: Vec<u64>) -> Self {
AirStack {
id_gen,
scope,
air: vec![],
}
}
pub fn merge(mut self, other: AirStack) -> Self {
self.air.extend(other.air.into_iter());
self
}
pub fn int(self, value: String) -> Self {
let mut air = self.air.clone();
air.push(Air::Int {
scope: self.scope.clone(),
value,
});
AirStack {
id_gen: self.id_gen,
scope: self.scope,
air,
}
}
pub fn string(mut self, value: String) -> Self {
self.air.push(Air::String {
scope: self.scope.clone(),
value,
});
self
}
pub fn byte_array(mut self, bytes: Vec<u8>) -> Self {
self.air.push(Air::ByteArray {
scope: self.scope.clone(),
bytes,
});
self
}
// pub fn sequence(mut self, expressions: AirEnv) -> Self {}
}

View File

@ -3,17 +3,15 @@ use std::sync::{
Arc, Arc,
}; };
pub mod air;
pub mod ast; pub mod ast;
pub mod builder;
pub mod builtins; pub mod builtins;
pub mod expr; pub mod expr;
pub mod format; pub mod format;
pub mod gen_uplc;
pub mod levenshtein; pub mod levenshtein;
pub mod parser; pub mod parser;
pub mod pretty; pub mod pretty;
pub mod tipo; pub mod tipo;
pub mod uplc;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct IdGenerator { pub struct IdGenerator {

View File

@ -4,7 +4,7 @@ pub mod schema;
pub mod validator; pub mod validator;
use crate::{config::Config, module::CheckedModules}; use crate::{config::Config, module::CheckedModules};
use aiken_lang::uplc::CodeGenerator; use aiken_lang::gen_uplc::CodeGenerator;
use definitions::{Definitions, Reference}; use definitions::{Definitions, Reference};
use error::Error; use error::Error;
use schema::{Annotated, Schema}; use schema::{Annotated, Schema};

View File

@ -6,7 +6,7 @@ use super::{
use crate::module::{CheckedModule, CheckedModules}; use crate::module::{CheckedModule, CheckedModules};
use aiken_lang::{ use aiken_lang::{
ast::{TypedArg, TypedFunction, TypedValidator}, ast::{TypedArg, TypedFunction, TypedValidator},
uplc::CodeGenerator, gen_uplc::CodeGenerator,
}; };
use miette::NamedSource; use miette::NamedSource;
use serde; use serde;
@ -187,8 +187,9 @@ mod test {
use aiken_lang::{ use aiken_lang::{
self, self,
ast::{ModuleKind, Tracing, TypedDataType, TypedFunction}, ast::{ModuleKind, Tracing, TypedDataType, TypedFunction},
builder::{DataTypeKey, FunctionAccessKey}, builtins,
builtins, parser, gen_uplc::builder::{DataTypeKey, FunctionAccessKey},
parser,
tipo::TypeInfo, tipo::TypeInfo,
IdGenerator, IdGenerator,
}; };

View File

@ -19,8 +19,8 @@ use crate::blueprint::{
}; };
use aiken_lang::{ use aiken_lang::{
ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction}, ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction},
builder::{DataTypeKey, FunctionAccessKey},
builtins, builtins,
gen_uplc::builder::{DataTypeKey, FunctionAccessKey},
tipo::TypeInfo, tipo::TypeInfo,
IdGenerator, IdGenerator,
}; };

View File

@ -4,10 +4,12 @@ use aiken_lang::{
DataType, Definition, Located, ModuleKind, TypedDataType, TypedFunction, TypedModule, DataType, Definition, Located, ModuleKind, TypedDataType, TypedFunction, TypedModule,
TypedValidator, UntypedModule, TypedValidator, UntypedModule,
}, },
gen_uplc::{
builder::{DataTypeKey, FunctionAccessKey}, builder::{DataTypeKey, FunctionAccessKey},
CodeGenerator,
},
parser::extra::{comments_before, Comment, ModuleExtra}, parser::extra::{comments_before, Comment, ModuleExtra},
tipo::TypeInfo, tipo::TypeInfo,
uplc::CodeGenerator,
}; };
use indexmap::IndexMap; use indexmap::IndexMap;
use petgraph::{algo, graph::NodeIndex, Direction, Graph}; use petgraph::{algo, graph::NodeIndex, Direction, Graph};

View File

@ -29,8 +29,6 @@ use crate::{
}, },
}; };
pub mod builder;
/// This represents a program in Untyped Plutus Core. /// This represents a program in Untyped Plutus Core.
/// A program contains a version tuple and a term. /// A program contains a version tuple and a term.
/// It is generic because Term requires a generic type. /// It is generic because Term requires a generic type.

View File

@ -1,6 +1,7 @@
use crate::builtins::DefaultFunction; use crate::{
ast::{Constant, Name, Term, Type},
use super::{Constant, Name, Term, Type}; builtins::DefaultFunction,
};
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";
@ -210,22 +211,21 @@ impl Term<Name> {
.apply(self.delay()) .apply(self.delay())
.force() .force()
} }
}
pub fn final_wrapper(term: Term<Name>) -> Term<Name> { pub fn assert_on_list(self) -> Term<Name> {
term.delayed_if_else(Term::unit(), Term::Error) self.lambda(ASSERT_ON_LIST.to_string())
} .apply(
Term::var(ASSERT_ON_LIST.to_string()).apply(Term::var(ASSERT_ON_LIST.to_string())),
pub fn assert_on_list(term: Term<Name>) -> Term<Name> { )
term.lambda(ASSERT_ON_LIST.to_string())
.apply(Term::var(ASSERT_ON_LIST.to_string()).apply(Term::var(ASSERT_ON_LIST.to_string())))
.lambda(ASSERT_ON_LIST.to_string()) .lambda(ASSERT_ON_LIST.to_string())
.apply( .apply(
Term::var("__list_to_check".to_string()) Term::var("__list_to_check".to_string())
.delayed_choose_list( .delayed_choose_list(
Term::unit(), Term::unit(),
Term::var("__check_with".to_string()) Term::var("__check_with".to_string())
.apply(Term::head_list().apply(Term::var("__list_to_check".to_string()))) .apply(
Term::head_list().apply(Term::var("__list_to_check".to_string())),
)
.choose_unit( .choose_unit(
Term::var(ASSERT_ON_LIST.to_string()) Term::var(ASSERT_ON_LIST.to_string())
.apply(Term::var(ASSERT_ON_LIST.to_string())) .apply(Term::var(ASSERT_ON_LIST.to_string()))
@ -240,26 +240,30 @@ pub fn assert_on_list(term: Term<Name>) -> Term<Name> {
.lambda("__list_to_check".to_string()) .lambda("__list_to_check".to_string())
.lambda(ASSERT_ON_LIST), .lambda(ASSERT_ON_LIST),
) )
} }
pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> { pub fn final_wrapper(self: Term<Name>) -> Term<Name> {
term.lambda(CONSTR_FIELDS_EXPOSER.to_string()).apply( self.delayed_if_else(Term::unit(), Term::Error)
}
pub fn constr_fields_exposer(self: Term<Name>) -> Term<Name> {
self.lambda(CONSTR_FIELDS_EXPOSER.to_string()).apply(
Term::snd_pair() Term::snd_pair()
.apply(Term::unconstr_data().apply(Term::var("__constr_var".to_string()))) .apply(Term::unconstr_data().apply(Term::var("__constr_var".to_string())))
.lambda("__constr_var"), .lambda("__constr_var"),
) )
} }
pub fn constr_index_exposer(term: Term<Name>) -> Term<Name> { pub fn constr_index_exposer(self: Term<Name>) -> Term<Name> {
term.lambda(CONSTR_INDEX_EXPOSER.to_string()).apply( self.lambda(CONSTR_INDEX_EXPOSER.to_string()).apply(
Term::fst_pair() Term::fst_pair()
.apply(Term::unconstr_data().apply(Term::var("__constr_var".to_string()))) .apply(Term::unconstr_data().apply(Term::var("__constr_var".to_string())))
.lambda("__constr_var".to_string()), .lambda("__constr_var".to_string()),
) )
} }
pub fn constr_get_field(term: Term<Name>) -> Term<Name> { pub fn constr_get_field(self: Term<Name>) -> Term<Name> {
term.lambda(CONSTR_GET_FIELD.to_string()) self.lambda(CONSTR_GET_FIELD.to_string())
.apply( .apply(
Term::var(CONSTR_GET_FIELD.to_string()) Term::var(CONSTR_GET_FIELD.to_string())
.apply(Term::var(CONSTR_GET_FIELD.to_string())) .apply(Term::var(CONSTR_GET_FIELD.to_string()))
@ -292,13 +296,15 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
.lambda("__current_arg_number".to_string()) .lambda("__current_arg_number".to_string())
.lambda(CONSTR_GET_FIELD.to_string()), .lambda(CONSTR_GET_FIELD.to_string()),
) )
} }
pub fn repeat_tail_list(term: Term<Name>, repeat: usize) -> Term<Name> { pub fn repeat_tail_list(self: Term<Name>, repeat: usize) -> Term<Name> {
let mut term = term; let mut term = self;
for _ in 0..repeat { for _ in 0..repeat {
term = Term::tail_list().apply(term); term = Term::tail_list().apply(term);
} }
term term
}
} }

View File

@ -1,4 +1,5 @@
pub mod ast; pub mod ast;
pub mod builder;
pub mod builtins; pub mod builtins;
mod debruijn; mod debruijn;
mod flat; mod flat;