final checkpoint

This commit is contained in:
microproofs 2023-07-25 02:19:13 -04:00 committed by Kasey
parent 8641c305f4
commit 02ce3761ae
3 changed files with 135 additions and 145 deletions

View File

@ -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();

View File

@ -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);
} }
});
} }

View File

@ -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();