got past the errors and warnings

This commit is contained in:
microproofs 2024-02-04 16:35:32 -05:00 committed by Kasey
parent 51f1da2505
commit 6c6be3f53d
2 changed files with 252 additions and 252 deletions

View File

@ -50,7 +50,7 @@ use self::{
AssignmentProperties, ClauseProperties, CodeGenSpecialFuncs, CycleFunctionNames,
DataTypeKey, FunctionAccessKey, HoistableFunction, Variant,
},
tree::{AirExpression, AirMsg, AirTree, TreePath},
tree::{AirMsg, AirTree, TreePath},
};
#[derive(Clone)]
@ -141,7 +141,7 @@ impl<'a> CodeGenerator<'a> {
let mut validator_args_tree =
self.check_validator_args(&fun.arguments, true, air_tree_fun, &src_code, &lines);
validator_args_tree = AirTree::no_op().hoist_over(validator_args_tree);
validator_args_tree = AirTree::no_op(validator_args_tree);
let full_tree = self.hoist_functions_to_validator(validator_args_tree);
@ -166,7 +166,7 @@ impl<'a> CodeGenerator<'a> {
&lines,
);
validator_args_tree_other = AirTree::no_op().hoist_over(validator_args_tree_other);
validator_args_tree_other = AirTree::no_op(validator_args_tree_other);
let full_tree_other = self.hoist_functions_to_validator(validator_args_tree_other);
@ -201,7 +201,7 @@ impl<'a> CodeGenerator<'a> {
pub fn generate_test(&mut self, test_body: &TypedExpr, module_name: &String) -> Program<Name> {
let mut air_tree = self.build(test_body, module_name, &[]);
air_tree = AirTree::no_op().hoist_over(air_tree);
air_tree = AirTree::no_op(air_tree);
let full_tree = self.hoist_functions_to_validator(air_tree);
@ -849,9 +849,7 @@ impl<'a> CodeGenerator<'a> {
) -> AirTree {
assert!(
match &value {
AirTree::Expression(AirExpression::Var { name, .. })
if props.kind == AssignmentKind::Let =>
{
AirTree::Var { name, .. } if props.kind == AssignmentKind::Let => {
name != "_"
}
_ => true,
@ -889,7 +887,7 @@ impl<'a> CodeGenerator<'a> {
let expr = AirTree::let_assignment(name, value, expect);
AirTree::assert_bool(true, expr, props.msg_func.clone()).hoist_over(then)
AirTree::assert_bool(true, expr, props.msg_func.clone(), then)
}
Pattern::Var { name, .. } => {
@ -956,7 +954,7 @@ impl<'a> CodeGenerator<'a> {
} else if !props.remove_unused {
AirTree::let_assignment(name, value, then)
} else {
AirTree::no_op().hoist_over(then)
AirTree::no_op(then)
}
}
Pattern::List { elements, tail, .. } => {
@ -1067,8 +1065,8 @@ impl<'a> CodeGenerator<'a> {
elems.reverse();
let list_access = if elements.is_empty() {
AirTree::list_empty(value, props.msg_func)
if elements.is_empty() {
AirTree::list_empty(value, props.msg_func, then)
} else {
AirTree::list_access(
elems,
@ -1081,10 +1079,9 @@ impl<'a> CodeGenerator<'a> {
} else {
ExpectLevel::Items
},
then,
)
};
list_access.hoist_over(then)
}
}
Pattern::Constructor {
arguments,
@ -1095,7 +1092,7 @@ impl<'a> CodeGenerator<'a> {
if tipo.is_bool() {
assert!(props.kind.is_expect());
AirTree::assert_bool(name == "True", value, props.msg_func).hoist_over(then)
AirTree::assert_bool(name == "True", value, props.msg_func, then)
} else if tipo.is_void() {
AirTree::let_assignment("_", value, then)
} else {
@ -1201,7 +1198,7 @@ impl<'a> CodeGenerator<'a> {
} else {
(false, None)
};
AirTree::fields_expose(fields, local_value, msg, is_expect).hoist_over(then)
AirTree::fields_expose(fields, local_value, msg, is_expect, then)
};
// TODO: See if we can combine these two if-conditions;
@ -1223,13 +1220,12 @@ impl<'a> CodeGenerator<'a> {
panic!("Found constructor type {} with 0 constructors", name)
});
let assert_constr = AirTree::assert_constr_index(
AirTree::assert_constr_index(
index,
AirTree::local_var(&constructor_name, tipo.clone()),
props.msg_func,
);
assert_constr.hoist_over(then)
then,
)
} else {
then
}
@ -1314,10 +1310,8 @@ impl<'a> CodeGenerator<'a> {
};
// This `value` is either value param that was passed in or local var
let tuple_access =
AirTree::tuple_access(fields, tipo.clone(), value, msg, is_expect);
tuple_access.hoist_over(then)
AirTree::tuple_access(fields, tipo.clone(), value, msg, is_expect, then)
}
}
}
@ -1349,17 +1343,9 @@ impl<'a> CodeGenerator<'a> {
let fst_name = format!("__pair_fst_span_{}_{}", location.start, location.end);
let snd_name = format!("__pair_snd_span_{}_{}", location.start, location.end);
let tuple_access = AirTree::tuple_access(
vec![fst_name.clone(), snd_name.clone()],
inner_list_type.clone(),
AirTree::local_var(&pair_name, inner_list_type.clone()),
msg_func.clone(),
msg_func.is_some(),
);
let expect_fst = self.expect_type_assign(
&inner_pair_types[0],
AirTree::local_var(fst_name, inner_pair_types[0].clone()),
AirTree::local_var(fst_name.clone(), inner_pair_types[0].clone()),
defined_data_types,
location,
msg_func.clone(),
@ -1367,14 +1353,20 @@ impl<'a> CodeGenerator<'a> {
let expect_snd = self.expect_type_assign(
&inner_pair_types[1],
AirTree::local_var(snd_name, inner_pair_types[1].clone()),
AirTree::local_var(snd_name.clone(), inner_pair_types[1].clone()),
defined_data_types,
location,
msg_func.clone(),
);
let anon_func_body =
tuple_access.hoist_over(AirTree::let_assignment("_", expect_fst, expect_snd));
let anon_func_body = AirTree::tuple_access(
vec![fst_name, snd_name],
inner_list_type.clone(),
AirTree::local_var(&pair_name, inner_list_type.clone()),
msg_func.clone(),
msg_func.is_some(),
AirTree::let_assignment("_", expect_fst, expect_snd),
);
let unwrap_function = AirTree::anon_func(vec![pair_name], anon_func_body);
@ -1499,17 +1491,9 @@ impl<'a> CodeGenerator<'a> {
let fst_name = format!("__pair_fst_span_{}_{}", location.start, location.end);
let snd_name = format!("__pair_snd_span_{}_{}", location.start, location.end);
let tuple_access = AirTree::tuple_access(
vec![fst_name.clone(), snd_name.clone()],
tipo.clone(),
AirTree::local_var(&pair_name, tipo.clone()),
msg_func.clone(),
msg_func.is_some(),
);
let expect_fst = self.expect_type_assign(
&tuple_inner_types[0],
AirTree::local_var(fst_name, tuple_inner_types[0].clone()),
AirTree::local_var(fst_name.clone(), tuple_inner_types[0].clone()),
defined_data_types,
location,
msg_func.clone(),
@ -1517,17 +1501,22 @@ impl<'a> CodeGenerator<'a> {
let expect_snd = self.expect_type_assign(
&tuple_inner_types[1],
AirTree::local_var(snd_name, tuple_inner_types[1].clone()),
AirTree::local_var(snd_name.clone(), tuple_inner_types[1].clone()),
defined_data_types,
location,
msg_func,
msg_func.clone(),
);
AirTree::let_assignment(
&pair_name,
value,
tuple_access.hoist_over(AirTree::let_assignment("_", expect_fst, expect_snd)),
)
let tuple_access = AirTree::tuple_access(
vec![fst_name, snd_name],
tipo.clone(),
AirTree::local_var(&pair_name, tipo.clone()),
msg_func.clone(),
msg_func.is_some(),
AirTree::let_assignment("_", expect_fst, expect_snd),
);
AirTree::let_assignment(&pair_name, value, tuple_access)
} else if tipo.is_tuple() {
let tuple_inner_types = tipo.get_inner_types();
@ -1567,10 +1556,9 @@ impl<'a> CodeGenerator<'a> {
AirTree::local_var(&tuple_name, tipo.clone()),
msg_func,
true,
then,
);
let tuple_access = tuple_access.hoist_over(then);
AirTree::let_assignment(&tuple_name, value, tuple_access)
// Constructor
@ -1653,7 +1641,7 @@ impl<'a> CodeGenerator<'a> {
);
constr_args.reverse();
let assign = if constr_args.is_empty() {
let then = if constr_args.is_empty() {
AirTree::fields_empty(
AirTree::local_var(
format!(
@ -1663,6 +1651,7 @@ impl<'a> CodeGenerator<'a> {
tipo.clone(),
),
msg_term.clone(),
constr_then,
)
} else {
AirTree::fields_expose(
@ -1676,11 +1665,10 @@ impl<'a> CodeGenerator<'a> {
),
msg_term.clone(),
true,
constr_then,
)
};
let then = assign.hoist_over(constr_then);
AirTree::clause(
format!("__subject_span_{}_{}", location.start, location.end),
AirTree::int(index),
@ -1796,8 +1784,12 @@ impl<'a> CodeGenerator<'a> {
clause_then = AirTree::let_assignment(
&clause_guard_name,
builder::handle_clause_guard(guard),
AirTree::clause_guard(&clause_guard_name, AirTree::bool(true), bool())
.hoist_over(clause_then),
AirTree::clause_guard(
&clause_guard_name,
AirTree::bool(true),
bool(),
clause_then,
),
);
}
@ -2279,6 +2271,7 @@ impl<'a> CodeGenerator<'a> {
// Since check_last_item is false this will never get added to the final uplc anyway
None,
ExpectLevel::None,
elems_then,
)
} else {
assert!(defined_tails.len() >= elems.len());
@ -2292,10 +2285,11 @@ impl<'a> CodeGenerator<'a> {
.collect_vec(),
list_tail,
subject_tipo.clone(),
elems_then,
)
};
(AirTree::void(), list_assign.hoist_over(elems_then))
(AirTree::void(), list_assign)
}
Pattern::Constructor {
name,
@ -2422,8 +2416,8 @@ impl<'a> CodeGenerator<'a> {
),
None,
false,
next_then,
)
.hoist_over(next_then)
};
(AirTree::int(constr_index), field_assign)
@ -2530,7 +2524,7 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(),
}
let tuple_name_assigns = if props.final_clause && !names_to_define.is_empty() {
if props.final_clause && !names_to_define.is_empty() {
names_to_define.sort_by(|(id1, _), (id2, _)| id1.cmp(id2));
let names =
@ -2544,22 +2538,23 @@ impl<'a> CodeGenerator<'a> {
names
});
(
AirTree::void(),
AirTree::tuple_access(
names,
subject_tipo.clone(),
AirTree::local_var(&props.original_subject_name, subject_tipo.clone()),
None,
false,
tuple_name_assigns,
),
)
.hoist_over(tuple_name_assigns)
} else {
tuple_name_assigns
};
(AirTree::void(), tuple_name_assigns)
}
}
}
}
fn nested_clause_condition(
&self,
@ -2580,8 +2575,12 @@ impl<'a> CodeGenerator<'a> {
match pattern {
Pattern::Int { value, .. } => {
props.complex_clause = true;
AirTree::clause_guard(&props.original_subject_name, AirTree::int(value), int())
.hoist_over(then)
AirTree::clause_guard(
&props.original_subject_name,
AirTree::int(value),
int(),
then,
)
}
Pattern::Var { name, .. } => AirTree::let_assignment(
name,
@ -2609,11 +2608,9 @@ impl<'a> CodeGenerator<'a> {
subject_tipo.clone(),
false,
None,
then,
)
.hoist_over(then)
} else {
let mut clause_assigns = vec![];
let ClauseProperties {
specific_clause:
SpecificClause::ListClause {
@ -2630,6 +2627,25 @@ impl<'a> CodeGenerator<'a> {
defined_tails.push(props.original_subject_name.clone());
for (index, _) in elements.iter().enumerate() {
let tail_name = format!("{tail_name_base}_{index}");
if elements.len() - 1 == index {
if tail.is_none() {
*current_index += 1;
defined_tails.push(tail_name);
}
} else {
*current_index += 1;
defined_tails.push(tail_name);
};
}
let (_, assigns) = self.clause_pattern(pattern, subject_tipo, props, then);
elements
.iter()
.enumerate()
.rfold(assigns, |then, (index, _)| {
let prev_tail_name = if index == 0 {
props.original_subject_name.clone()
} else {
@ -2637,47 +2653,40 @@ impl<'a> CodeGenerator<'a> {
};
let tail_name = format!("{tail_name_base}_{index}");
if elements.len() - 1 == index {
if tail.is_some() {
clause_assigns.push(AirTree::list_clause_guard(
AirTree::list_clause_guard(
prev_tail_name,
subject_tipo.clone(),
true,
None,
));
then,
)
} else {
clause_assigns.push(AirTree::list_clause_guard(
AirTree::list_clause_guard(
prev_tail_name,
subject_tipo.clone(),
true,
Some(tail_name.to_string()),
));
clause_assigns.push(AirTree::list_clause_guard(
AirTree::list_clause_guard(
tail_name.to_string(),
subject_tipo.clone(),
false,
None,
));
*current_index += 1;
defined_tails.push(tail_name);
then,
),
)
}
} else {
clause_assigns.push(AirTree::list_clause_guard(
AirTree::list_clause_guard(
prev_tail_name,
subject_tipo.clone(),
true,
Some(tail_name.to_string()),
));
*current_index += 1;
defined_tails.push(tail_name);
};
then,
)
}
let (_, assigns) = self.clause_pattern(pattern, subject_tipo, props, then);
AirTree::UnhoistedSequence(clause_assigns).hoist_over(assigns)
})
}
}
Pattern::Constructor {
@ -2689,8 +2698,8 @@ impl<'a> CodeGenerator<'a> {
&props.original_subject_name,
AirTree::bool(constr_name == "True"),
bool(),
then,
)
.hoist_over(then)
} else {
let (cond, assign) =
self.clause_pattern(pattern, subject_tipo, props, then);
@ -2706,8 +2715,8 @@ impl<'a> CodeGenerator<'a> {
&props.original_subject_name,
cond,
subject_tipo.clone(),
assign,
)
.hoist_over(assign)
}
}
}
@ -2721,13 +2730,12 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(),
};
let tuple_access = AirTree::tuple_clause_guard(
AirTree::tuple_clause_guard(
&props.original_subject_name,
subject_tipo.clone(),
defined_indices,
);
tuple_access.hoist_over(assign)
assign,
)
}
}
}
@ -3215,7 +3223,9 @@ impl<'a> CodeGenerator<'a> {
func_params.clone()
};
body = AirTree::define_func(
let node_to_edit = air_tree.find_air_tree_node(tree_path);
let defined_function = AirTree::define_func(
&key.function_name,
&key.module_name,
variant,
@ -3223,36 +3233,34 @@ impl<'a> CodeGenerator<'a> {
is_recursive,
recursive_nonstatics,
body,
node_to_edit.clone(),
);
let function_deps = self.hoist_dependent_functions(
let defined_dependencies = self.hoist_dependent_functions(
deps,
params_empty,
key,
variant,
(key, variant),
hoisted_functions,
functions_to_hoist,
defined_function,
);
let node_to_edit = air_tree.find_air_tree_node(tree_path);
// now hoist full function onto validator tree
*node_to_edit = function_deps.hoist_over(body.hoist_over(node_to_edit.clone()));
*node_to_edit = defined_dependencies;
hoisted_functions.push((key.clone(), variant.clone()));
} else {
body = self
.hoist_dependent_functions(
let defined_func = self.hoist_dependent_functions(
deps,
params_empty,
key,
variant,
(key, variant),
hoisted_functions,
functions_to_hoist,
)
.hoist_over(body);
body,
);
self.zero_arg_functions
.insert((key.clone(), variant.clone()), body.to_vec());
.insert((key.clone(), variant.clone()), defined_func.to_vec());
}
}
HoistableFunction::CyclicFunction {
@ -3269,27 +3277,28 @@ impl<'a> CodeGenerator<'a> {
modify_cyclic_calls(body, key, &self.cyclic_functions);
}
let cyclic_body = AirTree::define_cyclic_func(
let node_to_edit = air_tree.find_air_tree_node(tree_path);
let cyclic_func = AirTree::define_cyclic_func(
&key.function_name,
&key.module_name,
variant,
functions,
node_to_edit.clone(),
);
let function_deps = self.hoist_dependent_functions(
let defined_dependencies = self.hoist_dependent_functions(
deps,
// cyclic functions always have params
false,
key,
variant,
(key, variant),
hoisted_functions,
functions_to_hoist,
cyclic_func,
);
let node_to_edit = air_tree.find_air_tree_node(tree_path);
// now hoist full function onto validator tree
*node_to_edit =
function_deps.hoist_over(cyclic_body.hoist_over(node_to_edit.clone()));
*node_to_edit = defined_dependencies;
hoisted_functions.push((key.clone(), variant.clone()));
}
@ -3306,21 +3315,20 @@ impl<'a> CodeGenerator<'a> {
&mut self,
deps: (&TreePath, Vec<(FunctionAccessKey, String)>),
params_empty: bool,
key: &FunctionAccessKey,
variant: &String,
func_key_variant: (&FunctionAccessKey, &Variant),
hoisted_functions: &mut Vec<(FunctionAccessKey, String)>,
functions_to_hoist: &IndexMap<
FunctionAccessKey,
IndexMap<String, (TreePath, HoistableFunction)>,
>,
air_tree: AirTree,
) -> AirTree {
let (key, variant) = func_key_variant;
let (func_path, func_deps) = deps;
let mut deps_vec = func_deps;
let mut sorted_dep_vec = vec![];
let mut dep_insertions = vec![];
while let Some(dep) = deps_vec.pop() {
let function_variants = functions_to_hoist
.get(&dep.0)
@ -3369,10 +3377,10 @@ impl<'a> CodeGenerator<'a> {
}
sorted_dep_vec.dedup();
sorted_dep_vec.reverse();
// This part handles hoisting dependencies
while let Some((dep_key, dep_variant)) = sorted_dep_vec.pop() {
sorted_dep_vec
.into_iter()
.fold(air_tree, |then, (dep_key, dep_variant)| {
if (!params_empty
// if the dependency is the same as the function we're hoisting
// or we hoisted it, then skip it
@ -3381,7 +3389,7 @@ impl<'a> CodeGenerator<'a> {
}))
|| (&dep_key == key && &dep_variant == variant)
{
continue;
return then;
}
let dependency = functions_to_hoist
@ -3393,6 +3401,8 @@ impl<'a> CodeGenerator<'a> {
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
// In the case of zero args, we need to hoist the dependency function to the top of the zero arg function
// The dependency we are hoisting should have an equal path to the function we hoisted
// if we are going to hoist it
if &dep_path.common_ancestor(func_path) == func_path || params_empty {
match dep_function.clone() {
HoistableFunction::Function {
@ -3402,7 +3412,7 @@ impl<'a> CodeGenerator<'a> {
} => {
if dependent_params.is_empty() {
// continue for zero arg functions. They are treated like global hoists.
continue;
return then;
}
let is_dependent_recursive = dependency_deps
@ -3420,7 +3430,11 @@ impl<'a> CodeGenerator<'a> {
dependent_params.clone()
};
dep_insertions.push(AirTree::define_func(
if !params_empty {
hoisted_functions.push((dep_key.clone(), dep_variant.clone()));
}
AirTree::define_func(
&dep_key.function_name,
&dep_key.module_name,
&dep_variant,
@ -3428,11 +3442,8 @@ impl<'a> CodeGenerator<'a> {
is_dependent_recursive,
recursive_nonstatics,
dep_air_tree,
));
if !params_empty {
hoisted_functions.push((dep_key.clone(), dep_variant.clone()));
}
then,
)
}
HoistableFunction::CyclicFunction { functions, .. } => {
let mut functions = functions.clone();
@ -3441,26 +3452,25 @@ impl<'a> CodeGenerator<'a> {
modify_cyclic_calls(body, &dep_key, &self.cyclic_functions);
}
dep_insertions.push(AirTree::define_cyclic_func(
if !params_empty {
hoisted_functions.push((dep_key.clone(), dep_variant.clone()));
}
AirTree::define_cyclic_func(
&dep_key.function_name,
&dep_key.module_name,
&dep_variant,
functions,
));
if !params_empty {
hoisted_functions.push((dep_key.clone(), dep_variant.clone()));
}
then,
)
}
HoistableFunction::Link(_) => unreachable!(),
HoistableFunction::CyclicLink(_) => unreachable!(),
}
} else {
then
}
}
dep_insertions.reverse();
AirTree::UnhoistedSequence(dep_insertions)
})
}
fn define_dependent_functions(
@ -3520,11 +3530,11 @@ impl<'a> CodeGenerator<'a> {
current_depth,
depth_index,
&mut |air_tree, tree_path| {
if let AirTree::Expression(AirExpression::Var {
if let AirTree::Var {
constructor,
variant_name,
..
}) = air_tree
} = air_tree
{
let ValueConstructorVariant::ModuleFn {
name: func_name,

View File

@ -432,6 +432,8 @@ impl AirTree {
args,
}
}
#[allow(clippy::too_many_arguments)]
pub fn define_func(
func_name: impl ToString,
module_name: impl ToString,
@ -1160,9 +1162,7 @@ impl AirTree {
AirTree::ByteArray { bytes } => air_vec.push(Air::ByteArray {
bytes: bytes.clone(),
}),
AirTree::CurvePoint { point } => air_vec.push(Air::CurvePoint {
point: point.clone(),
}),
AirTree::CurvePoint { point } => air_vec.push(Air::CurvePoint { point: *point }),
AirTree::Bool { value } => air_vec.push(Air::Bool { value: *value }),
AirTree::List { tipo, tail, items } => {
air_vec.push(Air::List {
@ -1212,7 +1212,7 @@ impl AirTree {
AirTree::Builtin { func, tipo, args } => {
air_vec.push(Air::Builtin {
count: args.len(),
func: func.clone(),
func: *func,
tipo: tipo.clone(),
});
@ -1613,15 +1613,7 @@ impl AirTree {
apply_with_func_last,
),
AirTree::TupleClause {
subject_tipo,
indices,
predefined_indices,
subject_name,
complex_clause,
then,
otherwise,
} => {
AirTree::TupleClause { otherwise, .. } => {
tuple_then_index = Some(index_count.next_number());
otherwise.do_traverse_tree_with(
tree_path,
@ -1670,9 +1662,7 @@ impl AirTree {
apply_with_func_last,
);
}
AirTree::TupleClause {
then, otherwise, ..
} => {
AirTree::TupleClause { then, .. } => {
let Some(index) = tuple_then_index else {
unreachable!()
};