feat: add support for hoisting code gen functions

fix: code gen vars should be module functions
fix: missed a recursive call in do_find_air_tree_node under binop
This commit is contained in:
microproofs 2023-07-21 14:14:16 -04:00 committed by Kasey
parent c0f09856d3
commit a099c01734
2 changed files with 67 additions and 18 deletions

View File

@ -1011,7 +1011,21 @@ impl<'a> CodeGenerator<'a> {
}
let func_call = AirTree::call(
AirTree::local_var(EXPECT_ON_LIST, void()),
AirTree::var(
ValueConstructor::public(
void(),
ValueConstructorVariant::ModuleFn {
name: EXPECT_ON_LIST.to_string(),
field_map: None,
module: "".to_string(),
arity: 1,
location,
builtin: None,
},
),
EXPECT_ON_LIST,
"",
),
void(),
vec![AirTree::local_var(map_name, tipo.clone()), unwrap_function],
);
@ -1055,7 +1069,21 @@ impl<'a> CodeGenerator<'a> {
}
let func_call = AirTree::call(
AirTree::local_var(EXPECT_ON_LIST, void()),
AirTree::var(
ValueConstructor::public(
void(),
ValueConstructorVariant::ModuleFn {
name: EXPECT_ON_LIST.to_string(),
field_map: None,
module: "".to_string(),
arity: 1,
location,
builtin: None,
},
),
EXPECT_ON_LIST,
"",
),
void(),
vec![AirTree::local_var(list_name, tipo.clone()), unwrap_function],
);
@ -2446,10 +2474,37 @@ impl<'a> CodeGenerator<'a> {
function_name: func_name.clone(),
};
let function_def = self
.functions
.get(&generic_function_key)
.unwrap_or_else(|| panic!("Missing Function Definition"));
let function_def = self.functions.get(&generic_function_key);
let Some(function_def) = function_def
else {
let code_gen_func = self
.code_gen_functions
.get(&generic_function_key.function_name)
.unwrap_or_else(|| panic!("Missing Code Gen Function Definition"));
if let Some(func_variants) = function_usage.get_mut(&generic_function_key) {
let (path, _) = func_variants.get_mut("").unwrap();
*path = path.common_ancestor(tree_path);
} else {
let CodeGenFunction::Function(tree, _) = code_gen_func
else { unreachable!() };
let mut function_variant_path = IndexMap::new();
function_variant_path.insert(
"".to_string(),
(
tree_path.clone(),
UserFunction::Function(tree.clone(), vec![]),
),
);
function_usage.insert(generic_function_key, function_variant_path);
}
return;
};
let mut function_var_types = function_var_tipo
.arg_types()
@ -2511,7 +2566,7 @@ impl<'a> CodeGenerator<'a> {
func_variants.insert(
variant_name,
(
tree_path.current_path(),
tree_path.clone(),
UserFunction::Function(function_air_tree_body, vec![]),
),
);
@ -2528,7 +2583,7 @@ impl<'a> CodeGenerator<'a> {
function_variant_path.insert(
variant_name,
(
tree_path.current_path(),
tree_path.clone(),
UserFunction::Function(function_air_tree_body, vec![]),
),
);

View File

@ -28,12 +28,6 @@ impl TreePath {
self.path.pop()
}
pub fn current_path(&self) -> Self {
let mut path = self.path.clone();
path.pop();
TreePath { path }
}
pub fn common_ancestor(&self, other: &Self) -> Self {
let mut common_ancestor = TreePath::new();
@ -1743,9 +1737,9 @@ impl AirTree {
_ => unreachable!(),
}
with(self, tree_path);
tree_path.pop();
with(self, tree_path);
}
pub fn find_air_tree_node<'a>(&'a mut self, tree_path: &TreePath) -> &'a mut AirTree {
@ -1757,7 +1751,7 @@ impl AirTree {
&'a mut self,
tree_path_iter: &mut Iter<(usize, usize)>,
) -> &'a mut AirTree {
if let Some((_depth, index)) = tree_path_iter.next() {
if let Some((depth, index)) = tree_path_iter.next() {
let mut children_nodes = vec![];
match self {
AirTree::Statement {
@ -1891,7 +1885,7 @@ impl AirTree {
}
AirExpression::BinOp { left, right, .. } => {
if *index == 0 {
left.as_mut()
left.as_mut().do_find_air_tree_node(tree_path_iter)
} else if *index == 1 {
right.as_mut().do_find_air_tree_node(tree_path_iter)
} else {