diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 3ca4eb72..92f2b425 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -41,7 +41,7 @@ use crate::{ use self::{ air::Air, builder::{ - cast_validator_args, constants_ir, convert_type_to_data, extract_constant, + air_holds_msg, cast_validator_args, constants_ir, convert_type_to_data, extract_constant, lookup_data_type_by_tipo, modify_cyclic_calls, modify_self_calls, rearrange_list_clauses, AssignmentProperties, ClauseProperties, CodeGenSpecialFuncs, CycleFunctionNames, DataTypeKey, FunctionAccessKey, HoistableFunction, Variant, @@ -3680,6 +3680,16 @@ impl<'a> CodeGenerator<'a> { fn gen_uplc(&mut self, ir: Air, arg_stack: &mut Vec>) { // Going to mark the changes made to code gen after air tree implementation + let error_term = if self.tracing && air_holds_msg(&ir) { + // In the case of an air that holds a msg and tracing is active + // we pop the msg off the stack first + let msg = arg_stack.pop().unwrap(); + + Term::Error.delayed_trace(msg) + } else { + Term::Error + }; + match ir { Air::Int { value } => { arg_stack.push(Term::integer(value.parse().unwrap())); @@ -3966,13 +3976,6 @@ impl<'a> CodeGenerator<'a> { } => { let value = arg_stack.pop().unwrap(); - let error_term = if self.tracing && is_expect { - let msg = arg_stack.pop().unwrap(); - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); let list_id = self.id_gen.next(); @@ -4495,13 +4498,6 @@ impl<'a> CodeGenerator<'a> { Air::AssertConstr { constr_index } => { let constr = arg_stack.pop().unwrap(); - let trace_term = if self.tracing { - let msg = arg_stack.pop().unwrap(); - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); term = Term::equals_integer() @@ -4513,27 +4509,19 @@ impl<'a> CodeGenerator<'a> { ) .apply(constr), ) - .delayed_if_then_else(term, trace_term); + .delayed_if_then_else(term, error_term); arg_stack.push(term); } Air::AssertBool { is_true } => { let value = arg_stack.pop().unwrap(); - let trace_term = if self.tracing { - let msg = arg_stack.pop().unwrap(); - - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); if is_true { - term = value.delayed_if_then_else(term, trace_term) + term = value.delayed_if_then_else(term, error_term) } else { - term = value.delayed_if_then_else(trace_term, term) + term = value.delayed_if_then_else(error_term, term) } arg_stack.push(term); } @@ -4911,13 +4899,6 @@ impl<'a> CodeGenerator<'a> { let value = arg_stack.pop().unwrap(); - let error_term = if self.tracing && is_expect { - let msg = arg_stack.pop().unwrap(); - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); let list_id = self.id_gen.next(); @@ -4972,13 +4953,6 @@ impl<'a> CodeGenerator<'a> { Air::FieldsEmpty => { let value = arg_stack.pop().unwrap(); - let error_term = if self.tracing { - let msg = arg_stack.pop().unwrap(); - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); term = Term::var( @@ -4993,13 +4967,6 @@ impl<'a> CodeGenerator<'a> { Air::ListEmpty => { let value = arg_stack.pop().unwrap(); - let error_term = if self.tracing { - let msg = arg_stack.pop().unwrap(); - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); term = value.delayed_choose_list(term, error_term); @@ -5190,13 +5157,6 @@ impl<'a> CodeGenerator<'a> { let inner_types = tipo.get_inner_types(); let value = arg_stack.pop().unwrap(); - let error_term = if self.tracing && is_expect && !tipo.is_2_tuple() { - let msg = arg_stack.pop().unwrap(); - Term::Error.delayed_trace(msg) - } else { - Term::Error - }; - let mut term = arg_stack.pop().unwrap(); let list_id = self.id_gen.next(); diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 76d603cf..7232d529 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -28,7 +28,10 @@ use crate::{ tipo::Type, }; -use super::tree::{AirExpression, AirStatement, AirTree, TreePath}; +use super::{ + air::Air, + tree::{AirExpression, AirStatement, AirTree, TreePath}, +}; pub type Variant = String; @@ -1883,3 +1886,16 @@ pub fn get_src_code_by_span( .expect("Out of bounds span") .to_string() } + +pub fn air_holds_msg(air: &Air) -> bool { + match air { + Air::AssertConstr { .. } | Air::AssertBool { .. } | Air::FieldsEmpty | Air::ListEmpty => { + true + } + Air::FieldsExpose { is_expect, .. } + | Air::ListAccessor { is_expect, .. } + | Air::TupleAccessor { is_expect, .. } => *is_expect, + + _ => false, + } +} diff --git a/crates/aiken-lang/src/gen_uplc/tree.rs b/crates/aiken-lang/src/gen_uplc/tree.rs index 6c4675ac..2eede818 100644 --- a/crates/aiken-lang/src/gen_uplc/tree.rs +++ b/crates/aiken-lang/src/gen_uplc/tree.rs @@ -959,8 +959,10 @@ impl AirTree { air_vec.push(Air::AssertConstr { constr_index: *constr_index, }); - constr.create_air_vec(air_vec); + // msg is first so we can pop it off first in uplc_gen + // if traces are on msg.create_air_vec(air_vec); + constr.create_air_vec(air_vec); } AirStatement::AssertBool { is_true, @@ -968,8 +970,8 @@ impl AirTree { msg, } => { air_vec.push(Air::AssertBool { is_true: *is_true }); - value.create_air_vec(air_vec); msg.create_air_vec(air_vec); + value.create_air_vec(air_vec); } AirStatement::ClauseGuard { subject_name, @@ -1016,10 +1018,12 @@ impl AirTree { indices: indices.clone(), is_expect: msg.is_some(), }); - record.create_air_vec(air_vec); + msg.iter().for_each(|msg| { msg.create_air_vec(air_vec); }); + + record.create_air_vec(air_vec); } AirStatement::ListAccessor { tipo, @@ -1034,10 +1038,12 @@ impl AirTree { tail: *tail, is_expect: msg.is_some(), }); - list.create_air_vec(air_vec); + msg.iter().for_each(|msg| { msg.create_air_vec(air_vec); }); + + list.create_air_vec(air_vec); } AirStatement::ListExpose { tipo, @@ -1061,23 +1067,25 @@ impl AirTree { tipo: tipo.clone(), is_expect: msg.is_some(), }); - tuple.create_air_vec(air_vec); + msg.iter().for_each(|msg| { msg.create_air_vec(air_vec); }); + + tuple.create_air_vec(air_vec); } AirStatement::NoOp => { air_vec.push(Air::NoOp); } AirStatement::FieldsEmpty { constr, msg } => { air_vec.push(Air::FieldsEmpty); - constr.create_air_vec(air_vec); msg.create_air_vec(air_vec); + constr.create_air_vec(air_vec); } AirStatement::ListEmpty { list, msg } => { air_vec.push(Air::ListEmpty); - list.create_air_vec(air_vec); msg.create_air_vec(air_vec); + list.create_air_vec(air_vec); } }; exp.create_air_vec(air_vec);