changed assert_on_list from being defined at uplc level to being defined at air level to enable proper hoisting
This commit is contained in:
parent
f4ba6b8985
commit
abd97f0ade
|
@ -3,7 +3,9 @@ use std::{rc::Rc, sync::Arc};
|
|||
use indexmap::{IndexMap, IndexSet};
|
||||
use itertools::Itertools;
|
||||
use uplc::{
|
||||
ast::{Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType},
|
||||
ast::{
|
||||
Constant as UplcConstant, DeBruijn, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
||||
},
|
||||
builder::{CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD, CONSTR_INDEX_EXPOSER},
|
||||
builtins::DefaultFunction,
|
||||
machine::cost_model::ExBudget,
|
||||
|
@ -37,6 +39,13 @@ use builder::{
|
|||
|
||||
use self::{builder::replace_opaque_type, scope::Scope, stack::AirStack};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CodeGenFunction {
|
||||
air: Vec<Air>,
|
||||
dependencies: Vec<String>,
|
||||
recursive: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CodeGenerator<'a> {
|
||||
defined_functions: IndexMap<FunctionAccessKey, ()>,
|
||||
|
@ -45,8 +54,9 @@ pub struct CodeGenerator<'a> {
|
|||
module_types: IndexMap<&'a String, &'a TypeInfo>,
|
||||
id_gen: Rc<IdGenerator>,
|
||||
needs_field_access: bool,
|
||||
used_data_assert_on_list: bool,
|
||||
code_gen_functions: IndexMap<String, CodeGenFunction>,
|
||||
zero_arg_functions: IndexMap<FunctionAccessKey, Vec<Air>>,
|
||||
uplc_to_function: IndexMap<Program<DeBruijn>, FunctionAccessKey>,
|
||||
}
|
||||
|
||||
impl<'a> CodeGenerator<'a> {
|
||||
|
@ -60,19 +70,21 @@ impl<'a> CodeGenerator<'a> {
|
|||
functions,
|
||||
data_types,
|
||||
module_types,
|
||||
id_gen: IdGenerator::new().into(),
|
||||
needs_field_access: false,
|
||||
used_data_assert_on_list: false,
|
||||
id_gen: IdGenerator::new().into(),
|
||||
code_gen_functions: IndexMap::new(),
|
||||
zero_arg_functions: IndexMap::new(),
|
||||
uplc_to_function: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.needs_field_access = false;
|
||||
self.used_data_assert_on_list = false;
|
||||
self.code_gen_functions = IndexMap::new();
|
||||
self.zero_arg_functions = IndexMap::new();
|
||||
self.id_gen = IdGenerator::new().into();
|
||||
self.needs_field_access = false;
|
||||
self.defined_functions = IndexMap::new();
|
||||
self.uplc_to_function = IndexMap::new();
|
||||
}
|
||||
|
||||
pub fn generate(
|
||||
|
@ -157,11 +169,13 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
|
||||
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 {
|
||||
term.assert_on_list()
|
||||
} else {
|
||||
term
|
||||
};
|
||||
// let mut term = if self.used_data_assert_on_list {
|
||||
// term.assert_on_list()
|
||||
// } else {
|
||||
// term
|
||||
// };
|
||||
|
||||
let mut term = term;
|
||||
|
||||
if self.needs_field_access {
|
||||
term = term
|
||||
|
@ -197,14 +211,10 @@ impl<'a> CodeGenerator<'a> {
|
|||
TypedExpr::Pipeline { expressions, .. } | TypedExpr::Sequence { expressions, .. } => {
|
||||
let mut stacks = Vec::new();
|
||||
|
||||
for (index, expr) in expressions.iter().enumerate() {
|
||||
if index == 0 {
|
||||
self.build(expr, ir_stack);
|
||||
} else {
|
||||
let mut stack = ir_stack.empty_with_scope();
|
||||
self.build(expr, &mut stack);
|
||||
stacks.push(stack);
|
||||
}
|
||||
for expr in expressions.iter() {
|
||||
let mut stack = ir_stack.empty_with_scope();
|
||||
self.build(expr, &mut stack);
|
||||
stacks.push(stack);
|
||||
}
|
||||
|
||||
ir_stack.sequence(stacks);
|
||||
|
@ -1638,6 +1648,8 @@ impl<'a> CodeGenerator<'a> {
|
|||
{
|
||||
let mut expect_stack = pattern_stack.empty_with_scope();
|
||||
|
||||
println!("GETTING 2 HERE");
|
||||
|
||||
self.expect_pattern(
|
||||
pattern,
|
||||
&mut expect_stack,
|
||||
|
@ -2225,7 +2237,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
|| tipo.is_data()
|
||||
{
|
||||
} else if tipo.is_map() {
|
||||
self.used_data_assert_on_list = true;
|
||||
// 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];
|
||||
|
@ -2266,7 +2278,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
expect_stack.void();
|
||||
} else if tipo.is_list() {
|
||||
self.used_data_assert_on_list = true;
|
||||
// self.used_data_assert_on_list = true;
|
||||
let new_id = self.id_gen.next();
|
||||
let inner_list_type = &tipo.get_inner_types()[0];
|
||||
|
||||
|
@ -4813,8 +4825,9 @@ impl<'a> CodeGenerator<'a> {
|
|||
param_stack.local_var(data(), arg.arg_name.get_variable_name().unwrap_or("_"));
|
||||
|
||||
let mut actual_type = arg.tipo.clone();
|
||||
|
||||
println!("GETTING HERE");
|
||||
replace_opaque_type(&mut actual_type, self.data_types.clone());
|
||||
println!("ALSO HERE. TYPE IS {:#?}", actual_type);
|
||||
|
||||
self.assignment(
|
||||
&Pattern::Var {
|
||||
|
@ -4834,6 +4847,8 @@ impl<'a> CodeGenerator<'a> {
|
|||
arg.arg_name.get_variable_name().unwrap_or("_").to_string(),
|
||||
);
|
||||
|
||||
println!("CONTINUING HERE");
|
||||
|
||||
let mut air_vec = air_stack.complete();
|
||||
|
||||
term = term
|
||||
|
|
|
@ -5,7 +5,7 @@ use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction};
|
|||
|
||||
use crate::{
|
||||
ast::Span,
|
||||
builtins::void,
|
||||
builtins::{data, list, void},
|
||||
tipo::{Type, ValueConstructor, ValueConstructorVariant},
|
||||
IdGenerator,
|
||||
};
|
||||
|
@ -706,13 +706,73 @@ impl AirStack {
|
|||
|
||||
self.merge_child(value_stack);
|
||||
}
|
||||
|
||||
pub fn assert_on_list(&mut self) {
|
||||
let mut head_stack = self.empty_with_scope();
|
||||
let mut tail_stack = self.empty_with_scope();
|
||||
let mut check_with_stack = self.empty_with_scope();
|
||||
let mut expect_stack = self.empty_with_scope();
|
||||
let mut var_stack = self.empty_with_scope();
|
||||
let mut void_stack = self.empty_with_scope();
|
||||
let mut fun_stack = self.empty_with_scope();
|
||||
let mut arg_stack1 = self.empty_with_scope();
|
||||
let mut arg_stack2 = self.empty_with_scope();
|
||||
|
||||
self.air.push(Air::DefineFunc {
|
||||
scope: self.scope.clone(),
|
||||
func_name: EXPECT_ON_LIST.to_string(),
|
||||
module_name: "".to_string(),
|
||||
params: vec!["__list_to_check".to_string(), "__check_with".to_string()],
|
||||
recursive: true,
|
||||
variant_name: "".to_string(),
|
||||
});
|
||||
|
||||
var_stack.local_var(list(data()), "__list_to_check");
|
||||
|
||||
head_stack.builtin(DefaultFunction::HeadList, data(), vec![var_stack]);
|
||||
|
||||
fun_stack.local_var(void(), "__check_with".to_string());
|
||||
|
||||
check_with_stack.call(void(), fun_stack, vec![head_stack]);
|
||||
|
||||
void_stack.void();
|
||||
void_stack.void();
|
||||
|
||||
self.list_clause(
|
||||
void(),
|
||||
"__list_to_check".to_string(),
|
||||
None,
|
||||
false,
|
||||
void_stack,
|
||||
);
|
||||
|
||||
self.choose_unit(check_with_stack);
|
||||
|
||||
expect_stack.local_var(void(), EXPECT_ON_LIST.to_string());
|
||||
|
||||
arg_stack1.local_var(list(data()), "__list_to_check".to_string());
|
||||
|
||||
arg_stack2.local_var(void(), "__check_with".to_string());
|
||||
|
||||
tail_stack.builtin(DefaultFunction::TailList, list(data()), vec![arg_stack1]);
|
||||
|
||||
self.call(void(), expect_stack, vec![tail_stack, arg_stack2])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{gen_uplc::air::Air, IdGenerator};
|
||||
use uplc::builtins::DefaultFunction;
|
||||
|
||||
use crate::{
|
||||
ast::Span,
|
||||
builtins::{data, list, void},
|
||||
gen_uplc::air::Air,
|
||||
tipo::{ValueConstructor, ValueConstructorVariant},
|
||||
IdGenerator,
|
||||
};
|
||||
|
||||
use super::AirStack;
|
||||
|
||||
|
@ -812,4 +872,135 @@ mod test {
|
|||
],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_on_list_matches_air() {
|
||||
let id_gen: Rc<IdGenerator> = IdGenerator::new().into();
|
||||
|
||||
let scope = vec![id_gen.next()];
|
||||
|
||||
let mut stack1 = AirStack {
|
||||
id_gen,
|
||||
scope: scope.into(),
|
||||
air: vec![],
|
||||
};
|
||||
|
||||
stack1.assert_on_list();
|
||||
|
||||
println!("{:#?}", stack1);
|
||||
|
||||
let air_vec = vec![
|
||||
Air::DefineFunc {
|
||||
scope: vec![0].into(),
|
||||
func_name: "__expect_on_list".to_string(),
|
||||
module_name: "".to_string(),
|
||||
params: vec!["__list_to_check".to_string(), "__check_with".to_string()],
|
||||
recursive: true,
|
||||
variant_name: "".to_string(),
|
||||
},
|
||||
Air::ListClause {
|
||||
scope: vec![0, 7].into(),
|
||||
tipo: void(),
|
||||
tail_name: "__list_to_check".to_string(),
|
||||
next_tail_name: None,
|
||||
complex_clause: false,
|
||||
},
|
||||
Air::Void {
|
||||
scope: vec![0, 7, 5].into(),
|
||||
},
|
||||
Air::Void {
|
||||
scope: vec![0, 7, 5, 6].into(),
|
||||
},
|
||||
Air::Builtin {
|
||||
scope: vec![0, 7, 8].into(),
|
||||
count: 2,
|
||||
func: DefaultFunction::ChooseUnit,
|
||||
tipo: void(),
|
||||
},
|
||||
Air::Call {
|
||||
scope: vec![0, 7, 8, 4].into(),
|
||||
count: 1,
|
||||
tipo: void(),
|
||||
},
|
||||
Air::Var {
|
||||
scope: vec![0, 7, 8, 4, 3].into(),
|
||||
constructor: ValueConstructor {
|
||||
public: true,
|
||||
variant: ValueConstructorVariant::LocalVariable {
|
||||
location: Span::empty(),
|
||||
},
|
||||
tipo: void(),
|
||||
},
|
||||
name: "__check_with".to_string(),
|
||||
variant_name: "".to_string(),
|
||||
},
|
||||
Air::Builtin {
|
||||
scope: vec![0, 7, 8, 4, 2].into(),
|
||||
count: 1,
|
||||
func: DefaultFunction::HeadList,
|
||||
tipo: data(),
|
||||
},
|
||||
Air::Var {
|
||||
scope: vec![0, 7, 8, 4, 2, 1].into(),
|
||||
constructor: ValueConstructor {
|
||||
public: true,
|
||||
variant: ValueConstructorVariant::LocalVariable {
|
||||
location: Span::empty(),
|
||||
},
|
||||
tipo: list(data()),
|
||||
},
|
||||
name: "__list_to_check".to_string(),
|
||||
variant_name: "".to_string(),
|
||||
},
|
||||
Air::Call {
|
||||
scope: vec![0, 7, 8, 13].into(),
|
||||
count: 2,
|
||||
tipo: void(),
|
||||
},
|
||||
Air::Var {
|
||||
scope: vec![0, 7, 8, 13, 9].into(),
|
||||
constructor: ValueConstructor {
|
||||
public: true,
|
||||
variant: ValueConstructorVariant::LocalVariable {
|
||||
location: Span::empty(),
|
||||
},
|
||||
tipo: void(),
|
||||
},
|
||||
name: "__expect_on_list".to_string(),
|
||||
variant_name: "".to_string(),
|
||||
},
|
||||
Air::Builtin {
|
||||
scope: vec![0, 7, 8, 13, 12].into(),
|
||||
count: 1,
|
||||
func: DefaultFunction::TailList,
|
||||
tipo: list(data()),
|
||||
},
|
||||
Air::Var {
|
||||
scope: vec![0, 7, 8, 13, 12, 10].into(),
|
||||
constructor: ValueConstructor {
|
||||
public: true,
|
||||
variant: ValueConstructorVariant::LocalVariable {
|
||||
location: Span::empty(),
|
||||
},
|
||||
tipo: list(data()),
|
||||
},
|
||||
name: "__list_to_check".to_string(),
|
||||
variant_name: "".to_string(),
|
||||
},
|
||||
Air::Var {
|
||||
scope: vec![0, 7, 8, 13, 11].into(),
|
||||
constructor: ValueConstructor {
|
||||
public: true,
|
||||
variant: ValueConstructorVariant::LocalVariable {
|
||||
location: Span::empty(),
|
||||
},
|
||||
tipo: void(),
|
||||
},
|
||||
name: "__check_with".to_string(),
|
||||
variant_name: "".to_string(),
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(stack1.air, air_vec)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -507,8 +507,8 @@ mod test {
|
|||
"$ref": "#/definitions/test_module~1Input"
|
||||
}
|
||||
},
|
||||
"compiledCode": "583b0100003232323232323222253330064a22930b180080091129998030010a4c26600a6002600e0046660060066010004002ae695cdaab9f5742ae89",
|
||||
"hash": "e37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4",
|
||||
"compiledCode": "5902aa01000032323232323232323232323232322322322533300c4a22930b1980599299980599b874800000454ccc040c024008526153300d49011d4578706563746564206e6f206669656c647320666f7220436f6e73747200161533300b3370e90010008a99980818048010a4c2a6601a92011d4578706563746564206e6f206669656c647320666f7220436f6e73747200161533300b3370e90020008a99980818048010a4c2a6601a92011d4578706563746564206e6f206669656c647320666f7220436f6e7374720016153300d4912b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e7400163009001001330093253330093370e90000008991919191919299980a180b00109980819299980819b87480000044c8c94ccc05cc06400852615330144901334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375a602e002601c00c2a660249212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e740016300e0053301033009003232498dd7000a4c2a660229201334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375c602800260280046eb0c048004c048008c040004c01c00854cc02d2412b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e74001630070010013001001222533300d00214984cc024c004c038008ccc00c00cc03c008004cc0040052000222233330073370e00200601a4666600a00a66e000112002300f0010020022300737540024600a6ea80055cd2b9b5738aae7555cf2ab9f5742ae89",
|
||||
"hash": "f5268862002ca36eaf7ad18cb01daf0393f6c78715272ca3fd88143a",
|
||||
"definitions": {
|
||||
"ByteArray": {
|
||||
"dataType": "bytes"
|
||||
|
@ -619,8 +619,8 @@ mod test {
|
|||
"$ref": "#/definitions/Tuple$Int_Int_Int"
|
||||
}
|
||||
},
|
||||
"compiledCode": "585301000032323232323232232232253330084a22930b1bac0013232337606012004601200260120026eb0004c0040048894ccc0180085261330053001300700233300300330080020015734ae6d55cfaba157441",
|
||||
"hash": "500b9b576c11ad73dee3b9d5202496a7df78e8de4097c57f0acfcc3a",
|
||||
"compiledCode": "58cd01000032323232323232323232232232253330084a22930b1919191919192999808980980108030a99807249334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375a602200260220046eb4c03c004c03c008dd698068009bac001323232003375c60140046eb4c020004c8c8cdd81806001180600098060009bac0013001001222533300900214984cc014c004c028008ccc00c00cc02c0080055cd2b9b5738aae7555cf2ab9f5742ae881",
|
||||
"hash": "992c2391be3d472eda9de2da280f68338bff2eddb45dc75ab3e36046",
|
||||
"definitions": {
|
||||
"ByteArray": {
|
||||
"dataType": "bytes"
|
||||
|
|
Loading…
Reference in New Issue