From 46d779763ba0d1428c4f65fe0ec284b3152986fc Mon Sep 17 00:00:00 2001 From: microproofs Date: Thu, 4 Jan 2024 11:24:59 -0500 Subject: [PATCH] refactor: convert msgs to use AirMsg type instead of AirTree --- crates/aiken-lang/src/gen_uplc.rs | 75 +++++++--------- crates/aiken-lang/src/gen_uplc/air.rs | 1 - crates/aiken-lang/src/gen_uplc/builder.rs | 12 ++- crates/aiken-lang/src/gen_uplc/tree.rs | 102 ++++++++++++++-------- 4 files changed, 108 insertions(+), 82 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index afdc6efcd..4aa2ad297 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -46,7 +46,7 @@ use self::{ AssignmentProperties, ClauseProperties, CodeGenSpecialFuncs, CycleFunctionNames, DataTypeKey, FunctionAccessKey, HoistableFunction, Variant, }, - tree::{AirExpression, AirTree, TreePath}, + tree::{AirExpression, AirMsg, AirTree, TreePath}, }; #[derive(Clone)] @@ -479,9 +479,9 @@ impl<'a> CodeGenerator<'a> { ); let msg_func = if self.tracing && kind.is_expect() { - self.special_functions.use_function_tree(msg_func_name) + self.special_functions.use_function_msg(msg_func_name) } else { - AirTree::void_msg() + AirMsg::Void }; self.assignment( @@ -534,7 +534,7 @@ impl<'a> CodeGenerator<'a> { kind: AssignmentKind::Let, remove_unused: false, full_check: false, - msg_func: AirTree::void_msg(), + msg_func: AirMsg::Void, }, ); @@ -1289,7 +1289,7 @@ impl<'a> CodeGenerator<'a> { value: AirTree, defined_data_types: &mut IndexMap, location: Span, - msg_func: AirTree, + msg_func: AirMsg, ) -> AirTree { assert!(tipo.get_generic().is_none()); let tipo = &convert_opaque_type(tipo, &self.data_types); @@ -1577,11 +1577,15 @@ impl<'a> CodeGenerator<'a> { // 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() { let (msg_term, error_term) = if self.tracing { - let msg = AirTree::local_var("__param_msg", string()); + let msg = AirMsg::LocalVar("__param_msg".to_string()); ( msg.clone(), - AirTree::trace(msg, tipo.clone(), AirTree::error(tipo.clone(), false)), + AirTree::trace( + msg.to_air_tree().unwrap(), + tipo.clone(), + AirTree::error(tipo.clone(), false), + ), ) } else { (msg_func.clone(), AirTree::error(tipo.clone(), false)) @@ -1722,41 +1726,28 @@ impl<'a> CodeGenerator<'a> { defined_data_types.insert(data_type_name.to_string(), 1); } - if self.tracing { - let module_fn = ValueConstructorVariant::ModuleFn { - name: data_type_name.to_string(), - field_map: None, - module: "".to_string(), - arity: 2, - location, - builtin: None, - }; - - let func_var = AirTree::var( - ValueConstructor::public(tipo.clone(), module_fn), - data_type_name, - "", - ); - - AirTree::call(func_var, void(), vec![value, msg_func]) + let args = if self.tracing { + vec![value, msg_func.to_air_tree().unwrap()] } else { - let module_fn = ValueConstructorVariant::ModuleFn { - name: data_type_name.to_string(), - field_map: None, - module: "".to_string(), - arity: 1, - location, - builtin: None, - }; + vec![value] + }; - let func_var = AirTree::var( - ValueConstructor::public(tipo.clone(), module_fn), - data_type_name, - "", - ); + let module_fn = ValueConstructorVariant::ModuleFn { + name: data_type_name.to_string(), + field_map: None, + module: "".to_string(), + arity: args.len(), + location, + builtin: None, + }; - AirTree::call(func_var, void(), vec![value]) - } + let func_var = AirTree::var( + ValueConstructor::public(tipo.clone(), module_fn), + data_type_name, + "", + ); + + AirTree::call(func_var, void(), args) } } @@ -2753,9 +2744,9 @@ impl<'a> CodeGenerator<'a> { ); let msg_func = if self.tracing && !actual_type.is_data() { - self.special_functions.use_function_tree(msg_func_name) + self.special_functions.use_function_msg(msg_func_name) } else { - AirTree::void_msg() + AirMsg::Void }; let assign = self.assignment( @@ -5255,7 +5246,7 @@ impl<'a> CodeGenerator<'a> { } } - Air::NoOp | Air::VoidMsg => {} + Air::NoOp => {} } } } diff --git a/crates/aiken-lang/src/gen_uplc/air.rs b/crates/aiken-lang/src/gen_uplc/air.rs index 02f6c1288..3ad00a913 100644 --- a/crates/aiken-lang/src/gen_uplc/air.rs +++ b/crates/aiken-lang/src/gen_uplc/air.rs @@ -183,5 +183,4 @@ pub enum Air { NoOp, FieldsEmpty, ListEmpty, - VoidMsg, } diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 7232d529f..41110b728 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -30,7 +30,7 @@ use crate::{ use super::{ air::Air, - tree::{AirExpression, AirStatement, AirTree, TreePath}, + tree::{AirExpression, AirMsg, AirStatement, AirTree, TreePath}, }; pub type Variant = String; @@ -85,7 +85,7 @@ pub struct AssignmentProperties { pub kind: AssignmentKind, pub remove_unused: bool, pub full_check: bool, - pub msg_func: AirTree, + pub msg_func: AirMsg, } #[derive(Clone, Debug)] @@ -246,6 +246,14 @@ impl CodeGenSpecialFuncs { AirTree::local_var(func_name, tipo) } + pub fn use_function_msg(&mut self, func_name: String) -> AirMsg { + if !self.used_funcs.contains(&func_name) { + self.used_funcs.push(func_name.to_string()); + } + + AirMsg::LocalVar(func_name) + } + pub fn use_function_uplc(&mut self, func_name: String) -> String { if !self.used_funcs.contains(&func_name) { self.used_funcs.push(func_name.to_string()); diff --git a/crates/aiken-lang/src/gen_uplc/tree.rs b/crates/aiken-lang/src/gen_uplc/tree.rs index 1fff0af3a..c4f391c61 100644 --- a/crates/aiken-lang/src/gen_uplc/tree.rs +++ b/crates/aiken-lang/src/gen_uplc/tree.rs @@ -90,6 +90,23 @@ impl Default for IndexCounter { } } +#[derive(Debug, Clone, PartialEq)] +pub enum AirMsg { + Void, + LocalVar(String), + Msg(String), +} + +impl AirMsg { + pub fn to_air_tree(&self) -> Option { + match self { + AirMsg::Void => None, + AirMsg::LocalVar(name) => Some(AirTree::local_var(name, string())), + AirMsg::Msg(msg) => Some(AirTree::string(msg)), + } + } +} + #[derive(Debug, Clone, PartialEq)] pub enum AirTree { Statement { @@ -127,12 +144,12 @@ pub enum AirStatement { AssertConstr { constr_index: usize, constr: Box, - msg: Box, + msg: AirMsg, }, AssertBool { is_true: bool, value: Box, - msg: Box, + msg: AirMsg, }, // Clause Guards ClauseGuard { @@ -155,7 +172,7 @@ pub enum AirStatement { FieldsExpose { indices: Vec<(usize, String, Rc)>, record: Box, - msg: Box>, + msg: Option, }, // List Access ListAccessor { @@ -163,7 +180,7 @@ pub enum AirStatement { names: Vec, tail: bool, list: Box, - msg: Box>, + msg: Option, }, ListExpose { tipo: Rc, @@ -175,16 +192,16 @@ pub enum AirStatement { names: Vec, tipo: Rc, tuple: Box, - msg: Box>, + msg: Option, }, // Misc. FieldsEmpty { constr: Box, - msg: Box, + msg: AirMsg, }, ListEmpty { list: Box, - msg: Box, + msg: AirMsg, }, NoOp, } @@ -332,7 +349,6 @@ pub enum AirExpression { msg: Box, then: Box, }, - VoidMsg, } impl AirTree { @@ -497,22 +513,22 @@ impl AirTree { value: value.into(), }) } - pub fn assert_constr_index(constr_index: usize, constr: AirTree, msg: AirTree) -> AirTree { + pub fn assert_constr_index(constr_index: usize, constr: AirTree, msg: AirMsg) -> AirTree { AirTree::Statement { statement: AirStatement::AssertConstr { constr_index, constr: constr.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } } - pub fn assert_bool(is_true: bool, value: AirTree, msg: AirTree) -> AirTree { + pub fn assert_bool(is_true: bool, value: AirTree, msg: AirMsg) -> AirTree { AirTree::Statement { statement: AirStatement::AssertBool { is_true, value: value.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } @@ -718,13 +734,13 @@ impl AirTree { pub fn fields_expose( indices: Vec<(usize, String, Rc)>, record: AirTree, - msg: Option, + msg: Option, ) -> AirTree { AirTree::Statement { statement: AirStatement::FieldsExpose { indices, record: record.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } @@ -734,7 +750,7 @@ impl AirTree { tipo: Rc, tail: bool, list: AirTree, - msg: Option, + msg: Option, ) -> AirTree { AirTree::Statement { statement: AirStatement::ListAccessor { @@ -742,7 +758,7 @@ impl AirTree { names, tail, list: list.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } @@ -765,14 +781,14 @@ impl AirTree { names: Vec, tipo: Rc, tuple: AirTree, - msg: Option, + msg: Option, ) -> AirTree { AirTree::Statement { statement: AirStatement::TupleAccessor { names, tipo, tuple: tuple.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } @@ -807,27 +823,24 @@ impl AirTree { hoisted_over: None, } } - pub fn fields_empty(constr: AirTree, msg: AirTree) -> AirTree { + pub fn fields_empty(constr: AirTree, msg: AirMsg) -> AirTree { AirTree::Statement { statement: AirStatement::FieldsEmpty { constr: constr.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } } - pub fn list_empty(list: AirTree, msg: AirTree) -> AirTree { + pub fn list_empty(list: AirTree, msg: AirMsg) -> AirTree { AirTree::Statement { statement: AirStatement::ListEmpty { list: list.into(), - msg: msg.into(), + msg, }, hoisted_over: None, } } - pub fn void_msg() -> AirTree { - AirTree::Expression(AirExpression::VoidMsg) - } pub fn hoist_over(mut self, next_exp: AirTree) -> AirTree { match &mut self { @@ -966,7 +979,11 @@ impl AirTree { }); // msg is first so we can pop it off first in uplc_gen // if traces are on - msg.create_air_vec(air_vec); + + if let Some(msg) = msg.to_air_tree() { + msg.create_air_vec(air_vec); + } + constr.create_air_vec(air_vec); } AirStatement::AssertBool { @@ -975,7 +992,11 @@ impl AirTree { msg, } => { air_vec.push(Air::AssertBool { is_true: *is_true }); - msg.create_air_vec(air_vec); + + if let Some(msg) = msg.to_air_tree() { + msg.create_air_vec(air_vec); + } + value.create_air_vec(air_vec); } AirStatement::ClauseGuard { @@ -1024,9 +1045,9 @@ impl AirTree { is_expect: msg.is_some(), }); - msg.iter().for_each(|msg| { + if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { msg.create_air_vec(air_vec); - }); + } record.create_air_vec(air_vec); } @@ -1044,9 +1065,9 @@ impl AirTree { is_expect: msg.is_some(), }); - msg.iter().for_each(|msg| { + if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { msg.create_air_vec(air_vec); - }); + } list.create_air_vec(air_vec); } @@ -1073,9 +1094,9 @@ impl AirTree { is_expect: msg.is_some(), }); - msg.iter().for_each(|msg| { + if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { msg.create_air_vec(air_vec); - }); + } tuple.create_air_vec(air_vec); } @@ -1084,12 +1105,20 @@ impl AirTree { } AirStatement::FieldsEmpty { constr, msg } => { air_vec.push(Air::FieldsEmpty); - msg.create_air_vec(air_vec); + + if let Some(msg) = msg.to_air_tree() { + msg.create_air_vec(air_vec); + } + constr.create_air_vec(air_vec); } AirStatement::ListEmpty { list, msg } => { air_vec.push(Air::ListEmpty); - msg.create_air_vec(air_vec); + + if let Some(msg) = msg.to_air_tree() { + msg.create_air_vec(air_vec); + } + list.create_air_vec(air_vec); } }; @@ -1317,7 +1346,6 @@ impl AirTree { msg.create_air_vec(air_vec); then.create_air_vec(air_vec); } - AirExpression::VoidMsg => air_vec.push(Air::VoidMsg), }, AirTree::UnhoistedSequence(_) => { unreachable!("FIRST RESOLVE ALL UNHOISTED SEQUENCES") @@ -1350,7 +1378,7 @@ impl AirTree { | AirExpression::RecordUpdate { tipo, .. } | AirExpression::ErrorTerm { tipo, .. } | AirExpression::Trace { tipo, .. } => tipo.clone(), - AirExpression::Void | AirExpression::VoidMsg => void(), + AirExpression::Void => void(), AirExpression::Var { constructor, .. } => constructor.tipo.clone(), AirExpression::Fn { func_body, .. } => func_body.return_type(), AirExpression::UnOp { op, .. } => match op {