refactor: convert msgs to use AirMsg type instead of AirTree

This commit is contained in:
microproofs 2024-01-04 11:24:59 -05:00 committed by Kasey
parent 394cac86b8
commit c50a9cb5bd
4 changed files with 108 additions and 82 deletions

View File

@ -46,7 +46,7 @@ use self::{
AssignmentProperties, ClauseProperties, CodeGenSpecialFuncs, CycleFunctionNames, AssignmentProperties, ClauseProperties, CodeGenSpecialFuncs, CycleFunctionNames,
DataTypeKey, FunctionAccessKey, HoistableFunction, Variant, DataTypeKey, FunctionAccessKey, HoistableFunction, Variant,
}, },
tree::{AirExpression, AirTree, TreePath}, tree::{AirExpression, AirMsg, AirTree, TreePath},
}; };
#[derive(Clone)] #[derive(Clone)]
@ -479,9 +479,9 @@ impl<'a> CodeGenerator<'a> {
); );
let msg_func = if self.tracing && kind.is_expect() { 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 { } else {
AirTree::void_msg() AirMsg::Void
}; };
self.assignment( self.assignment(
@ -534,7 +534,7 @@ impl<'a> CodeGenerator<'a> {
kind: AssignmentKind::Let, kind: AssignmentKind::Let,
remove_unused: false, remove_unused: false,
full_check: false, full_check: false,
msg_func: AirTree::void_msg(), msg_func: AirMsg::Void,
}, },
); );
@ -1289,7 +1289,7 @@ impl<'a> CodeGenerator<'a> {
value: AirTree, value: AirTree,
defined_data_types: &mut IndexMap<String, u64>, defined_data_types: &mut IndexMap<String, u64>,
location: Span, location: Span,
msg_func: AirTree, msg_func: AirMsg,
) -> AirTree { ) -> AirTree {
assert!(tipo.get_generic().is_none()); assert!(tipo.get_generic().is_none());
let tipo = &convert_opaque_type(tipo, &self.data_types); 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 // 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) = if self.tracing {
let msg = AirTree::local_var("__param_msg", string()); let msg = AirMsg::LocalVar("__param_msg".to_string());
( (
msg.clone(), 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 { } else {
(msg_func.clone(), AirTree::error(tipo.clone(), false)) (msg_func.clone(), AirTree::error(tipo.clone(), false))
@ -1722,29 +1726,17 @@ impl<'a> CodeGenerator<'a> {
defined_data_types.insert(data_type_name.to_string(), 1); defined_data_types.insert(data_type_name.to_string(), 1);
} }
if self.tracing { let args = if self.tracing {
let module_fn = ValueConstructorVariant::ModuleFn { vec![value, msg_func.to_air_tree().unwrap()]
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])
} else { } else {
vec![value]
};
let module_fn = ValueConstructorVariant::ModuleFn { let module_fn = ValueConstructorVariant::ModuleFn {
name: data_type_name.to_string(), name: data_type_name.to_string(),
field_map: None, field_map: None,
module: "".to_string(), module: "".to_string(),
arity: 1, arity: args.len(),
location, location,
builtin: None, builtin: None,
}; };
@ -1755,8 +1747,7 @@ impl<'a> CodeGenerator<'a> {
"", "",
); );
AirTree::call(func_var, void(), vec![value]) AirTree::call(func_var, void(), args)
}
} }
} }
@ -2753,9 +2744,9 @@ impl<'a> CodeGenerator<'a> {
); );
let msg_func = if self.tracing && !actual_type.is_data() { 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 { } else {
AirTree::void_msg() AirMsg::Void
}; };
let assign = self.assignment( let assign = self.assignment(
@ -5255,7 +5246,7 @@ impl<'a> CodeGenerator<'a> {
} }
} }
Air::NoOp | Air::VoidMsg => {} Air::NoOp => {}
} }
} }
} }

View File

@ -183,5 +183,4 @@ pub enum Air {
NoOp, NoOp,
FieldsEmpty, FieldsEmpty,
ListEmpty, ListEmpty,
VoidMsg,
} }

View File

@ -30,7 +30,7 @@ use crate::{
use super::{ use super::{
air::Air, air::Air,
tree::{AirExpression, AirStatement, AirTree, TreePath}, tree::{AirExpression, AirMsg, AirStatement, AirTree, TreePath},
}; };
pub type Variant = String; pub type Variant = String;
@ -85,7 +85,7 @@ pub struct AssignmentProperties {
pub kind: AssignmentKind, pub kind: AssignmentKind,
pub remove_unused: bool, pub remove_unused: bool,
pub full_check: bool, pub full_check: bool,
pub msg_func: AirTree, pub msg_func: AirMsg,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -246,6 +246,14 @@ impl CodeGenSpecialFuncs {
AirTree::local_var(func_name, tipo) 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 { pub fn use_function_uplc(&mut self, func_name: String) -> String {
if !self.used_funcs.contains(&func_name) { if !self.used_funcs.contains(&func_name) {
self.used_funcs.push(func_name.to_string()); self.used_funcs.push(func_name.to_string());

View File

@ -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<AirTree> {
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)] #[derive(Debug, Clone, PartialEq)]
pub enum AirTree { pub enum AirTree {
Statement { Statement {
@ -127,12 +144,12 @@ pub enum AirStatement {
AssertConstr { AssertConstr {
constr_index: usize, constr_index: usize,
constr: Box<AirTree>, constr: Box<AirTree>,
msg: Box<AirTree>, msg: AirMsg,
}, },
AssertBool { AssertBool {
is_true: bool, is_true: bool,
value: Box<AirTree>, value: Box<AirTree>,
msg: Box<AirTree>, msg: AirMsg,
}, },
// Clause Guards // Clause Guards
ClauseGuard { ClauseGuard {
@ -155,7 +172,7 @@ pub enum AirStatement {
FieldsExpose { FieldsExpose {
indices: Vec<(usize, String, Rc<Type>)>, indices: Vec<(usize, String, Rc<Type>)>,
record: Box<AirTree>, record: Box<AirTree>,
msg: Box<Option<AirTree>>, msg: Option<AirMsg>,
}, },
// List Access // List Access
ListAccessor { ListAccessor {
@ -163,7 +180,7 @@ pub enum AirStatement {
names: Vec<String>, names: Vec<String>,
tail: bool, tail: bool,
list: Box<AirTree>, list: Box<AirTree>,
msg: Box<Option<AirTree>>, msg: Option<AirMsg>,
}, },
ListExpose { ListExpose {
tipo: Rc<Type>, tipo: Rc<Type>,
@ -175,16 +192,16 @@ pub enum AirStatement {
names: Vec<String>, names: Vec<String>,
tipo: Rc<Type>, tipo: Rc<Type>,
tuple: Box<AirTree>, tuple: Box<AirTree>,
msg: Box<Option<AirTree>>, msg: Option<AirMsg>,
}, },
// Misc. // Misc.
FieldsEmpty { FieldsEmpty {
constr: Box<AirTree>, constr: Box<AirTree>,
msg: Box<AirTree>, msg: AirMsg,
}, },
ListEmpty { ListEmpty {
list: Box<AirTree>, list: Box<AirTree>,
msg: Box<AirTree>, msg: AirMsg,
}, },
NoOp, NoOp,
} }
@ -332,7 +349,6 @@ pub enum AirExpression {
msg: Box<AirTree>, msg: Box<AirTree>,
then: Box<AirTree>, then: Box<AirTree>,
}, },
VoidMsg,
} }
impl AirTree { impl AirTree {
@ -497,22 +513,22 @@ impl AirTree {
value: value.into(), 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 { AirTree::Statement {
statement: AirStatement::AssertConstr { statement: AirStatement::AssertConstr {
constr_index, constr_index,
constr: constr.into(), constr: constr.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, 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 { AirTree::Statement {
statement: AirStatement::AssertBool { statement: AirStatement::AssertBool {
is_true, is_true,
value: value.into(), value: value.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, hoisted_over: None,
} }
@ -718,13 +734,13 @@ impl AirTree {
pub fn fields_expose( pub fn fields_expose(
indices: Vec<(usize, String, Rc<Type>)>, indices: Vec<(usize, String, Rc<Type>)>,
record: AirTree, record: AirTree,
msg: Option<AirTree>, msg: Option<AirMsg>,
) -> AirTree { ) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::FieldsExpose { statement: AirStatement::FieldsExpose {
indices, indices,
record: record.into(), record: record.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, hoisted_over: None,
} }
@ -734,7 +750,7 @@ impl AirTree {
tipo: Rc<Type>, tipo: Rc<Type>,
tail: bool, tail: bool,
list: AirTree, list: AirTree,
msg: Option<AirTree>, msg: Option<AirMsg>,
) -> AirTree { ) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::ListAccessor { statement: AirStatement::ListAccessor {
@ -742,7 +758,7 @@ impl AirTree {
names, names,
tail, tail,
list: list.into(), list: list.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, hoisted_over: None,
} }
@ -765,14 +781,14 @@ impl AirTree {
names: Vec<String>, names: Vec<String>,
tipo: Rc<Type>, tipo: Rc<Type>,
tuple: AirTree, tuple: AirTree,
msg: Option<AirTree>, msg: Option<AirMsg>,
) -> AirTree { ) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::TupleAccessor { statement: AirStatement::TupleAccessor {
names, names,
tipo, tipo,
tuple: tuple.into(), tuple: tuple.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, hoisted_over: None,
} }
@ -807,27 +823,24 @@ impl AirTree {
hoisted_over: None, hoisted_over: None,
} }
} }
pub fn fields_empty(constr: AirTree, msg: AirTree) -> AirTree { pub fn fields_empty(constr: AirTree, msg: AirMsg) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::FieldsEmpty { statement: AirStatement::FieldsEmpty {
constr: constr.into(), constr: constr.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, hoisted_over: None,
} }
} }
pub fn list_empty(list: AirTree, msg: AirTree) -> AirTree { pub fn list_empty(list: AirTree, msg: AirMsg) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::ListEmpty { statement: AirStatement::ListEmpty {
list: list.into(), list: list.into(),
msg: msg.into(), msg,
}, },
hoisted_over: None, hoisted_over: None,
} }
} }
pub fn void_msg() -> AirTree {
AirTree::Expression(AirExpression::VoidMsg)
}
pub fn hoist_over(mut self, next_exp: AirTree) -> AirTree { pub fn hoist_over(mut self, next_exp: AirTree) -> AirTree {
match &mut self { match &mut self {
@ -966,7 +979,11 @@ impl AirTree {
}); });
// msg is first so we can pop it off first in uplc_gen // msg is first so we can pop it off first in uplc_gen
// if traces are on // if traces are on
if let Some(msg) = msg.to_air_tree() {
msg.create_air_vec(air_vec); msg.create_air_vec(air_vec);
}
constr.create_air_vec(air_vec); constr.create_air_vec(air_vec);
} }
AirStatement::AssertBool { AirStatement::AssertBool {
@ -975,7 +992,11 @@ impl AirTree {
msg, msg,
} => { } => {
air_vec.push(Air::AssertBool { is_true: *is_true }); air_vec.push(Air::AssertBool { is_true: *is_true });
if let Some(msg) = msg.to_air_tree() {
msg.create_air_vec(air_vec); msg.create_air_vec(air_vec);
}
value.create_air_vec(air_vec); value.create_air_vec(air_vec);
} }
AirStatement::ClauseGuard { AirStatement::ClauseGuard {
@ -1024,9 +1045,9 @@ impl AirTree {
is_expect: msg.is_some(), 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); msg.create_air_vec(air_vec);
}); }
record.create_air_vec(air_vec); record.create_air_vec(air_vec);
} }
@ -1044,9 +1065,9 @@ impl AirTree {
is_expect: msg.is_some(), 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); msg.create_air_vec(air_vec);
}); }
list.create_air_vec(air_vec); list.create_air_vec(air_vec);
} }
@ -1073,9 +1094,9 @@ impl AirTree {
is_expect: msg.is_some(), 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); msg.create_air_vec(air_vec);
}); }
tuple.create_air_vec(air_vec); tuple.create_air_vec(air_vec);
} }
@ -1084,12 +1105,20 @@ impl AirTree {
} }
AirStatement::FieldsEmpty { constr, msg } => { AirStatement::FieldsEmpty { constr, msg } => {
air_vec.push(Air::FieldsEmpty); air_vec.push(Air::FieldsEmpty);
if let Some(msg) = msg.to_air_tree() {
msg.create_air_vec(air_vec); msg.create_air_vec(air_vec);
}
constr.create_air_vec(air_vec); constr.create_air_vec(air_vec);
} }
AirStatement::ListEmpty { list, msg } => { AirStatement::ListEmpty { list, msg } => {
air_vec.push(Air::ListEmpty); air_vec.push(Air::ListEmpty);
if let Some(msg) = msg.to_air_tree() {
msg.create_air_vec(air_vec); msg.create_air_vec(air_vec);
}
list.create_air_vec(air_vec); list.create_air_vec(air_vec);
} }
}; };
@ -1317,7 +1346,6 @@ impl AirTree {
msg.create_air_vec(air_vec); msg.create_air_vec(air_vec);
then.create_air_vec(air_vec); then.create_air_vec(air_vec);
} }
AirExpression::VoidMsg => air_vec.push(Air::VoidMsg),
}, },
AirTree::UnhoistedSequence(_) => { AirTree::UnhoistedSequence(_) => {
unreachable!("FIRST RESOLVE ALL UNHOISTED SEQUENCES") unreachable!("FIRST RESOLVE ALL UNHOISTED SEQUENCES")
@ -1350,7 +1378,7 @@ impl AirTree {
| AirExpression::RecordUpdate { tipo, .. } | AirExpression::RecordUpdate { tipo, .. }
| AirExpression::ErrorTerm { tipo, .. } | AirExpression::ErrorTerm { tipo, .. }
| AirExpression::Trace { tipo, .. } => tipo.clone(), | AirExpression::Trace { tipo, .. } => tipo.clone(),
AirExpression::Void | AirExpression::VoidMsg => void(), AirExpression::Void => void(),
AirExpression::Var { constructor, .. } => constructor.tipo.clone(), AirExpression::Var { constructor, .. } => constructor.tipo.clone(),
AirExpression::Fn { func_body, .. } => func_body.return_type(), AirExpression::Fn { func_body, .. } => func_body.return_type(),
AirExpression::UnOp { op, .. } => match op { AirExpression::UnOp { op, .. } => match op {