Get rid of 'VoidMsg' in favor of an 'Option'.

This commit is contained in:
KtorZ 2024-01-04 17:59:15 +01:00 committed by Kasey
parent c50a9cb5bd
commit 30a6b77116
3 changed files with 86 additions and 53 deletions

View File

@ -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_msg(msg_func_name) Some(self.special_functions.use_function_msg(msg_func_name))
} else { } else {
AirMsg::Void None
}; };
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: AirMsg::Void, msg_func: None,
}, },
); );
@ -1027,7 +1027,8 @@ impl<'a> CodeGenerator<'a> {
tipo.clone(), tipo.clone(),
tail.is_some(), tail.is_some(),
value, value,
Some(props.msg_func), props.msg_func,
true,
) )
}; };
@ -1180,12 +1181,12 @@ impl<'a> CodeGenerator<'a> {
if check_replaceable_opaque_type(tipo, &self.data_types) { if check_replaceable_opaque_type(tipo, &self.data_types) {
sequence.push(AirTree::let_assignment(&indices[0].1, value)); sequence.push(AirTree::let_assignment(&indices[0].1, value));
} else { } else {
let msg = if props.full_check { let (is_expect, msg) = if props.full_check {
Some(props.msg_func) (true, props.msg_func)
} else { } else {
None (false, None)
}; };
sequence.push(AirTree::fields_expose(indices, value, msg)); sequence.push(AirTree::fields_expose(indices, value, msg, is_expect));
} }
sequence.append( sequence.append(
@ -1266,15 +1267,21 @@ impl<'a> CodeGenerator<'a> {
let indices = elems.iter().map(|(name, _)| name.to_string()).collect_vec(); let indices = elems.iter().map(|(name, _)| name.to_string()).collect_vec();
let msg = if props.full_check { let (is_expect, msg) = if props.full_check {
Some(props.msg_func) (true, props.msg_func)
} else { } else {
None (false, None)
}; };
// This `value` is either value param that was passed in or // This `value` is either value param that was passed in or
// local var // local var
sequence.push(AirTree::tuple_access(indices, tipo.clone(), value, msg)); sequence.push(AirTree::tuple_access(
indices,
tipo.clone(),
value,
msg,
is_expect,
));
sequence.append(&mut elems.into_iter().map(|(_, field)| field).collect_vec()); sequence.append(&mut elems.into_iter().map(|(_, field)| field).collect_vec());
@ -1289,7 +1296,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: AirMsg, msg_func: Option<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);
@ -1317,6 +1324,7 @@ impl<'a> CodeGenerator<'a> {
inner_list_type.clone(), inner_list_type.clone(),
AirTree::local_var(&pair_name, inner_list_type.clone()), AirTree::local_var(&pair_name, inner_list_type.clone()),
None, None,
false,
); );
let expect_fst = self.expect_type_assign( let expect_fst = self.expect_type_assign(
@ -1469,6 +1477,7 @@ impl<'a> CodeGenerator<'a> {
tipo.clone(), tipo.clone(),
AirTree::local_var(pair_name, tipo.clone()), AirTree::local_var(pair_name, tipo.clone()),
None, None,
false,
); );
let expect_fst = self.expect_type_assign( let expect_fst = self.expect_type_assign(
@ -1534,7 +1543,8 @@ impl<'a> CodeGenerator<'a> {
tuple_index_names, tuple_index_names,
tipo.clone(), tipo.clone(),
AirTree::local_var(tuple_name, tipo.clone()), AirTree::local_var(tuple_name, tipo.clone()),
Some(msg_func), msg_func,
true,
); );
let mut tuple_expects = tuple_expect_items let mut tuple_expects = tuple_expect_items
@ -1580,15 +1590,15 @@ impl<'a> CodeGenerator<'a> {
let msg = AirMsg::LocalVar("__param_msg".to_string()); let msg = AirMsg::LocalVar("__param_msg".to_string());
( (
msg.clone(), Some(msg.clone()),
AirTree::trace( AirTree::trace(
msg.to_air_tree().unwrap(), msg.to_air_tree(),
tipo.clone(), tipo.clone(),
AirTree::error(tipo.clone(), false), AirTree::error(tipo.clone(), false),
), ),
) )
} else { } else {
(msg_func.clone(), AirTree::error(tipo.clone(), false)) (None, AirTree::error(tipo.clone(), false))
}; };
defined_data_types.insert(data_type_name.clone(), 1); defined_data_types.insert(data_type_name.clone(), 1);
@ -1659,7 +1669,8 @@ impl<'a> CodeGenerator<'a> {
), ),
tipo.clone(), tipo.clone(),
), ),
Some(msg_term.clone()), msg_term.clone(),
true,
); );
assigns.insert(0, expose); assigns.insert(0, expose);
@ -1727,7 +1738,12 @@ impl<'a> CodeGenerator<'a> {
} }
let args = if self.tracing { let args = if self.tracing {
vec![value, msg_func.to_air_tree().unwrap()] vec![
value,
msg_func
.expect("should be unreachable: no msg func with tracing enabled.")
.to_air_tree(),
]
} else { } else {
vec![value] vec![value]
}; };
@ -2255,6 +2271,7 @@ impl<'a> CodeGenerator<'a> {
// So for the msg we pass in empty string if tracing is on // So for the msg we pass in empty string if tracing is on
// Since check_last_item is false this will never get added to the final uplc anyway // Since check_last_item is false this will never get added to the final uplc anyway
None, None,
false,
) )
} else { } else {
assert!(defined_tails.len() >= defined_heads.len()); assert!(defined_tails.len() >= defined_heads.len());
@ -2398,6 +2415,7 @@ impl<'a> CodeGenerator<'a> {
subject_tipo.clone(), subject_tipo.clone(),
), ),
None, None,
false,
) )
}; };
@ -2532,6 +2550,7 @@ impl<'a> CodeGenerator<'a> {
subject_tipo.clone(), subject_tipo.clone(),
AirTree::local_var(&props.original_subject_name, subject_tipo.clone()), AirTree::local_var(&props.original_subject_name, subject_tipo.clone()),
None, None,
false,
), ),
); );
} }
@ -2744,9 +2763,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_msg(msg_func_name) Some(self.special_functions.use_function_msg(msg_func_name))
} else { } else {
AirMsg::Void None
}; };
let assign = self.assignment( let assign = self.assignment(

View File

@ -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: AirMsg, pub msg_func: Option<AirMsg>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View File

@ -92,17 +92,15 @@ impl Default for IndexCounter {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum AirMsg { pub enum AirMsg {
Void,
LocalVar(String), LocalVar(String),
Msg(String), Msg(String),
} }
impl AirMsg { impl AirMsg {
pub fn to_air_tree(&self) -> Option<AirTree> { pub fn to_air_tree(&self) -> AirTree {
match self { match self {
AirMsg::Void => None, AirMsg::LocalVar(name) => AirTree::local_var(name, string()),
AirMsg::LocalVar(name) => Some(AirTree::local_var(name, string())), AirMsg::Msg(msg) => AirTree::string(msg),
AirMsg::Msg(msg) => Some(AirTree::string(msg)),
} }
} }
} }
@ -144,12 +142,12 @@ pub enum AirStatement {
AssertConstr { AssertConstr {
constr_index: usize, constr_index: usize,
constr: Box<AirTree>, constr: Box<AirTree>,
msg: AirMsg, msg: Option<AirMsg>,
}, },
AssertBool { AssertBool {
is_true: bool, is_true: bool,
value: Box<AirTree>, value: Box<AirTree>,
msg: AirMsg, msg: Option<AirMsg>,
}, },
// Clause Guards // Clause Guards
ClauseGuard { ClauseGuard {
@ -172,6 +170,7 @@ pub enum AirStatement {
FieldsExpose { FieldsExpose {
indices: Vec<(usize, String, Rc<Type>)>, indices: Vec<(usize, String, Rc<Type>)>,
record: Box<AirTree>, record: Box<AirTree>,
is_expect: bool,
msg: Option<AirMsg>, msg: Option<AirMsg>,
}, },
// List Access // List Access
@ -180,6 +179,7 @@ pub enum AirStatement {
names: Vec<String>, names: Vec<String>,
tail: bool, tail: bool,
list: Box<AirTree>, list: Box<AirTree>,
is_expect: bool,
msg: Option<AirMsg>, msg: Option<AirMsg>,
}, },
ListExpose { ListExpose {
@ -192,16 +192,17 @@ pub enum AirStatement {
names: Vec<String>, names: Vec<String>,
tipo: Rc<Type>, tipo: Rc<Type>,
tuple: Box<AirTree>, tuple: Box<AirTree>,
is_expect: bool,
msg: Option<AirMsg>, msg: Option<AirMsg>,
}, },
// Misc. // Misc.
FieldsEmpty { FieldsEmpty {
constr: Box<AirTree>, constr: Box<AirTree>,
msg: AirMsg, msg: Option<AirMsg>,
}, },
ListEmpty { ListEmpty {
list: Box<AirTree>, list: Box<AirTree>,
msg: AirMsg, msg: Option<AirMsg>,
}, },
NoOp, NoOp,
} }
@ -513,7 +514,11 @@ impl AirTree {
value: value.into(), value: value.into(),
}) })
} }
pub fn assert_constr_index(constr_index: usize, constr: AirTree, msg: AirMsg) -> AirTree { pub fn assert_constr_index(
constr_index: usize,
constr: AirTree,
msg: Option<AirMsg>,
) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::AssertConstr { statement: AirStatement::AssertConstr {
constr_index, constr_index,
@ -523,7 +528,7 @@ impl AirTree {
hoisted_over: None, hoisted_over: None,
} }
} }
pub fn assert_bool(is_true: bool, value: AirTree, msg: AirMsg) -> AirTree { pub fn assert_bool(is_true: bool, value: AirTree, msg: Option<AirMsg>) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::AssertBool { statement: AirStatement::AssertBool {
is_true, is_true,
@ -735,12 +740,14 @@ impl AirTree {
indices: Vec<(usize, String, Rc<Type>)>, indices: Vec<(usize, String, Rc<Type>)>,
record: AirTree, record: AirTree,
msg: Option<AirMsg>, msg: Option<AirMsg>,
is_expect: bool,
) -> AirTree { ) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::FieldsExpose { statement: AirStatement::FieldsExpose {
indices, indices,
record: record.into(), record: record.into(),
msg, msg,
is_expect,
}, },
hoisted_over: None, hoisted_over: None,
} }
@ -751,6 +758,7 @@ impl AirTree {
tail: bool, tail: bool,
list: AirTree, list: AirTree,
msg: Option<AirMsg>, msg: Option<AirMsg>,
is_expect: bool,
) -> AirTree { ) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::ListAccessor { statement: AirStatement::ListAccessor {
@ -758,6 +766,7 @@ impl AirTree {
names, names,
tail, tail,
list: list.into(), list: list.into(),
is_expect,
msg, msg,
}, },
hoisted_over: None, hoisted_over: None,
@ -782,6 +791,7 @@ impl AirTree {
tipo: Rc<Type>, tipo: Rc<Type>,
tuple: AirTree, tuple: AirTree,
msg: Option<AirMsg>, msg: Option<AirMsg>,
is_expect: bool,
) -> AirTree { ) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::TupleAccessor { statement: AirStatement::TupleAccessor {
@ -789,6 +799,7 @@ impl AirTree {
tipo, tipo,
tuple: tuple.into(), tuple: tuple.into(),
msg, msg,
is_expect,
}, },
hoisted_over: None, hoisted_over: None,
} }
@ -823,7 +834,7 @@ impl AirTree {
hoisted_over: None, hoisted_over: None,
} }
} }
pub fn fields_empty(constr: AirTree, msg: AirMsg) -> AirTree { pub fn fields_empty(constr: AirTree, msg: Option<AirMsg>) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::FieldsEmpty { statement: AirStatement::FieldsEmpty {
constr: constr.into(), constr: constr.into(),
@ -832,7 +843,7 @@ impl AirTree {
hoisted_over: None, hoisted_over: None,
} }
} }
pub fn list_empty(list: AirTree, msg: AirMsg) -> AirTree { pub fn list_empty(list: AirTree, msg: Option<AirMsg>) -> AirTree {
AirTree::Statement { AirTree::Statement {
statement: AirStatement::ListEmpty { statement: AirStatement::ListEmpty {
list: list.into(), list: list.into(),
@ -980,8 +991,8 @@ 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() { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
constr.create_air_vec(air_vec); constr.create_air_vec(air_vec);
@ -993,8 +1004,8 @@ impl AirTree {
} => { } => {
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() { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
value.create_air_vec(air_vec); value.create_air_vec(air_vec);
@ -1039,14 +1050,15 @@ impl AirTree {
indices, indices,
record, record,
msg, msg,
is_expect,
} => { } => {
air_vec.push(Air::FieldsExpose { air_vec.push(Air::FieldsExpose {
indices: indices.clone(), indices: indices.clone(),
is_expect: msg.is_some(), is_expect: *is_expect,
}); });
if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
record.create_air_vec(air_vec); record.create_air_vec(air_vec);
@ -1057,16 +1069,17 @@ impl AirTree {
tail, tail,
list, list,
msg, msg,
is_expect,
} => { } => {
air_vec.push(Air::ListAccessor { air_vec.push(Air::ListAccessor {
tipo: tipo.clone(), tipo: tipo.clone(),
names: names.clone(), names: names.clone(),
tail: *tail, tail: *tail,
is_expect: msg.is_some(), is_expect: *is_expect,
}); });
if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
list.create_air_vec(air_vec); list.create_air_vec(air_vec);
@ -1087,15 +1100,16 @@ impl AirTree {
tipo, tipo,
tuple, tuple,
msg, msg,
is_expect,
} => { } => {
air_vec.push(Air::TupleAccessor { air_vec.push(Air::TupleAccessor {
names: names.clone(), names: names.clone(),
tipo: tipo.clone(), tipo: tipo.clone(),
is_expect: msg.is_some(), is_expect: *is_expect,
}); });
if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
tuple.create_air_vec(air_vec); tuple.create_air_vec(air_vec);
@ -1106,8 +1120,8 @@ 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() { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
constr.create_air_vec(air_vec); constr.create_air_vec(air_vec);
@ -1115,8 +1129,8 @@ impl AirTree {
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() { if let Some(msg) = msg {
msg.create_air_vec(air_vec); msg.to_air_tree().create_air_vec(air_vec);
} }
list.create_air_vec(air_vec); list.create_air_vec(air_vec);