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,
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<String, u64>,
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 => {}
}
}
}

View File

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

View File

@ -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());

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)]
pub enum AirTree {
Statement {
@ -127,12 +144,12 @@ pub enum AirStatement {
AssertConstr {
constr_index: usize,
constr: Box<AirTree>,
msg: Box<AirTree>,
msg: AirMsg,
},
AssertBool {
is_true: bool,
value: Box<AirTree>,
msg: Box<AirTree>,
msg: AirMsg,
},
// Clause Guards
ClauseGuard {
@ -155,7 +172,7 @@ pub enum AirStatement {
FieldsExpose {
indices: Vec<(usize, String, Rc<Type>)>,
record: Box<AirTree>,
msg: Box<Option<AirTree>>,
msg: Option<AirMsg>,
},
// List Access
ListAccessor {
@ -163,7 +180,7 @@ pub enum AirStatement {
names: Vec<String>,
tail: bool,
list: Box<AirTree>,
msg: Box<Option<AirTree>>,
msg: Option<AirMsg>,
},
ListExpose {
tipo: Rc<Type>,
@ -175,16 +192,16 @@ pub enum AirStatement {
names: Vec<String>,
tipo: Rc<Type>,
tuple: Box<AirTree>,
msg: Box<Option<AirTree>>,
msg: Option<AirMsg>,
},
// Misc.
FieldsEmpty {
constr: Box<AirTree>,
msg: Box<AirTree>,
msg: AirMsg,
},
ListEmpty {
list: Box<AirTree>,
msg: Box<AirTree>,
msg: AirMsg,
},
NoOp,
}
@ -332,7 +349,6 @@ pub enum AirExpression {
msg: Box<AirTree>,
then: Box<AirTree>,
},
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<Type>)>,
record: AirTree,
msg: Option<AirTree>,
msg: Option<AirMsg>,
) -> 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<Type>,
tail: bool,
list: AirTree,
msg: Option<AirTree>,
msg: Option<AirMsg>,
) -> 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<String>,
tipo: Rc<Type>,
tuple: AirTree,
msg: Option<AirTree>,
msg: Option<AirMsg>,
) -> 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 {