final checkpoint
This commit is contained in:
parent
8641c305f4
commit
02ce3761ae
|
@ -24,7 +24,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
gen_uplc2::builder::{
|
gen_uplc2::builder::{
|
||||||
convert_opaque_type, erase_opaque_type_operations, find_and_replace_generics,
|
convert_opaque_type, erase_opaque_type_operations, find_and_replace_generics,
|
||||||
get_generic_id_and_type, get_variant_name, monomorphize,
|
get_generic_id_and_type, get_variant_name, monomorphize, CodeGenFunction,
|
||||||
},
|
},
|
||||||
tipo::{
|
tipo::{
|
||||||
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
||||||
|
@ -34,7 +34,7 @@ use crate::{
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
air::Air,
|
air::Air,
|
||||||
builder::{CodeGenFunction, UserFunction},
|
builder::UserFunction,
|
||||||
tree::{AirExpression, AirStatement, AirTree, TreePath},
|
tree::{AirExpression, AirStatement, AirTree, TreePath},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1012,7 +1012,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let expect_list_func = AirTree::expect_on_list();
|
let expect_list_func = AirTree::expect_on_list();
|
||||||
self.code_gen_functions.insert(
|
self.code_gen_functions.insert(
|
||||||
EXPECT_ON_LIST.to_string(),
|
EXPECT_ON_LIST.to_string(),
|
||||||
CodeGenFunction::Function(expect_list_func, vec![]),
|
CodeGenFunction::Function {
|
||||||
|
body: expect_list_func,
|
||||||
|
params: vec!["__list_to_check".to_string(), "__check_with".to_string()],
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1070,7 +1073,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let expect_list_func = AirTree::expect_on_list();
|
let expect_list_func = AirTree::expect_on_list();
|
||||||
self.code_gen_functions.insert(
|
self.code_gen_functions.insert(
|
||||||
EXPECT_ON_LIST.to_string(),
|
EXPECT_ON_LIST.to_string(),
|
||||||
CodeGenFunction::Function(expect_list_func, vec![]),
|
CodeGenFunction::Function {
|
||||||
|
body: expect_list_func,
|
||||||
|
params: vec!["__list_to_check".to_string(), "__check_with".to_string()],
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,28 +1338,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let recursive = diff_defined_types.contains(&data_type_name);
|
let code_gen_func = CodeGenFunction::Function {
|
||||||
// remove self from dependencies
|
body: func_body,
|
||||||
if recursive {
|
params: vec!["__param_0".to_string()],
|
||||||
diff_defined_types.remove(
|
};
|
||||||
diff_defined_types
|
|
||||||
.iter()
|
|
||||||
.position(|item| item == &data_type_name)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let code_gen_func = CodeGenFunction::Function(
|
|
||||||
AirTree::define_func(
|
|
||||||
&data_type_name,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
vec!["__param_0".to_string()],
|
|
||||||
recursive,
|
|
||||||
func_body,
|
|
||||||
),
|
|
||||||
diff_defined_types,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.code_gen_functions
|
self.code_gen_functions
|
||||||
.insert(data_type_name.clone(), code_gen_func);
|
.insert(data_type_name.clone(), code_gen_func);
|
||||||
|
@ -2248,9 +2236,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut used_functions = vec![];
|
let mut used_functions = vec![];
|
||||||
let mut defined_functions = vec![];
|
let mut defined_functions = vec![];
|
||||||
let mut hoisted_functions = vec![];
|
let mut hoisted_functions = vec![];
|
||||||
|
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.
|
||||||
erase_opaque_type_operations(&mut air_tree, &self.data_types);
|
air_tree.traverse_tree_with(&mut |air_tree: &mut AirTree, _| {
|
||||||
|
erase_opaque_type_operations(air_tree, &self.data_types);
|
||||||
|
});
|
||||||
|
|
||||||
self.find_function_vars_and_depth(
|
self.find_function_vars_and_depth(
|
||||||
&mut air_tree,
|
&mut air_tree,
|
||||||
|
@ -2261,6 +2252,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
validator_hoistable = used_functions.clone();
|
||||||
|
|
||||||
while let Some((key, variant_name)) = used_functions.pop() {
|
while let Some((key, variant_name)) = used_functions.pop() {
|
||||||
defined_functions.push((key.clone(), variant_name.clone()));
|
defined_functions.push((key.clone(), variant_name.clone()));
|
||||||
let function_variants = functions_to_hoist
|
let function_variants = functions_to_hoist
|
||||||
|
@ -2300,45 +2293,44 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("FUNCTIONS TO HOIST {:#?}", functions_to_hoist);
|
|
||||||
|
|
||||||
// First we need to sort functions by dependencies
|
// First we need to sort functions by dependencies
|
||||||
// here's also where we deal with mutual recursion
|
// here's also where we deal with mutual recursion
|
||||||
let mut function_vec = vec![];
|
|
||||||
let mut sorted_function_vec = vec![];
|
let mut sorted_function_vec = vec![];
|
||||||
for (generic_func, function_variants) in functions_to_hoist.iter() {
|
|
||||||
for (variant, _) in function_variants {
|
|
||||||
function_vec.push((generic_func, variant));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function_vec.reverse();
|
while let Some((generic_func, variant)) = validator_hoistable.pop() {
|
||||||
|
|
||||||
while let Some((generic_func, variant)) = function_vec.pop() {
|
|
||||||
let function_variants = functions_to_hoist
|
let function_variants = functions_to_hoist
|
||||||
.get(generic_func)
|
.get(&generic_func)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
||||||
|
|
||||||
|
let function_has_params = self
|
||||||
|
.functions
|
||||||
|
.get(&generic_func)
|
||||||
|
.map(|func| !func.arguments.is_empty())
|
||||||
|
.unwrap_or_else(|| true);
|
||||||
|
|
||||||
let (_, function) = function_variants
|
let (_, function) = function_variants
|
||||||
.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
|
// TODO: change this part to handle mutual recursion
|
||||||
if let UserFunction::Function(_, deps) = function {
|
if let UserFunction::Function(_, deps) = function {
|
||||||
|
if function_has_params {
|
||||||
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) {
|
||||||
function_vec.push((dep_generic_func, dep_variant));
|
validator_hoistable
|
||||||
|
.push((dep_generic_func.clone(), dep_variant.clone()));
|
||||||
let remove_index =
|
let remove_index =
|
||||||
sorted_function_vec
|
sorted_function_vec
|
||||||
.iter()
|
.iter()
|
||||||
.position(|(generic_func, variant)| {
|
.position(|(generic_func, variant)| {
|
||||||
*generic_func == dep_generic_func && *variant == dep_variant
|
generic_func == dep_generic_func && variant == dep_variant
|
||||||
});
|
});
|
||||||
if let Some(index) = remove_index {
|
if let Some(index) = remove_index {
|
||||||
sorted_function_vec.remove(index);
|
sorted_function_vec.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
todo!("Deal with Link later")
|
todo!("Deal with Link later")
|
||||||
}
|
}
|
||||||
|
@ -2351,29 +2343,28 @@ impl<'a> CodeGenerator<'a> {
|
||||||
for (key, variant) in sorted_function_vec {
|
for (key, variant) in sorted_function_vec {
|
||||||
if hoisted_functions
|
if hoisted_functions
|
||||||
.iter()
|
.iter()
|
||||||
.any(|(func_key, func_variant)| func_key == key && func_variant == variant)
|
.any(|(func_key, func_variant)| func_key == &key && func_variant == &variant)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let function_variants = functions_to_hoist
|
let function_variants = functions_to_hoist
|
||||||
.get(key)
|
.get(&key)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
||||||
|
|
||||||
let (tree_path, function) = function_variants
|
let (tree_path, function) = function_variants
|
||||||
.get(variant)
|
.get(&variant)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
.unwrap_or_else(|| panic!("Missing Function Variant Definition"));
|
||||||
|
|
||||||
self.hoist_function(
|
self.hoist_function(
|
||||||
&mut air_tree,
|
&mut air_tree,
|
||||||
tree_path,
|
tree_path,
|
||||||
function,
|
function,
|
||||||
(key, variant),
|
(&key, &variant),
|
||||||
&functions_to_hoist,
|
&functions_to_hoist,
|
||||||
&mut hoisted_functions,
|
&mut hoisted_functions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
println!("NOW AIR TREE {:#?}", air_tree);
|
|
||||||
|
|
||||||
air_tree
|
air_tree
|
||||||
}
|
}
|
||||||
|
@ -2402,13 +2393,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.any(|(dep_key, dep_variant)| dep_key == key && dep_variant == variant);
|
.any(|(dep_key, dep_variant)| dep_key == key && dep_variant == variant);
|
||||||
|
|
||||||
// first grab dependencies
|
// first grab dependencies
|
||||||
let func = self
|
let func_params = self
|
||||||
.functions
|
.functions
|
||||||
.get(key)
|
.get(key)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
.map(|func| {
|
||||||
|
func.arguments
|
||||||
let params = func
|
|
||||||
.arguments
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|func_arg| {
|
.map(|func_arg| {
|
||||||
func_arg
|
func_arg
|
||||||
|
@ -2417,9 +2406,17 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.unwrap_or("_")
|
.unwrap_or("_")
|
||||||
.to_string()
|
.to_string()
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let Some(CodeGenFunction::Function { params, .. }) =
|
||||||
|
self.code_gen_functions.get(&key.function_name)
|
||||||
|
else { unreachable!() };
|
||||||
|
|
||||||
let params_empty = params.is_empty();
|
params.clone()
|
||||||
|
});
|
||||||
|
|
||||||
|
let params_empty = func_params.is_empty();
|
||||||
|
|
||||||
let deps = (tree_path, func_deps.clone());
|
let deps = (tree_path, func_deps.clone());
|
||||||
|
|
||||||
|
@ -2428,7 +2425,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&key.function_name,
|
&key.function_name,
|
||||||
&key.module_name,
|
&key.module_name,
|
||||||
variant,
|
variant,
|
||||||
params,
|
func_params,
|
||||||
is_recursive,
|
is_recursive,
|
||||||
body,
|
body,
|
||||||
);
|
);
|
||||||
|
@ -2506,12 +2503,11 @@ 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 dependent_func = self
|
let dependent_params = self
|
||||||
.functions
|
.functions
|
||||||
.get(&dep_key)
|
.get(&dep_key)
|
||||||
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
.map(|dep_func| {
|
||||||
|
dep_func
|
||||||
let dependent_params = dependent_func
|
|
||||||
.arguments
|
.arguments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|func_arg| {
|
.map(|func_arg| {
|
||||||
|
@ -2521,7 +2517,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.unwrap_or("_")
|
.unwrap_or("_")
|
||||||
.to_string()
|
.to_string()
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let Some(CodeGenFunction::Function { params, .. }) =
|
||||||
|
self.code_gen_functions.get(&key.function_name)
|
||||||
|
else { unreachable!() };
|
||||||
|
|
||||||
|
params.clone()
|
||||||
|
});
|
||||||
|
|
||||||
let UserFunction::Function(dep_air_tree, dependency_deps) =
|
let UserFunction::Function(dep_air_tree, dependency_deps) =
|
||||||
dep_function.clone()
|
dep_function.clone()
|
||||||
|
@ -2656,7 +2660,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
*path = path.common_ancestor(tree_path);
|
*path = path.common_ancestor(tree_path);
|
||||||
} else {
|
} else {
|
||||||
let CodeGenFunction::Function(air_tree, _) = code_gen_func
|
let CodeGenFunction::Function{ body, .. } = code_gen_func
|
||||||
else { unreachable!() };
|
else { unreachable!() };
|
||||||
|
|
||||||
let mut function_variant_path = IndexMap::new();
|
let mut function_variant_path = IndexMap::new();
|
||||||
|
@ -2665,10 +2669,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
(
|
(
|
||||||
tree_path.clone(),
|
tree_path.clone(),
|
||||||
UserFunction::Function(air_tree.clone(), vec![]),
|
UserFunction::Function(body.clone(), vec![]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
dependency_functions.push((generic_function_key.clone(), "".to_string()));
|
||||||
function_usage.insert(generic_function_key, function_variant_path);
|
function_usage.insert(generic_function_key, function_variant_path);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2725,13 +2730,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} else {
|
} else {
|
||||||
let mut function_air_tree_body = self.build(&function_def.body);
|
let mut function_air_tree_body = self.build(&function_def.body);
|
||||||
|
|
||||||
// TODO: change this to be more like a stream
|
function_air_tree_body.traverse_tree_with(&mut |air_tree, _| {
|
||||||
monomorphize(&mut function_air_tree_body, &mono_types);
|
monomorphize(air_tree, &mono_types);
|
||||||
|
|
||||||
erase_opaque_type_operations(
|
erase_opaque_type_operations(air_tree, &self.data_types);
|
||||||
&mut function_air_tree_body,
|
});
|
||||||
&self.data_types,
|
|
||||||
);
|
|
||||||
|
|
||||||
func_variants.insert(
|
func_variants.insert(
|
||||||
variant,
|
variant,
|
||||||
|
@ -2744,10 +2747,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} else {
|
} else {
|
||||||
let mut function_air_tree_body = self.build(&function_def.body);
|
let mut function_air_tree_body = self.build(&function_def.body);
|
||||||
|
|
||||||
// TODO: change this to be more like a stream
|
function_air_tree_body.traverse_tree_with(&mut |air_tree, _| {
|
||||||
monomorphize(&mut function_air_tree_body, &mono_types);
|
monomorphize(air_tree, &mono_types);
|
||||||
|
|
||||||
erase_opaque_type_operations(&mut function_air_tree_body, &self.data_types);
|
erase_opaque_type_operations(air_tree, &self.data_types);
|
||||||
|
});
|
||||||
|
|
||||||
let mut function_variant_path = IndexMap::new();
|
let mut function_variant_path = IndexMap::new();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use super::tree::{AirExpression, AirStatement, AirTree};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum CodeGenFunction {
|
pub enum CodeGenFunction {
|
||||||
Function(AirTree, Vec<String>),
|
Function { body: AirTree, params: Vec<String> },
|
||||||
Link(String),
|
Link(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,20 +318,17 @@ pub fn get_variant_name(t: &Arc<Type>) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monomorphize(air_tree: &mut AirTree, mono_types: &IndexMap<u64, Arc<Type>>) {
|
pub fn monomorphize(air_tree: &mut AirTree, mono_types: &IndexMap<u64, Arc<Type>>) {
|
||||||
air_tree.traverse_tree_with(&mut |air_tree: &mut AirTree, _| {
|
|
||||||
let mut held_types = air_tree.mut_held_types();
|
let mut held_types = air_tree.mut_held_types();
|
||||||
|
|
||||||
while let Some(tipo) = held_types.pop() {
|
while let Some(tipo) = held_types.pop() {
|
||||||
*tipo = find_and_replace_generics(tipo, mono_types)
|
*tipo = find_and_replace_generics(tipo, mono_types);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn erase_opaque_type_operations(
|
pub fn erase_opaque_type_operations(
|
||||||
air_tree: &mut AirTree,
|
air_tree: &mut AirTree,
|
||||||
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
||||||
) {
|
) {
|
||||||
air_tree.traverse_tree_with(&mut |air_tree, _| {
|
|
||||||
if let AirTree::Expression(e) = air_tree {
|
if let AirTree::Expression(e) = air_tree {
|
||||||
match e {
|
match e {
|
||||||
AirExpression::Constr { tipo, args, .. } => {
|
AirExpression::Constr { tipo, args, .. } => {
|
||||||
|
@ -348,8 +345,7 @@ pub fn erase_opaque_type_operations(
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else if let AirTree::Statement {
|
} else if let AirTree::Statement {
|
||||||
statement:
|
statement: AirStatement::FieldsExpose {
|
||||||
AirStatement::FieldsExpose {
|
|
||||||
record, indices, ..
|
record, indices, ..
|
||||||
},
|
},
|
||||||
hoisted_over: Some(hoisted_over),
|
hoisted_over: Some(hoisted_over),
|
||||||
|
@ -367,5 +363,4 @@ pub fn erase_opaque_type_operations(
|
||||||
while let Some(tipo) = held_types.pop() {
|
while let Some(tipo) = held_types.pop() {
|
||||||
*tipo = convert_opaque_type(tipo, data_types);
|
*tipo = convert_opaque_type(tipo, data_types);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -829,22 +829,13 @@ impl AirTree {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
let list_clause = AirTree::list_clause(
|
AirTree::list_clause(
|
||||||
"__list_to_check",
|
"__list_to_check",
|
||||||
void(),
|
void(),
|
||||||
AirTree::void(),
|
AirTree::void(),
|
||||||
assign.hoist_over(next_call),
|
assign.hoist_over(next_call),
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
);
|
|
||||||
|
|
||||||
AirTree::define_func(
|
|
||||||
EXPECT_ON_LIST,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
vec!["__list_to_check".to_string(), "__check_with".to_string()],
|
|
||||||
true,
|
|
||||||
list_clause,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1758,7 +1749,7 @@ impl AirTree {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
a => unreachable!("GOT THIS {:#?}", a),
|
||||||
}
|
}
|
||||||
|
|
||||||
tree_path.pop();
|
tree_path.pop();
|
||||||
|
|
Loading…
Reference in New Issue