Fixed remaining issue when all parameters passed in to a recursive function were static.

Also fixed issue where modifying the calls in the airtree lead to an out of bounds index.
This commit is contained in:
microproofs 2024-09-12 16:57:45 -04:00
parent 30e66be568
commit 362ca2544f
No known key found for this signature in database
GPG Key ID: 14F93C84DE6AFD17
3 changed files with 182 additions and 485 deletions

View File

@ -3507,12 +3507,9 @@ impl<'a> CodeGenerator<'a> {
let mut validator_hoistable; let mut validator_hoistable;
// TODO change subsequent tree traversals to be more like a stream. // TODO change subsequent tree traversals to be more like a stream.
air_tree.traverse_tree_with( air_tree.traverse_tree_with(&mut |air_tree: &mut AirTree, _| {
&mut |air_tree: &mut AirTree, _| { erase_opaque_type_operations(air_tree, &self.data_types);
erase_opaque_type_operations(air_tree, &self.data_types); });
},
true,
);
self.find_function_vars_and_depth( self.find_function_vars_and_depth(
&mut air_tree, &mut air_tree,
@ -4234,12 +4231,9 @@ impl<'a> CodeGenerator<'a> {
let mut body = AirTree::no_op(body.clone()); let mut body = AirTree::no_op(body.clone());
body.traverse_tree_with( body.traverse_tree_with(&mut |air_tree, _| {
&mut |air_tree, _| { erase_opaque_type_operations(air_tree, &self.data_types);
erase_opaque_type_operations(air_tree, &self.data_types); });
},
true,
);
function_variant_path.insert( function_variant_path.insert(
"".to_string(), "".to_string(),
@ -4331,13 +4325,10 @@ impl<'a> CodeGenerator<'a> {
&[], &[],
)); ));
function_air_tree_body.traverse_tree_with( function_air_tree_body.traverse_tree_with(&mut |air_tree, _| {
&mut |air_tree, _| { erase_opaque_type_operations(air_tree, &self.data_types);
erase_opaque_type_operations(air_tree, &self.data_types); monomorphize(air_tree, &mono_types);
monomorphize(air_tree, &mono_types); });
},
true,
);
args.iter().for_each(|arg| { args.iter().for_each(|arg| {
arg.arg_name.get_variable_name().iter().for_each(|arg| { arg.arg_name.get_variable_name().iter().for_each(|arg| {
@ -4376,13 +4367,10 @@ impl<'a> CodeGenerator<'a> {
&[], &[],
)); ));
function_air_tree_body.traverse_tree_with( function_air_tree_body.traverse_tree_with(&mut |air_tree, _| {
&mut |air_tree, _| { erase_opaque_type_operations(air_tree, &self.data_types);
erase_opaque_type_operations(air_tree, &self.data_types); monomorphize(air_tree, &mono_types);
monomorphize(air_tree, &mono_types); });
},
true,
);
let mut function_variant_path = IndexMap::new(); let mut function_variant_path = IndexMap::new();
@ -4409,7 +4397,6 @@ impl<'a> CodeGenerator<'a> {
} }
} }
}, },
true,
); );
} }
@ -4462,12 +4449,9 @@ impl<'a> CodeGenerator<'a> {
let mut value = let mut value =
AirTree::no_op(self.build(definition, &access_key.module_name, &[])); AirTree::no_op(self.build(definition, &access_key.module_name, &[]));
value.traverse_tree_with( value.traverse_tree_with(&mut |air_tree, _| {
&mut |air_tree, _| { erase_opaque_type_operations(air_tree, &self.data_types);
erase_opaque_type_operations(air_tree, &self.data_types); });
},
true,
);
value = self.hoist_functions_to_validator(value); value = self.hoist_functions_to_validator(value);
@ -5020,7 +5004,7 @@ impl<'a> CodeGenerator<'a> {
func_body = func_body.lambda(param.clone()); func_body = func_body.lambda(param.clone());
} }
if params.is_empty() { if recursive_nonstatic_params.is_empty() || params.is_empty() {
func_body = func_body.delay(); func_body = func_body.delay();
} }
@ -5048,6 +5032,10 @@ impl<'a> CodeGenerator<'a> {
recursive_func_body = recursive_func_body.apply(Term::var(param)); recursive_func_body = recursive_func_body.apply(Term::var(param));
} }
if recursive_nonstatic_params.is_empty() {
recursive_func_body = recursive_func_body.force();
}
// Then construct an outer function with *all* parameters, not just the nonstatic ones. // Then construct an outer function with *all* parameters, not just the nonstatic ones.
let mut outer_func_body = let mut outer_func_body =
recursive_func_body.lambda(&func_name).apply(func_body); recursive_func_body.lambda(&func_name).apply(func_body);

View File

@ -485,22 +485,20 @@ pub fn modify_self_calls(
func_params: &[String], func_params: &[String],
) -> Vec<String> { ) -> Vec<String> {
let mut potential_recursive_statics = func_params.to_vec(); let mut potential_recursive_statics = func_params.to_vec();
// identify which parameters are recursively nonstatic (i.e. get modified before the self-call) // identify which parameters are recursively nonstatic (i.e. get modified before the self-call)
// TODO: this would be a lot simpler if each `Var`, `Let`, function argument, etc. had a unique identifier // TODO: this would be a lot simpler if each `Var`, `Let`, function argument, etc. had a unique identifier
// rather than just a name; this would let us track if the Var passed to itself was the same value as the method argument // rather than just a name; this would let us track if the Var passed to itself was the same value as the method argument
let mut calls_and_var_usage = (0, 0); let mut calls_and_var_usage = (0, 0);
body.traverse_tree_with( body.traverse_tree_with(&mut |air_tree: &mut AirTree, _tree_path| {
&mut |air_tree: &mut AirTree, _tree_path| { identify_recursive_static_params(
identify_recursive_static_params( air_tree,
air_tree, func_params,
func_params, &(func_key.clone(), variant.clone()),
&(func_key.clone(), variant.clone()), &mut calls_and_var_usage,
&mut calls_and_var_usage, &mut potential_recursive_statics,
&mut potential_recursive_statics, );
); });
},
false,
);
// Find the index of any recursively static parameters, // Find the index of any recursively static parameters,
// so we can remove them from the call-site of each recursive call // so we can remove them from the call-site of each recursive call
@ -512,69 +510,64 @@ pub fn modify_self_calls(
.collect(); .collect();
// Modify any self calls to remove recursive static parameters and append `self` as a parameter for the recursion // Modify any self calls to remove recursive static parameters and append `self` as a parameter for the recursion
body.traverse_tree_with( body.traverse_tree_with(&mut |air_tree: &mut AirTree, _| {
&mut |air_tree: &mut AirTree, _| { if let AirTree::Call {
if let AirTree::Call { func: func_recursive,
func: func_recursive, args,
args, ..
.. } = air_tree
} = air_tree {
{ if let AirTree::Call { func, .. } = func_recursive.as_ref() {
if let AirTree::Call { func, .. } = func_recursive.as_ref() { if let AirTree::Var {
if let AirTree::Var { constructor:
constructor: ValueConstructor {
ValueConstructor { variant: ValueConstructorVariant::ModuleFn { name, module, .. },
variant: ValueConstructorVariant::ModuleFn { name, module, .. }, ..
.. },
}, variant_name,
variant_name, ..
.. } = func.as_ref()
} = func.as_ref() {
// The name must match and the recursive function must not be
// passed around for this optimization to work.
if name == &func_key.function_name
&& module == &func_key.module_name
&& variant == variant_name
&& calls_and_var_usage.0 == calls_and_var_usage.1
{ {
// The name must match and the recursive function must not be // Remove any static-recursive-parameters, because they'll be bound statically
// passed around for this optimization to work. // above the recursive part of the function
if name == &func_key.function_name // note: assumes that static_recursive_params is sorted
&& module == &func_key.module_name for arg in recursive_static_indexes.iter().rev() {
&& variant == variant_name args.remove(*arg);
&& calls_and_var_usage.0 == calls_and_var_usage.1
{
// Remove any static-recursive-parameters, because they'll be bound statically
// above the recursive part of the function
// note: assumes that static_recursive_params is sorted
for arg in recursive_static_indexes.iter().rev() {
args.remove(*arg);
}
args.insert(0, func.as_ref().clone());
*func_recursive = func.as_ref().clone().into();
} }
} }
} }
} else if let AirTree::Var {
constructor:
ValueConstructor {
variant: ValueConstructorVariant::ModuleFn { name, module, .. },
..
},
variant_name,
..
} = &air_tree
{
if name.clone() == func_key.function_name
&& module.clone() == func_key.module_name
&& variant.clone() == variant_name.clone()
{
let self_call = AirTree::call(
air_tree.clone(),
air_tree.return_type(),
vec![air_tree.clone()],
);
*air_tree = self_call;
}
} }
}, } else if let AirTree::Var {
true, constructor:
); ValueConstructor {
variant: ValueConstructorVariant::ModuleFn { name, module, .. },
..
},
variant_name,
..
} = &air_tree
{
if name.clone() == func_key.function_name
&& module.clone() == func_key.module_name
&& variant.clone() == variant_name.clone()
{
let self_call = AirTree::call(
air_tree.clone(),
air_tree.return_type(),
vec![air_tree.clone()],
);
*air_tree = self_call;
}
}
});
// In the case of equal calls to usage we can reduce the static params // In the case of equal calls to usage we can reduce the static params
if calls_and_var_usage.0 == calls_and_var_usage.1 { if calls_and_var_usage.0 == calls_and_var_usage.1 {
@ -597,71 +590,68 @@ pub fn modify_cyclic_calls(
(CycleFunctionNames, usize, FunctionAccessKey), (CycleFunctionNames, usize, FunctionAccessKey),
>, >,
) { ) {
body.traverse_tree_with( body.traverse_tree_with(&mut |air_tree: &mut AirTree, _| {
&mut |air_tree: &mut AirTree, _| { if let AirTree::Var {
if let AirTree::Var { constructor:
constructor: ValueConstructor {
ValueConstructor { variant: ValueConstructorVariant::ModuleFn { name, module, .. },
variant: ValueConstructorVariant::ModuleFn { name, module, .. }, tipo,
tipo, ..
.. },
}, variant_name,
variant_name, ..
.. } = air_tree
} = air_tree {
let tipo = tipo.clone();
let var_key = FunctionAccessKey {
module_name: module.clone(),
function_name: name.clone(),
};
if let Some((names, index, cyclic_name)) =
cyclic_links.get(&(var_key.clone(), variant_name.to_string()))
{ {
let tipo = tipo.clone(); if *cyclic_name == *func_key {
let var_key = FunctionAccessKey { let cyclic_var_name = if cyclic_name.module_name.is_empty() {
module_name: module.clone(), cyclic_name.function_name.to_string()
function_name: name.clone(), } else {
}; format!("{}_{}", cyclic_name.module_name, cyclic_name.function_name)
};
if let Some((names, index, cyclic_name)) = let index_name = names[*index].clone();
cyclic_links.get(&(var_key.clone(), variant_name.to_string()))
{
if *cyclic_name == *func_key {
let cyclic_var_name = if cyclic_name.module_name.is_empty() {
cyclic_name.function_name.to_string()
} else {
format!("{}_{}", cyclic_name.module_name, cyclic_name.function_name)
};
let index_name = names[*index].clone(); let var = AirTree::var(
ValueConstructor::public(
let var = AirTree::var(
ValueConstructor::public(
tipo.clone(),
ValueConstructorVariant::ModuleFn {
name: cyclic_var_name.clone(),
field_map: None,
module: "".to_string(),
arity: 2,
location: Span::empty(),
builtin: None,
},
),
cyclic_var_name,
"".to_string(),
);
*air_tree = AirTree::call(
var.clone(),
tipo.clone(), tipo.clone(),
vec![ ValueConstructorVariant::ModuleFn {
var, name: cyclic_var_name.clone(),
AirTree::anon_func( field_map: None,
names.clone(), module: "".to_string(),
AirTree::local_var(index_name, tipo), arity: 2,
false, location: Span::empty(),
), builtin: None,
], },
); ),
} cyclic_var_name,
"".to_string(),
);
*air_tree = AirTree::call(
var.clone(),
tipo.clone(),
vec![
var,
AirTree::anon_func(
names.clone(),
AirTree::local_var(index_name, tipo),
false,
),
],
);
} }
} }
}, }
true, });
);
} }
pub fn pattern_has_conditions( pub fn pattern_has_conditions(

View File

@ -1810,19 +1810,9 @@ impl AirTree {
} }
} }
pub fn traverse_tree_with( pub fn traverse_tree_with(&mut self, with: &mut impl FnMut(&mut AirTree, &TreePath)) {
&mut self,
with: &mut impl FnMut(&mut AirTree, &TreePath),
apply_with_func_last: bool,
) {
let mut tree_path = TreePath::new(); let mut tree_path = TreePath::new();
self.do_traverse_tree_with( self.do_traverse_tree_with(&mut tree_path, 0, Fields::FirstField, with);
&mut tree_path,
0,
Fields::FirstField,
with,
apply_with_func_last,
);
} }
pub fn traverse_tree_with_path( pub fn traverse_tree_with_path(
@ -1831,9 +1821,8 @@ impl AirTree {
current_depth: usize, current_depth: usize,
depth_index: Fields, depth_index: Fields,
with: &mut impl FnMut(&mut AirTree, &TreePath), with: &mut impl FnMut(&mut AirTree, &TreePath),
apply_with_func_last: bool,
) { ) {
self.do_traverse_tree_with(path, current_depth, depth_index, with, apply_with_func_last); self.do_traverse_tree_with(path, current_depth, depth_index, with);
} }
fn do_traverse_tree_with( fn do_traverse_tree_with(
@ -1842,7 +1831,6 @@ impl AirTree {
current_depth: usize, current_depth: usize,
field_index: Fields, field_index: Fields,
with: &mut impl FnMut(&mut AirTree, &TreePath), with: &mut impl FnMut(&mut AirTree, &TreePath),
apply_with_func_last: bool,
) { ) {
tree_path.push(current_depth, field_index); tree_path.push(current_depth, field_index);
@ -1859,7 +1847,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
} }
@ -1870,20 +1857,13 @@ impl AirTree {
then: _, then: _,
otherwise, otherwise,
} => { } => {
value.do_traverse_tree_with( value.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FifthField, Fields::FifthField,
with, with,
apply_with_func_last,
); );
} }
@ -1898,14 +1878,12 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
) )
} }
AirTree::AssertBool { AirTree::AssertBool {
@ -1919,14 +1897,12 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
) )
} }
AirTree::ClauseGuard { AirTree::ClauseGuard {
@ -1940,7 +1916,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ThirdField, Fields::ThirdField,
with, with,
apply_with_func_last,
); );
} }
@ -1956,14 +1931,12 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FifthField, Fields::FifthField,
with, with,
apply_with_func_last,
) )
} }
AirTree::ListAccessor { AirTree::ListAccessor {
@ -1975,19 +1948,12 @@ impl AirTree {
then: _, then: _,
otherwise, otherwise,
} => { } => {
list.do_traverse_tree_with( list.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FourthField, with);
tree_path,
current_depth + 1,
Fields::FourthField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::SeventhField, Fields::SeventhField,
with, with,
apply_with_func_last,
) )
} }
AirTree::TupleAccessor { AirTree::TupleAccessor {
@ -1998,19 +1964,12 @@ impl AirTree {
then: _, then: _,
otherwise, otherwise,
} => { } => {
tuple.do_traverse_tree_with( tuple.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::SixthField, Fields::SixthField,
with, with,
apply_with_func_last,
) )
} }
AirTree::PairAccessor { AirTree::PairAccessor {
@ -2022,19 +1981,12 @@ impl AirTree {
then: _, then: _,
otherwise, otherwise,
} => { } => {
pair.do_traverse_tree_with( pair.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::SeventhField, Fields::SeventhField,
with, with,
apply_with_func_last,
) )
} }
AirTree::FieldsEmpty { AirTree::FieldsEmpty {
@ -2047,7 +1999,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::FirstField, Fields::FirstField,
with, with,
apply_with_func_last,
); );
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
@ -2055,7 +2006,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ThirdField, Fields::ThirdField,
with, with,
apply_with_func_last,
); );
} }
AirTree::ListEmpty { AirTree::ListEmpty {
@ -2063,19 +2013,12 @@ impl AirTree {
then: _, then: _,
otherwise, otherwise,
} => { } => {
list.do_traverse_tree_with( list.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FirstField, with);
tree_path,
current_depth + 1,
Fields::FirstField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::ThirdField, Fields::ThirdField,
with, with,
apply_with_func_last,
) )
} }
@ -2090,7 +2033,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ThirdField, Fields::ThirdField,
with, with,
apply_with_func_last,
), ),
AirTree::TupleClause { AirTree::TupleClause {
@ -2107,7 +2049,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SeventhField, Fields::SeventhField,
with, with,
apply_with_func_last,
); );
} }
AirTree::PairClause { AirTree::PairClause {
@ -2124,7 +2065,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SeventhField, Fields::SeventhField,
with, with,
apply_with_func_last,
); );
} }
@ -2164,20 +2104,10 @@ impl AirTree {
| AirTree::MultiValidator { .. } => {} | AirTree::MultiValidator { .. } => {}
} }
if !apply_with_func_last {
with(self, tree_path);
}
// Expressions or an assignment that hoist over a expression are traversed here // Expressions or an assignment that hoist over a expression are traversed here
match self { match self {
AirTree::NoOp { then } => { AirTree::NoOp { then } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FirstField, with);
tree_path,
current_depth + 1,
Fields::FirstField,
with,
apply_with_func_last,
);
} }
AirTree::When { AirTree::When {
tipo: _, tipo: _,
@ -2191,7 +2121,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::FifthField, Fields::FifthField,
with, with,
apply_with_func_last,
); );
} }
AirTree::TupleClause { AirTree::TupleClause {
@ -2203,13 +2132,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SixthField, with);
tree_path,
current_depth + 1,
Fields::SixthField,
with,
apply_with_func_last,
);
} }
AirTree::PairClause { AirTree::PairClause {
subject_tipo: _, subject_tipo: _,
@ -2220,13 +2143,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SixthField, with);
tree_path,
current_depth + 1,
Fields::SixthField,
with,
apply_with_func_last,
);
} }
AirTree::List { AirTree::List {
tipo: _, tipo: _,
@ -2239,7 +2156,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
} }
@ -2250,39 +2166,20 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
} }
AirTree::Pair { tipo: _, fst, snd } => { AirTree::Pair { tipo: _, fst, snd } => {
fst.do_traverse_tree_with( fst.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
snd.do_traverse_tree_with( snd.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
} }
AirTree::Call { AirTree::Call {
tipo: _, tipo: _,
func, func,
args, args,
} => { } => {
func.do_traverse_tree_with( func.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
for (index, arg) in args.iter_mut().enumerate() { for (index, arg) in args.iter_mut().enumerate() {
arg.do_traverse_tree_with( arg.do_traverse_tree_with(
@ -2290,7 +2187,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
} }
@ -2304,7 +2200,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
} }
AirTree::Builtin { AirTree::Builtin {
@ -2318,7 +2213,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
} }
@ -2329,30 +2223,17 @@ impl AirTree {
right, right,
argument_tipo: _, argument_tipo: _,
} => { } => {
left.do_traverse_tree_with( left.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
right.do_traverse_tree_with( right.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
); );
} }
AirTree::UnOp { op: _, arg } => { AirTree::UnOp { op: _, arg } => {
arg.do_traverse_tree_with( arg.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
} }
AirTree::CastFromData { AirTree::CastFromData {
tipo: _, tipo: _,
@ -2364,7 +2245,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
} }
AirTree::CastToData { tipo: _, value } => { AirTree::CastToData { tipo: _, value } => {
@ -2373,7 +2253,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
} }
@ -2390,23 +2269,15 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
); );
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::SixthField, Fields::SixthField,
with, with,
apply_with_func_last,
); );
} }
AirTree::ListClause { AirTree::ListClause {
@ -2417,37 +2288,23 @@ impl AirTree {
then, then,
otherwise, otherwise,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::SixthField, Fields::SixthField,
with, with,
apply_with_func_last,
); );
} }
AirTree::WrapClause { then, otherwise } => { AirTree::WrapClause { then, otherwise } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FirstField, with);
tree_path,
current_depth + 1,
Fields::FirstField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
} }
@ -2457,16 +2314,9 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::FirstField, Fields::FirstField,
with, with,
apply_with_func_last,
); );
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
} }
AirTree::If { AirTree::If {
tipo: _, tipo: _,
@ -2479,23 +2329,15 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
otherwise.do_traverse_tree_with( otherwise.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
); );
} }
AirTree::Constr { AirTree::Constr {
@ -2509,7 +2351,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
} }
@ -2525,7 +2366,6 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
); );
for (index, arg) in args.iter_mut().enumerate() { for (index, arg) in args.iter_mut().enumerate() {
@ -2534,26 +2374,13 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
} }
AirTree::Trace { tipo: _, msg, then } => { AirTree::Trace { tipo: _, msg, then } => {
msg.do_traverse_tree_with( msg.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
} }
AirTree::DefineFunc { AirTree::DefineFunc {
func_name: _, func_name: _,
@ -2570,15 +2397,8 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SeventhField, Fields::SeventhField,
with, with,
apply_with_func_last,
); );
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::EighthField, with)
tree_path,
current_depth + 1,
Fields::EighthField,
with,
apply_with_func_last,
)
} }
AirTree::DefineCyclicFuncs { AirTree::DefineCyclicFuncs {
func_name: _, func_name: _,
@ -2593,16 +2413,9 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::ArgsField(index), Fields::ArgsField(index),
with, with,
apply_with_func_last,
); );
} }
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
} }
AirTree::Int { .. } AirTree::Int { .. }
| AirTree::String { .. } | AirTree::String { .. }
@ -2617,13 +2430,7 @@ impl AirTree {
value: _, value: _,
then, then,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
} }
AirTree::SoftCastLet { AirTree::SoftCastLet {
name: _, name: _,
@ -2632,13 +2439,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FourthField, with);
tree_path,
current_depth + 1,
Fields::FourthField,
with,
apply_with_func_last,
);
} }
AirTree::AssertConstr { AirTree::AssertConstr {
constr_index: _, constr_index: _,
@ -2646,13 +2447,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
} }
AirTree::AssertBool { AirTree::AssertBool {
is_true: _, is_true: _,
@ -2660,13 +2455,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::ThirdField, with);
tree_path,
current_depth + 1,
Fields::ThirdField,
with,
apply_with_func_last,
);
} }
AirTree::ClauseGuard { AirTree::ClauseGuard {
subject_name: _, subject_name: _,
@ -2674,13 +2463,7 @@ impl AirTree {
pattern: _, pattern: _,
then, then,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FourthField, with);
tree_path,
current_depth + 1,
Fields::FourthField,
with,
apply_with_func_last,
);
} }
AirTree::ListClauseGuard { AirTree::ListClauseGuard {
subject_tipo: _, subject_tipo: _,
@ -2689,13 +2472,7 @@ impl AirTree {
inverse: _, inverse: _,
then, then,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
} }
AirTree::TupleGuard { AirTree::TupleGuard {
subject_tipo: _, subject_tipo: _,
@ -2703,13 +2480,7 @@ impl AirTree {
subject_name: _, subject_name: _,
then, then,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FourthField, with);
tree_path,
current_depth + 1,
Fields::FourthField,
with,
apply_with_func_last,
);
} }
AirTree::PairGuard { AirTree::PairGuard {
subject_tipo: _, subject_tipo: _,
@ -2718,13 +2489,7 @@ impl AirTree {
snd_name: _, snd_name: _,
then, then,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
} }
AirTree::FieldsExpose { AirTree::FieldsExpose {
indices: _, indices: _,
@ -2733,13 +2498,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FourthField, with);
tree_path,
current_depth + 1,
Fields::FourthField,
with,
apply_with_func_last,
);
} }
AirTree::ListAccessor { AirTree::ListAccessor {
tipo: _, tipo: _,
@ -2750,13 +2509,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SixthField, with);
tree_path,
current_depth + 1,
Fields::SixthField,
with,
apply_with_func_last,
);
} }
AirTree::ListExpose { AirTree::ListExpose {
tipo: _, tipo: _,
@ -2764,13 +2517,7 @@ impl AirTree {
tail: _, tail: _,
then, then,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FourthField, with);
tree_path,
current_depth + 1,
Fields::FourthField,
with,
apply_with_func_last,
);
} }
AirTree::TupleAccessor { AirTree::TupleAccessor {
names: _, names: _,
@ -2780,13 +2527,7 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::FifthField, with);
tree_path,
current_depth + 1,
Fields::FifthField,
with,
apply_with_func_last,
);
} }
AirTree::PairAccessor { AirTree::PairAccessor {
fst: _, fst: _,
@ -2797,39 +2538,21 @@ impl AirTree {
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SixthField, with);
tree_path,
current_depth + 1,
Fields::SixthField,
with,
apply_with_func_last,
);
} }
AirTree::FieldsEmpty { AirTree::FieldsEmpty {
constr: _, constr: _,
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
} }
AirTree::ListEmpty { AirTree::ListEmpty {
list: _, list: _,
then, then,
otherwise: _, otherwise: _,
} => { } => {
then.do_traverse_tree_with( then.do_traverse_tree_with(tree_path, current_depth + 1, Fields::SecondField, with);
tree_path,
current_depth + 1,
Fields::SecondField,
with,
apply_with_func_last,
);
} }
AirTree::MultiValidator { AirTree::MultiValidator {
two_arg_name: _, two_arg_name: _,
@ -2842,21 +2565,17 @@ impl AirTree {
current_depth + 1, current_depth + 1,
Fields::SecondField, Fields::SecondField,
with, with,
apply_with_func_last,
); );
three_arg.do_traverse_tree_with( three_arg.do_traverse_tree_with(
tree_path, tree_path,
current_depth + 1, current_depth + 1,
Fields::FourthField, Fields::FourthField,
with, with,
apply_with_func_last,
) )
} }
} }
if apply_with_func_last { with(self, tree_path);
with(self, tree_path);
}
tree_path.pop(); tree_path.pop();
} }