Replace 'bool' with 'TraceLevel' in codegen

Co-authored-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
microproofs 2024-01-17 11:53:29 -05:00 committed by KtorZ
parent d27ea98a8f
commit f79b37d551
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
5 changed files with 115 additions and 118 deletions

View File

@ -19,8 +19,8 @@ use uplc::{
use crate::{ use crate::{
ast::{ ast::{
AssignmentKind, BinOp, Bls12_381Point, Curve, Pattern, Span, TypedArg, TypedClause, AssignmentKind, BinOp, Bls12_381Point, Curve, Pattern, Span, TraceLevel, TypedArg,
TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp, TypedClause, TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp,
}, },
builtins::{bool, data, int, list, string, void}, builtins::{bool, data, int, list, string, void},
expr::TypedExpr, expr::TypedExpr,
@ -57,7 +57,7 @@ pub struct CodeGenerator<'a> {
module_types: IndexMap<&'a String, &'a TypeInfo>, module_types: IndexMap<&'a String, &'a TypeInfo>,
module_src: IndexMap<String, String>, module_src: IndexMap<String, String>,
/// immutable option /// immutable option
tracing: bool, tracing: TraceLevel,
/// mutable index maps that are reset /// mutable index maps that are reset
defined_functions: IndexMap<FunctionAccessKey, ()>, defined_functions: IndexMap<FunctionAccessKey, ()>,
special_functions: CodeGenSpecialFuncs, special_functions: CodeGenSpecialFuncs,
@ -75,7 +75,7 @@ impl<'a> CodeGenerator<'a> {
data_types: IndexMap<DataTypeKey, &'a TypedDataType>, data_types: IndexMap<DataTypeKey, &'a TypedDataType>,
module_types: IndexMap<&'a String, &'a TypeInfo>, module_types: IndexMap<&'a String, &'a TypeInfo>,
module_src: IndexMap<String, String>, module_src: IndexMap<String, String>,
tracing: bool, tracing: TraceLevel,
) -> Self { ) -> Self {
CodeGenerator { CodeGenerator {
functions, functions,
@ -478,10 +478,12 @@ impl<'a> CodeGenerator<'a> {
string(), string(),
); );
let msg_func = if self.tracing && kind.is_expect() { // TODO
let msg_func = match self.tracing {
TraceLevel::Verbose if kind.is_expect() => {
Some(self.special_functions.use_function_msg(msg_func_name)) Some(self.special_functions.use_function_msg(msg_func_name))
} else { }
None _ => None,
}; };
self.assignment( self.assignment(
@ -1586,7 +1588,8 @@ impl<'a> CodeGenerator<'a> {
// mutate code_gen_funcs and defined_data_types in this if branch // mutate code_gen_funcs and defined_data_types in this if branch
if function.is_none() && defined_data_types.get(&data_type_name).is_none() { if function.is_none() && defined_data_types.get(&data_type_name).is_none() {
let (msg_term, error_term) = if self.tracing { let (msg_term, error_term) = match self.tracing {
TraceLevel::Verbose => {
let msg = AirMsg::LocalVar("__param_msg".to_string()); let msg = AirMsg::LocalVar("__param_msg".to_string());
( (
@ -1597,8 +1600,8 @@ impl<'a> CodeGenerator<'a> {
AirTree::error(tipo.clone(), false), AirTree::error(tipo.clone(), false),
), ),
) )
} else { }
(None, AirTree::error(tipo.clone(), false)) TraceLevel::Silent => (None, AirTree::error(tipo.clone(), false)),
}; };
defined_data_types.insert(data_type_name.clone(), 1); defined_data_types.insert(data_type_name.clone(), 1);
@ -1717,16 +1720,15 @@ impl<'a> CodeGenerator<'a> {
} }
} }
let code_gen_func = if self.tracing { let code_gen_func = match self.tracing {
CodeGenFunction::Function { TraceLevel::Verbose => CodeGenFunction::Function {
body: func_body, body: func_body,
params: vec!["__param_0".to_string(), "__param_msg".to_string()], params: vec!["__param_0".to_string(), "__param_msg".to_string()],
} },
} else { TraceLevel::Silent => CodeGenFunction::Function {
CodeGenFunction::Function {
body: func_body, body: func_body,
params: vec!["__param_0".to_string()], params: vec!["__param_0".to_string()],
} },
}; };
self.code_gen_functions self.code_gen_functions
@ -1737,15 +1739,14 @@ impl<'a> CodeGenerator<'a> {
defined_data_types.insert(data_type_name.to_string(), 1); defined_data_types.insert(data_type_name.to_string(), 1);
} }
let args = if self.tracing { let args = match self.tracing {
vec![ TraceLevel::Silent => vec![value],
TraceLevel::Verbose => vec![
value, value,
msg_func msg_func
.expect("should be unreachable: no msg func with tracing enabled.") .expect("should be unreachable: no msg func with tracing enabled.")
.to_air_tree(), .to_air_tree(),
] ],
} else {
vec![value]
}; };
let module_fn = ValueConstructorVariant::ModuleFn { let module_fn = ValueConstructorVariant::ModuleFn {
@ -2762,10 +2763,12 @@ impl<'a> CodeGenerator<'a> {
string(), string(),
); );
let msg_func = if self.tracing && !actual_type.is_data() { // TODO
let msg_func = match self.tracing {
TraceLevel::Verbose => {
Some(self.special_functions.use_function_msg(msg_func_name)) Some(self.special_functions.use_function_msg(msg_func_name))
} else { }
None _ => None,
}; };
let assign = self.assignment( let assign = self.assignment(
@ -3721,14 +3724,14 @@ impl<'a> CodeGenerator<'a> {
fn gen_uplc(&mut self, ir: Air, arg_stack: &mut Vec<Term<Name>>) -> Option<Term<Name>> { fn gen_uplc(&mut self, ir: Air, arg_stack: &mut Vec<Term<Name>>) -> Option<Term<Name>> {
// Going to mark the changes made to code gen after air tree implementation // Going to mark the changes made to code gen after air tree implementation
let error_term = if self.tracing && air_holds_msg(&ir) { // TODO
// In the case of an air that holds a msg and tracing is active let error_term = match self.tracing {
// we pop the msg off the stack first TraceLevel::Verbose if air_holds_msg(&ir) => {
let msg = arg_stack.pop().unwrap(); let msg = arg_stack.pop().unwrap();
Term::Error.delayed_trace(msg) Term::Error.delayed_trace(msg)
} else { }
Term::Error _ => Term::Error,
}; };
match ir { match ir {

View File

@ -15,8 +15,8 @@ use uplc::{
use crate::{ use crate::{
ast::{ ast::{
AssignmentKind, DataType, Pattern, Span, TypedArg, TypedClause, TypedClauseGuard, AssignmentKind, DataType, Pattern, Span, TraceLevel, TypedArg, TypedClause,
TypedDataType, TypedPattern, TypedClauseGuard, TypedDataType, TypedPattern,
}, },
builtins::{bool, data, function, int, list, string, void}, builtins::{bool, data, function, int, list, string, void},
expr::TypedExpr, expr::TypedExpr,
@ -1621,11 +1621,25 @@ pub fn special_case_builtin(
pub fn wrap_as_multi_validator( pub fn wrap_as_multi_validator(
spend: Term<Name>, spend: Term<Name>,
mint: Term<Name>, mint: Term<Name>,
trace: bool, trace: TraceLevel,
spend_name: String, spend_name: String,
mint_name: String, mint_name: String,
) -> Term<Name> { ) -> Term<Name> {
if trace { match trace {
TraceLevel::Silent => Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("__second_arg")))
.delayed_if_then_else(
mint.apply(Term::var("__first_arg"))
.apply(Term::var("__second_arg")),
spend.apply(Term::var("__first_arg")).apply(
Term::head_list()
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("__second_arg"))),
),
)
.lambda("__second_arg")
.lambda("__first_arg"),
TraceLevel::Verbose => {
let trace_string = format!( let trace_string = format!(
"Incorrect redeemer type for validator {}. "Incorrect redeemer type for validator {}.
Double check you have wrapped the redeemer type as specified in your plutus.json", Double check you have wrapped the redeemer type as specified in your plutus.json",
@ -1648,9 +1662,12 @@ pub fn wrap_as_multi_validator(
))), ))),
spend spend
.apply(Term::var("__first_arg")) .apply(Term::var("__first_arg"))
.apply(Term::head_list().apply( .apply(
Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("__second_arg")), Term::head_list().apply(
)) Term::var(CONSTR_FIELDS_EXPOSER)
.apply(Term::var("__second_arg")),
),
)
.delayed_trace(Term::string(format!( .delayed_trace(Term::string(format!(
"Running 3 arg validator {}", "Running 3 arg validator {}",
spend_name spend_name
@ -1665,20 +1682,7 @@ pub fn wrap_as_multi_validator(
.apply(Term::string(trace_string)) .apply(Term::string(trace_string))
.lambda("__second_arg") .lambda("__second_arg")
.lambda("__first_arg") .lambda("__first_arg")
} else { }
Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("__second_arg")))
.delayed_if_then_else(
mint.apply(Term::var("__first_arg"))
.apply(Term::var("__second_arg")),
spend.apply(Term::var("__first_arg")).apply(
Term::head_list()
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("__second_arg"))),
),
)
.lambda("__second_arg")
.lambda("__first_arg")
} }
} }
@ -1717,16 +1721,15 @@ pub fn cast_validator_args(term: Term<Name>, arguments: &[TypedArg]) -> Term<Nam
term term
} }
pub fn wrap_validator_condition(air_tree: AirTree, trace: bool) -> AirTree { pub fn wrap_validator_condition(air_tree: AirTree, trace: TraceLevel) -> AirTree {
let success_branch = vec![(air_tree, AirTree::void())]; let success_branch = vec![(air_tree, AirTree::void())];
let otherwise = if trace { let otherwise = match trace {
AirTree::trace( TraceLevel::Silent => AirTree::error(void(), true),
TraceLevel::Verbose => AirTree::trace(
AirTree::string("Validator returned false"), AirTree::string("Validator returned false"),
void(), void(),
AirTree::error(void(), true), AirTree::error(void(), true),
) ),
} else {
AirTree::error(void(), true)
}; };
AirTree::if_branches(success_branch, void(), otherwise) AirTree::if_branches(success_branch, void(), otherwise)

View File

@ -217,7 +217,11 @@ impl Validator {
mod tests { mod tests {
use std::collections::HashMap; use std::collections::HashMap;
use aiken_lang::{self, builtins}; use aiken_lang::{
self,
ast::{TraceLevel, Tracing},
builtins,
};
use uplc::ast as uplc_ast; use uplc::ast as uplc_ast;
use crate::tests::TestProject; use crate::tests::TestProject;
@ -240,7 +244,7 @@ mod tests {
&project.functions, &project.functions,
&project.data_types, &project.data_types,
&project.module_types, &project.module_types,
true, Tracing::All(TraceLevel::Verbose),
); );
let (validator, def) = modules let (validator, def) = modules

View File

@ -22,10 +22,7 @@ use crate::blueprint::{
Blueprint, Blueprint,
}; };
use aiken_lang::{ use aiken_lang::{
ast::{ ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction, Validator},
Definition, Function, ModuleKind, TraceLevel, Tracing, TypedDataType, TypedFunction,
Validator,
},
builtins, builtins,
gen_uplc::builder::{DataTypeKey, FunctionAccessKey}, gen_uplc::builder::{DataTypeKey, FunctionAccessKey},
tipo::TypeInfo, tipo::TypeInfo,
@ -285,10 +282,7 @@ where
&self.functions, &self.functions,
&self.data_types, &self.data_types,
&self.module_types, &self.module_types,
match options.tracing.trace_level(true) { options.tracing,
TraceLevel::Silent => false,
TraceLevel::Verbose => true,
},
); );
let blueprint = Blueprint::new(&self.config, &self.checked_modules, &mut generator) let blueprint = Blueprint::new(&self.config, &self.checked_modules, &mut generator)
@ -317,15 +311,8 @@ where
verbose, verbose,
exact_match, exact_match,
} => { } => {
let tests = self.collect_tests( let tests =
verbose, self.collect_tests(verbose, match_tests, exact_match, options.tracing)?;
match_tests,
exact_match,
match options.tracing.trace_level(true) {
TraceLevel::Silent => false,
TraceLevel::Verbose => true,
},
)?;
if !tests.is_empty() { if !tests.is_empty() {
self.event_listener.handle_event(Event::RunningTests); self.event_listener.handle_event(Event::RunningTests);
@ -688,7 +675,7 @@ where
verbose: bool, verbose: bool,
match_tests: Option<Vec<String>>, match_tests: Option<Vec<String>>,
exact_match: bool, exact_match: bool,
code_gen_tracing: bool, tracing: Tracing,
) -> Result<Vec<Script>, Error> { ) -> Result<Vec<Script>, Error> {
let mut scripts = Vec::new(); let mut scripts = Vec::new();
let mut testable_validators = Vec::new(); let mut testable_validators = Vec::new();
@ -791,7 +778,7 @@ where
&self.functions, &self.functions,
&self.data_types, &self.data_types,
&self.module_types, &self.module_types,
code_gen_tracing, tracing,
); );
for (module_name, testable_validator) in &testable_validators { for (module_name, testable_validator) in &testable_validators {

View File

@ -1,7 +1,7 @@
use crate::error::Error; use crate::error::Error;
use aiken_lang::{ use aiken_lang::{
ast::{ ast::{
DataType, Definition, Function, Located, ModuleKind, TypedDataType, TypedFunction, DataType, Definition, Function, Located, ModuleKind, Tracing, TypedDataType, TypedFunction,
TypedModule, TypedValidator, UntypedModule, Validator, TypedModule, TypedValidator, UntypedModule, Validator,
}, },
gen_uplc::{ gen_uplc::{
@ -358,7 +358,7 @@ impl CheckedModules {
builtin_functions: &'a IndexMap<FunctionAccessKey, TypedFunction>, builtin_functions: &'a IndexMap<FunctionAccessKey, TypedFunction>,
builtin_data_types: &'a IndexMap<DataTypeKey, TypedDataType>, builtin_data_types: &'a IndexMap<DataTypeKey, TypedDataType>,
module_types: &'a HashMap<String, TypeInfo>, module_types: &'a HashMap<String, TypeInfo>,
tracing: bool, tracing: Tracing,
) -> CodeGenerator<'a> { ) -> CodeGenerator<'a> {
let mut functions = IndexMap::new(); let mut functions = IndexMap::new();
for (k, v) in builtin_functions { for (k, v) in builtin_functions {
@ -412,7 +412,7 @@ impl CheckedModules {
data_types, data_types,
module_types_index, module_types_index,
module_src, module_src,
tracing, tracing.trace_level(true),
) )
} }
} }