chore: change UserFunction to HoistableFunction to prepare for mututal recursion
This commit is contained in:
parent
984237075a
commit
0fb9837ddf
|
@ -42,7 +42,7 @@ use self::{
|
||||||
builder::{
|
builder::{
|
||||||
cast_validator_args, constants_ir, convert_type_to_data, extract_constant,
|
cast_validator_args, constants_ir, convert_type_to_data, extract_constant,
|
||||||
lookup_data_type_by_tipo, modify_self_calls, rearrange_list_clauses, AssignmentProperties,
|
lookup_data_type_by_tipo, modify_self_calls, rearrange_list_clauses, AssignmentProperties,
|
||||||
ClauseProperties, DataTypeKey, FunctionAccessKey, UserFunction,
|
ClauseProperties, DataTypeKey, FunctionAccessKey, HoistableFunction,
|
||||||
},
|
},
|
||||||
tree::{AirExpression, AirTree, TreePath},
|
tree::{AirExpression, AirTree, TreePath},
|
||||||
};
|
};
|
||||||
|
@ -2587,12 +2587,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.get(&variant_name)
|
.get(&variant_name)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
||||||
|
|
||||||
if let UserFunction::Function { body, deps, params } = function {
|
match function {
|
||||||
|
HoistableFunction::Function { body, deps, params } => {
|
||||||
let mut hoist_body = body.clone();
|
let mut hoist_body = body.clone();
|
||||||
let mut hoist_deps = deps.clone();
|
let mut hoist_deps = deps.clone();
|
||||||
let params = params.clone();
|
let params = params.clone();
|
||||||
|
let tree_path = tree_path.clone();
|
||||||
let mut tree_path = tree_path.clone();
|
|
||||||
|
|
||||||
self.define_dependent_functions(
|
self.define_dependent_functions(
|
||||||
&mut hoist_body,
|
&mut hoist_body,
|
||||||
|
@ -2600,7 +2600,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut used_functions,
|
&mut used_functions,
|
||||||
&defined_functions,
|
&defined_functions,
|
||||||
&mut hoist_deps,
|
&mut hoist_deps,
|
||||||
&mut tree_path,
|
tree_path,
|
||||||
);
|
);
|
||||||
|
|
||||||
let function_variants = functions_to_hoist
|
let function_variants = functions_to_hoist
|
||||||
|
@ -2615,13 +2615,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
validator_hoistable.push((key, variant_name));
|
validator_hoistable.push((key, variant_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
*function = UserFunction::Function {
|
*function = HoistableFunction::Function {
|
||||||
body: hoist_body,
|
body: hoist_body,
|
||||||
deps: hoist_deps,
|
deps: hoist_deps,
|
||||||
params,
|
params,
|
||||||
};
|
};
|
||||||
} else {
|
}
|
||||||
todo!("Deal with Link later")
|
HoistableFunction::Link(_) => todo!("Deal with Link later"),
|
||||||
|
HoistableFunction::CyclicLink(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validator_hoistable.dedup();
|
validator_hoistable.dedup();
|
||||||
|
@ -2635,7 +2636,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.flat_map(|(function_name, val)| {
|
.flat_map(|(function_name, val)| {
|
||||||
val.into_iter()
|
val.into_iter()
|
||||||
.map(|(variant, (_, function))| {
|
.map(|(variant, (_, function))| {
|
||||||
if let UserFunction::Function { deps, .. } = function {
|
if let HoistableFunction::Function { deps, .. } = function {
|
||||||
((function_name.clone(), variant.clone()), deps)
|
((function_name.clone(), variant.clone()), deps)
|
||||||
} else {
|
} else {
|
||||||
todo!("Deal with Link later")
|
todo!("Deal with Link later")
|
||||||
|
@ -2698,8 +2699,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.get(&variant)
|
.get(&variant)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
||||||
|
|
||||||
// TODO: change this part to handle mutual recursion
|
if let HoistableFunction::Function { deps, params, .. } = function {
|
||||||
if let UserFunction::Function { deps, params, .. } = function {
|
|
||||||
if !params.is_empty() {
|
if !params.is_empty() {
|
||||||
for (dep_generic_func, dep_variant) in deps.iter() {
|
for (dep_generic_func, dep_variant) in deps.iter() {
|
||||||
if !(dep_generic_func == &generic_func && dep_variant == &variant) {
|
if !(dep_generic_func == &generic_func && dep_variant == &variant) {
|
||||||
|
@ -2772,15 +2772,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
air_tree: &mut AirTree,
|
air_tree: &mut AirTree,
|
||||||
tree_path: &TreePath,
|
tree_path: &TreePath,
|
||||||
function: &UserFunction,
|
function: &HoistableFunction,
|
||||||
key_var: (&FunctionAccessKey, &String),
|
key_var: (&FunctionAccessKey, &String),
|
||||||
functions_to_hoist: &IndexMap<
|
functions_to_hoist: &IndexMap<
|
||||||
FunctionAccessKey,
|
FunctionAccessKey,
|
||||||
IndexMap<String, (TreePath, UserFunction)>,
|
IndexMap<String, (TreePath, HoistableFunction)>,
|
||||||
>,
|
>,
|
||||||
hoisted_functions: &mut Vec<(FunctionAccessKey, String)>,
|
hoisted_functions: &mut Vec<(FunctionAccessKey, String)>,
|
||||||
) {
|
) {
|
||||||
if let UserFunction::Function {
|
if let HoistableFunction::Function {
|
||||||
body,
|
body,
|
||||||
deps: func_deps,
|
deps: func_deps,
|
||||||
params,
|
params,
|
||||||
|
@ -2862,7 +2862,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
hoisted_functions: &mut Vec<(FunctionAccessKey, String)>,
|
hoisted_functions: &mut Vec<(FunctionAccessKey, String)>,
|
||||||
functions_to_hoist: &IndexMap<
|
functions_to_hoist: &IndexMap<
|
||||||
FunctionAccessKey,
|
FunctionAccessKey,
|
||||||
IndexMap<String, (TreePath, UserFunction)>,
|
IndexMap<String, (TreePath, HoistableFunction)>,
|
||||||
>,
|
>,
|
||||||
) -> AirTree {
|
) -> AirTree {
|
||||||
let (func_path, func_deps) = deps;
|
let (func_path, func_deps) = deps;
|
||||||
|
@ -2881,7 +2881,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.get(&dep.1)
|
.get(&dep.1)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
||||||
|
|
||||||
if let UserFunction::Function { deps, params, .. } = function {
|
if let HoistableFunction::Function { deps, params, .. } = function {
|
||||||
if !params.is_empty() {
|
if !params.is_empty() {
|
||||||
for (dep_generic_func, dep_variant) in deps.iter() {
|
for (dep_generic_func, dep_variant) in deps.iter() {
|
||||||
if !(dep_generic_func == &dep.0 && dep_variant == &dep.1) {
|
if !(dep_generic_func == &dep.0 && dep_variant == &dep.1) {
|
||||||
|
@ -2925,7 +2925,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
// In the case of zero args, we need to hoist the dependency function to the top of the zero arg function
|
// In the case of zero args, we need to hoist the dependency function to the top of the zero arg function
|
||||||
if &dep_path.common_ancestor(func_path) == func_path || params_empty {
|
if &dep_path.common_ancestor(func_path) == func_path || params_empty {
|
||||||
let UserFunction::Function {
|
let HoistableFunction::Function {
|
||||||
body: mut dep_air_tree,
|
body: mut dep_air_tree,
|
||||||
deps: dependency_deps,
|
deps: dependency_deps,
|
||||||
params: dependent_params,
|
params: dependent_params,
|
||||||
|
@ -2975,24 +2975,24 @@ impl<'a> CodeGenerator<'a> {
|
||||||
air_tree: &mut AirTree,
|
air_tree: &mut AirTree,
|
||||||
function_usage: &mut IndexMap<
|
function_usage: &mut IndexMap<
|
||||||
FunctionAccessKey,
|
FunctionAccessKey,
|
||||||
IndexMap<String, (TreePath, UserFunction)>,
|
IndexMap<String, (TreePath, HoistableFunction)>,
|
||||||
>,
|
>,
|
||||||
used_functions: &mut Vec<(FunctionAccessKey, String)>,
|
used_functions: &mut Vec<(FunctionAccessKey, String)>,
|
||||||
defined_functions: &[(FunctionAccessKey, String)],
|
defined_functions: &[(FunctionAccessKey, String)],
|
||||||
current_function_deps: &mut Vec<(FunctionAccessKey, String)>,
|
current_function_deps: &mut Vec<(FunctionAccessKey, String)>,
|
||||||
validator_tree_path: &mut TreePath,
|
mut function_tree_path: TreePath,
|
||||||
) {
|
) {
|
||||||
let Some((depth, index)) = validator_tree_path.pop() else {
|
let Some((depth, index)) = function_tree_path.pop() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
validator_tree_path.push(depth, index);
|
function_tree_path.push(depth, index);
|
||||||
|
|
||||||
self.find_function_vars_and_depth(
|
self.find_function_vars_and_depth(
|
||||||
air_tree,
|
air_tree,
|
||||||
function_usage,
|
function_usage,
|
||||||
current_function_deps,
|
current_function_deps,
|
||||||
validator_tree_path,
|
&mut function_tree_path,
|
||||||
depth + 1,
|
depth + 1,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -3015,7 +3015,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
air_tree: &mut AirTree,
|
air_tree: &mut AirTree,
|
||||||
function_usage: &mut IndexMap<
|
function_usage: &mut IndexMap<
|
||||||
FunctionAccessKey,
|
FunctionAccessKey,
|
||||||
IndexMap<String, (TreePath, UserFunction)>,
|
IndexMap<String, (TreePath, HoistableFunction)>,
|
||||||
>,
|
>,
|
||||||
dependency_functions: &mut Vec<(FunctionAccessKey, String)>,
|
dependency_functions: &mut Vec<(FunctionAccessKey, String)>,
|
||||||
path: &mut TreePath,
|
path: &mut TreePath,
|
||||||
|
@ -3089,7 +3089,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
(
|
(
|
||||||
tree_path.clone(),
|
tree_path.clone(),
|
||||||
UserFunction::Function {
|
HoistableFunction::Function {
|
||||||
body,
|
body,
|
||||||
deps: vec![],
|
deps: vec![],
|
||||||
params: params.clone(),
|
params: params.clone(),
|
||||||
|
@ -3176,7 +3176,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant,
|
variant,
|
||||||
(
|
(
|
||||||
tree_path.clone(),
|
tree_path.clone(),
|
||||||
UserFunction::Function {
|
HoistableFunction::Function {
|
||||||
body: function_air_tree_body,
|
body: function_air_tree_body,
|
||||||
deps: vec![],
|
deps: vec![],
|
||||||
params,
|
params,
|
||||||
|
@ -3207,7 +3207,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
variant,
|
variant,
|
||||||
(
|
(
|
||||||
tree_path.clone(),
|
tree_path.clone(),
|
||||||
UserFunction::Function {
|
HoistableFunction::Function {
|
||||||
body: function_air_tree_body,
|
body: function_air_tree_body,
|
||||||
deps: vec![],
|
deps: vec![],
|
||||||
params,
|
params,
|
||||||
|
@ -3593,7 +3593,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let zero_arg_functions = self.zero_arg_functions.clone();
|
let zero_arg_functions = self.zero_arg_functions.clone();
|
||||||
|
|
||||||
// How we handle empty anon functions has changed
|
// How we handle zero arg anon functions has changed
|
||||||
// We now delay zero arg anon functions and force them on a call operation
|
// We now delay zero arg anon functions and force them on a call operation
|
||||||
if let Term::Var(name) = &term {
|
if let Term::Var(name) = &term {
|
||||||
let text = &name.text;
|
let text = &name.text;
|
||||||
|
|
|
@ -40,13 +40,14 @@ pub enum CodeGenFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum UserFunction {
|
pub enum HoistableFunction {
|
||||||
Function {
|
Function {
|
||||||
body: AirTree,
|
body: AirTree,
|
||||||
deps: Vec<(FunctionAccessKey, String)>,
|
deps: Vec<(FunctionAccessKey, String)>,
|
||||||
params: Vec<String>,
|
params: Vec<String>,
|
||||||
},
|
},
|
||||||
Link(String),
|
Link((FunctionAccessKey, String)),
|
||||||
|
CyclicLink((FunctionAccessKey, String)),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
Loading…
Reference in New Issue