a checkpoint for function hoisting start and type fix
This commit is contained in:
parent
55ae708e3e
commit
9704cafefe
|
@ -671,7 +671,6 @@ pub fn prelude_functions(id_gen: &IdGenerator) -> IndexMap<FunctionAccessKey, Ty
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name: "".to_string(),
|
module_name: "".to_string(),
|
||||||
function_name: "not".to_string(),
|
function_name: "not".to_string(),
|
||||||
variant_name: "".to_string(),
|
|
||||||
},
|
},
|
||||||
Function {
|
Function {
|
||||||
arguments: vec![Arg {
|
arguments: vec![Arg {
|
||||||
|
@ -722,7 +721,6 @@ pub fn prelude_functions(id_gen: &IdGenerator) -> IndexMap<FunctionAccessKey, Ty
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name: "".to_string(),
|
module_name: "".to_string(),
|
||||||
function_name: "identity".to_string(),
|
function_name: "identity".to_string(),
|
||||||
variant_name: "".to_string(),
|
|
||||||
},
|
},
|
||||||
Function {
|
Function {
|
||||||
arguments: vec![Arg {
|
arguments: vec![Arg {
|
||||||
|
@ -769,7 +767,6 @@ pub fn prelude_functions(id_gen: &IdGenerator) -> IndexMap<FunctionAccessKey, Ty
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name: "".to_string(),
|
module_name: "".to_string(),
|
||||||
function_name: "always".to_string(),
|
function_name: "always".to_string(),
|
||||||
variant_name: "".to_string(),
|
|
||||||
},
|
},
|
||||||
Function {
|
Function {
|
||||||
can_error: false,
|
can_error: false,
|
||||||
|
@ -832,7 +829,6 @@ pub fn prelude_functions(id_gen: &IdGenerator) -> IndexMap<FunctionAccessKey, Ty
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name: "".to_string(),
|
module_name: "".to_string(),
|
||||||
function_name: "flip".to_string(),
|
function_name: "flip".to_string(),
|
||||||
variant_name: "".to_string(),
|
|
||||||
},
|
},
|
||||||
Function {
|
Function {
|
||||||
can_error: false,
|
can_error: false,
|
||||||
|
|
|
@ -702,7 +702,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let func = self.functions.get(&FunctionAccessKey {
|
let func = self.functions.get(&FunctionAccessKey {
|
||||||
module_name: module_name.clone(),
|
module_name: module_name.clone(),
|
||||||
function_name: name.clone(),
|
function_name: name.clone(),
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let type_info = self.module_types.get(module_name).unwrap();
|
let type_info = self.module_types.get(module_name).unwrap();
|
||||||
|
@ -3068,7 +3067,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
func_stack.define_func(
|
func_stack.define_func(
|
||||||
function_access_key.function_name.clone(),
|
function_access_key.function_name.clone(),
|
||||||
function_access_key.module_name.clone(),
|
function_access_key.module_name.clone(),
|
||||||
function_access_key.variant_name.clone(),
|
"",
|
||||||
func_comp.args.clone(),
|
func_comp.args.clone(),
|
||||||
func_comp.recursive,
|
func_comp.recursive,
|
||||||
recursion_stack,
|
recursion_stack,
|
||||||
|
@ -3112,7 +3111,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
|
|
||||||
for ir in function_ir.clone() {
|
for ir in function_ir.clone() {
|
||||||
let Air::Var { constructor, variant_name, .. } = ir
|
let Air::Var { constructor, .. } = ir
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -3125,7 +3124,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let ir_function_key = FunctionAccessKey {
|
let ir_function_key = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: func_name.clone(),
|
function_name: func_name.clone(),
|
||||||
variant_name: variant_name.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if recursion_func_map.contains_key(&ir_function_key) && func == &ir_function_key {
|
if recursion_func_map.contains_key(&ir_function_key) && func == &ir_function_key {
|
||||||
|
@ -3203,7 +3201,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let non_variant_function_key = FunctionAccessKey {
|
let non_variant_function_key = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: name.clone(),
|
function_name: name.clone(),
|
||||||
variant_name: String::new(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(function) = self.functions.get(&non_variant_function_key).cloned() {
|
if let Some(function) = self.functions.get(&non_variant_function_key).cloned() {
|
||||||
|
@ -3243,7 +3240,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let function_key = FunctionAccessKey {
|
let function_key = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: non_variant_function_key.function_name,
|
function_name: non_variant_function_key.function_name,
|
||||||
variant_name: variant_name.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ir_stack[index] = Air::Var {
|
ir_stack[index] = Air::Var {
|
||||||
|
@ -3278,13 +3274,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let current_func = FunctionAccessKey {
|
let current_func = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: func_name.clone(),
|
function_name: func_name.clone(),
|
||||||
variant_name: String::new(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_func_as_variant = FunctionAccessKey {
|
let current_func_as_variant = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: func_name.clone(),
|
function_name: func_name.clone(),
|
||||||
variant_name: variant_name.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let function = self.functions.get(¤t_func);
|
let function = self.functions.get(¤t_func);
|
||||||
|
@ -3335,7 +3329,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name: current_func.module_name,
|
module_name: current_func.module_name,
|
||||||
function_name: current_func.function_name,
|
function_name: current_func.function_name,
|
||||||
variant_name,
|
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
|
@ -3394,7 +3387,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let function_key = FunctionAccessKey {
|
let function_key = FunctionAccessKey {
|
||||||
module_name: "".to_string(),
|
module_name: "".to_string(),
|
||||||
function_name: name.to_string(),
|
function_name: name.to_string(),
|
||||||
variant_name: "".to_string(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let function_stack = AirStack {
|
let function_stack = AirStack {
|
||||||
|
@ -3416,7 +3408,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.map(|item| FunctionAccessKey {
|
.map(|item| FunctionAccessKey {
|
||||||
module_name: "".to_string(),
|
module_name: "".to_string(),
|
||||||
function_name: item,
|
function_name: item,
|
||||||
variant_name: "".to_string(),
|
|
||||||
})
|
})
|
||||||
.collect_vec(),
|
.collect_vec(),
|
||||||
recursive: false,
|
recursive: false,
|
||||||
|
@ -4178,14 +4169,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
module_name,
|
module_name,
|
||||||
function_name,
|
function_name,
|
||||||
variant_name,
|
|
||||||
},
|
},
|
||||||
ir,
|
ir,
|
||||||
) in zero_arg_functions.into_iter()
|
) in zero_arg_functions.into_iter()
|
||||||
{
|
{
|
||||||
let name_module =
|
let name_module = format!("{module_name}_{function_name}");
|
||||||
format!("{module_name}_{function_name}{variant_name}");
|
let name = function_name.to_string();
|
||||||
let name = format!("{function_name}{variant_name}");
|
|
||||||
if text == &name || text == &name_module {
|
if text == &name || text == &name_module {
|
||||||
let mut term = self.uplc_code_gen(&mut ir.clone());
|
let mut term = self.uplc_code_gen(&mut ir.clone());
|
||||||
term = term
|
term = term
|
||||||
|
|
|
@ -53,7 +53,6 @@ pub type ConstrUsageKey = String;
|
||||||
pub struct FunctionAccessKey {
|
pub struct FunctionAccessKey {
|
||||||
pub module_name: String,
|
pub module_name: String,
|
||||||
pub function_name: String,
|
pub function_name: String,
|
||||||
pub variant_name: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -766,7 +765,6 @@ pub fn match_ir_for_recursion(
|
||||||
let var_func_access = FunctionAccessKey {
|
let var_func_access = FunctionAccessKey {
|
||||||
module_name: module,
|
module_name: module,
|
||||||
function_name: func_name.clone(),
|
function_name: func_name.clone(),
|
||||||
variant_name: variant_name.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if function_access_key.clone() == var_func_access {
|
if function_access_key.clone() == var_func_access {
|
||||||
|
@ -1571,7 +1569,7 @@ pub fn handle_func_dependencies(
|
||||||
temp_stack.define_func(
|
temp_stack.define_func(
|
||||||
dependency.function_name.clone(),
|
dependency.function_name.clone(),
|
||||||
dependency.module_name.clone(),
|
dependency.module_name.clone(),
|
||||||
dependency.variant_name.clone(),
|
"",
|
||||||
depend_comp.args.clone(),
|
depend_comp.args.clone(),
|
||||||
depend_comp.recursive,
|
depend_comp.recursive,
|
||||||
recursion_stack,
|
recursion_stack,
|
||||||
|
@ -1607,7 +1605,6 @@ pub fn handle_recursion_ir(
|
||||||
&FunctionAccessKey {
|
&FunctionAccessKey {
|
||||||
function_name: func_key.function_name.clone(),
|
function_name: func_key.function_name.clone(),
|
||||||
module_name: func_key.module_name.clone(),
|
module_name: func_key.module_name.clone(),
|
||||||
variant_name: func_key.variant_name.clone(),
|
|
||||||
},
|
},
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,14 +25,20 @@ use crate::{
|
||||||
FunctionAccessKey, SpecificClause,
|
FunctionAccessKey, SpecificClause,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gen_uplc2::builder::{convert_opaque_type, find_and_replace_generics, get_generic_id_and_type},
|
gen_uplc2::builder::{
|
||||||
|
convert_opaque_type, erase_opaque_operations, find_and_replace_generics,
|
||||||
|
get_generic_id_and_type,
|
||||||
|
},
|
||||||
tipo::{
|
tipo::{
|
||||||
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
ModuleValueConstructor, PatternConstructor, Type, TypeInfo, ValueConstructor,
|
||||||
ValueConstructorVariant,
|
ValueConstructorVariant,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::tree::{AirExpression, AirTree};
|
use self::{
|
||||||
|
builder::{IndexCounter, TreePath},
|
||||||
|
tree::{AirExpression, AirStatement, AirTree},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum CodeGenFunction {
|
pub enum CodeGenFunction {
|
||||||
|
@ -40,6 +46,12 @@ pub enum CodeGenFunction {
|
||||||
Link(String),
|
Link(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum UserFunction {
|
||||||
|
Function(AirTree, Term<Name>),
|
||||||
|
Link(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CodeGenerator<'a> {
|
pub struct CodeGenerator<'a> {
|
||||||
defined_functions: IndexMap<FunctionAccessKey, ()>,
|
defined_functions: IndexMap<FunctionAccessKey, ()>,
|
||||||
|
@ -94,7 +106,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
println!("{:#?}", validator_args_tree);
|
println!("{:#?}", validator_args_tree);
|
||||||
println!("{:#?}", validator_args_tree.to_vec());
|
println!("{:#?}", validator_args_tree.to_vec());
|
||||||
|
|
||||||
let hydrated_tree = self.hoist_functions(validator_args_tree);
|
let full_tree = self.hoist_functions(validator_args_tree);
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -106,6 +118,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
println!("{:#?}", air_tree);
|
println!("{:#?}", air_tree);
|
||||||
println!("{:#?}", air_tree.to_vec());
|
println!("{:#?}", air_tree.to_vec());
|
||||||
|
|
||||||
|
let full_tree = self.hoist_functions(air_tree);
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +236,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedExpr::ModuleSelect {
|
TypedExpr::ModuleSelect {
|
||||||
tipo,
|
|
||||||
module_name,
|
module_name,
|
||||||
constructor: ModuleValueConstructor::Fn { name, .. },
|
constructor: ModuleValueConstructor::Fn { name, .. },
|
||||||
..
|
..
|
||||||
|
@ -273,8 +286,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TypedExpr::BinOp {
|
TypedExpr::BinOp {
|
||||||
name, left, right, ..
|
name,
|
||||||
} => AirTree::binop(*name, left.tipo(), self.build(left), self.build(right)),
|
left,
|
||||||
|
right,
|
||||||
|
tipo,
|
||||||
|
..
|
||||||
|
} => AirTree::binop(*name, tipo.clone(), self.build(left), self.build(right)),
|
||||||
|
|
||||||
TypedExpr::Assignment {
|
TypedExpr::Assignment {
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -360,6 +377,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&clauses,
|
&clauses,
|
||||||
last_clause,
|
last_clause,
|
||||||
&subject.tipo(),
|
&subject.tipo(),
|
||||||
|
tipo,
|
||||||
&mut ClauseProperties::init(
|
&mut ClauseProperties::init(
|
||||||
&subject.tipo(),
|
&subject.tipo(),
|
||||||
constr_var.clone(),
|
constr_var.clone(),
|
||||||
|
@ -370,8 +388,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let constr_assign = AirTree::let_assignment(&constr_var, self.build(subject));
|
let constr_assign = AirTree::let_assignment(&constr_var, self.build(subject));
|
||||||
let when_assign = AirTree::when(
|
let when_assign = AirTree::when(
|
||||||
subject_name,
|
subject_name,
|
||||||
subject.tipo(),
|
tipo.clone(),
|
||||||
AirTree::local_var(constr_var, tipo.clone()),
|
AirTree::local_var(constr_var, subject.tipo()),
|
||||||
clauses,
|
clauses,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -438,7 +456,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let func = self.functions.get(&FunctionAccessKey {
|
let func = self.functions.get(&FunctionAccessKey {
|
||||||
module_name: module_name.clone(),
|
module_name: module_name.clone(),
|
||||||
function_name: name.clone(),
|
function_name: name.clone(),
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let type_info = self.module_types.get(module_name).unwrap();
|
let type_info = self.module_types.get(module_name).unwrap();
|
||||||
|
@ -549,7 +566,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
if props.full_check {
|
if props.full_check {
|
||||||
let mut index_map = IndexMap::new();
|
let mut index_map = IndexMap::new();
|
||||||
let tipo = convert_opaque_type(tipo, &self.data_types);
|
let non_opaque_tipo = convert_opaque_type(tipo, &self.data_types);
|
||||||
|
|
||||||
let assignment = AirTree::let_assignment(name, value);
|
let assignment = AirTree::let_assignment(name, value);
|
||||||
let val = AirTree::local_var(name, tipo.clone());
|
let val = AirTree::local_var(name, tipo.clone());
|
||||||
|
@ -558,7 +575,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::let_assignment(name, assignment.hoist_over(val))
|
AirTree::let_assignment(name, assignment.hoist_over(val))
|
||||||
} else {
|
} else {
|
||||||
let expect = self.expect_type_assign(
|
let expect = self.expect_type_assign(
|
||||||
&tipo,
|
&non_opaque_tipo,
|
||||||
val.clone(),
|
val.clone(),
|
||||||
&mut index_map,
|
&mut index_map,
|
||||||
pattern.location(),
|
pattern.location(),
|
||||||
|
@ -1159,7 +1176,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.flat_map(|item| get_generic_id_and_type(item.0, &item.1))
|
.flat_map(|item| get_generic_id_and_type(item.0, &item.1))
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
vec![].into_iter().collect()
|
IndexMap::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let data_type_name = format!("__expect_{}_{}", data_type.name, data_type_variant);
|
let data_type_name = format!("__expect_{}_{}", data_type.name, data_type_variant);
|
||||||
|
@ -1339,6 +1356,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
clauses: &[TypedClause],
|
clauses: &[TypedClause],
|
||||||
final_clause: TypedClause,
|
final_clause: TypedClause,
|
||||||
subject_tipo: &Arc<Type>,
|
subject_tipo: &Arc<Type>,
|
||||||
|
return_tipo: &Arc<Type>,
|
||||||
props: &mut ClauseProperties,
|
props: &mut ClauseProperties,
|
||||||
) -> AirTree {
|
) -> AirTree {
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -1396,6 +1414,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
complex_clause,
|
complex_clause,
|
||||||
|
@ -1407,6 +1426,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1421,6 +1441,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
complex_clause,
|
complex_clause,
|
||||||
|
@ -1456,6 +1477,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1532,6 +1554,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1544,6 +1567,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
|
@ -1587,6 +1611,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1601,6 +1626,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
rest_clauses,
|
rest_clauses,
|
||||||
final_clause,
|
final_clause,
|
||||||
subject_tipo,
|
subject_tipo,
|
||||||
|
return_tipo,
|
||||||
&mut next_clause_props,
|
&mut next_clause_props,
|
||||||
),
|
),
|
||||||
props.complex_clause,
|
props.complex_clause,
|
||||||
|
@ -2194,14 +2220,18 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::anon_func(arg_names, arg_assigns.hoist_over(body))
|
AirTree::anon_func(arg_names, arg_assigns.hoist_over(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hoist_functions(&mut self, mut validator_args_tree: AirTree) -> AirTree {
|
fn hoist_functions(&mut self, mut air_tree: AirTree) -> AirTree {
|
||||||
let mut functions_to_hoist = IndexMap::new();
|
let mut functions_to_hoist = IndexMap::new();
|
||||||
let mut function_holder = IndexMap::new();
|
let mut function_holder = IndexMap::new();
|
||||||
|
|
||||||
|
erase_opaque_operations(&mut air_tree, &self.data_types);
|
||||||
|
|
||||||
self.find_function_vars_and_depth(
|
self.find_function_vars_and_depth(
|
||||||
&mut validator_args_tree,
|
&air_tree,
|
||||||
&mut functions_to_hoist,
|
&mut functions_to_hoist,
|
||||||
&mut function_holder,
|
&mut function_holder,
|
||||||
|
&mut TreePath::new(),
|
||||||
|
0,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2210,17 +2240,141 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
fn find_function_vars_and_depth(
|
fn find_function_vars_and_depth(
|
||||||
&mut self,
|
&mut self,
|
||||||
validator_args_tree: &mut AirTree,
|
validator_args_tree: &AirTree,
|
||||||
function_usage: &mut IndexMap<FunctionAccessKey, usize>,
|
function_usage: &mut IndexMap<FunctionAccessKey, IndexMap<String, TreePath>>,
|
||||||
function_holder: &mut IndexMap<FunctionAccessKey, AirTree>,
|
function_holder: &mut IndexMap<FunctionAccessKey, IndexMap<String, UserFunction>>,
|
||||||
|
tree_path: &mut TreePath,
|
||||||
current_depth: usize,
|
current_depth: usize,
|
||||||
|
depth_index: usize,
|
||||||
) {
|
) {
|
||||||
|
let mut index_count = IndexCounter::new();
|
||||||
|
tree_path.push(current_depth, depth_index);
|
||||||
match validator_args_tree {
|
match validator_args_tree {
|
||||||
AirTree::Statement {
|
AirTree::Statement {
|
||||||
statement,
|
statement,
|
||||||
hoisted_over: Some(hoisted_over),
|
hoisted_over: Some(hoisted_over),
|
||||||
} => todo!(),
|
} => {
|
||||||
|
match statement {
|
||||||
|
AirStatement::Let { value, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
value,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::DefineFunc { func_body, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
func_body,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::AssertConstr { constr, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
constr,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::AssertBool { value, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
value,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ClauseGuard { pattern, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
pattern,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ListClauseGuard { .. } => {}
|
||||||
|
AirStatement::TupleGuard { .. } => {}
|
||||||
|
AirStatement::FieldsExpose { record, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
record,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ListAccessor { list, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
list,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ListExpose { .. } => {}
|
||||||
|
AirStatement::TupleAccessor { tuple, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
tuple,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::NoOp => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
hoisted_over,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
AirTree::Expression(e) => match e {
|
AirTree::Expression(e) => match e {
|
||||||
|
AirExpression::List { items, .. } => {
|
||||||
|
for item in items {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
item,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::Tuple { items, .. } => {
|
||||||
|
for item in items {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
item,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
AirExpression::Var {
|
AirExpression::Var {
|
||||||
constructor,
|
constructor,
|
||||||
name,
|
name,
|
||||||
|
@ -2235,10 +2389,48 @@ impl<'a> CodeGenerator<'a> {
|
||||||
else { return };
|
else { return };
|
||||||
|
|
||||||
let function_var_tipo = &constructor.tipo;
|
let function_var_tipo = &constructor.tipo;
|
||||||
|
println!("FUNCTION VAR TYPE {:#?}", function_var_tipo);
|
||||||
|
|
||||||
let generic_function_key = FunctionAccessKey {
|
let generic_function_key = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: func_name.clone(),
|
function_name: func_name.clone(),
|
||||||
variant_name: "".to_string(),
|
};
|
||||||
|
|
||||||
|
let function_def = self
|
||||||
|
.functions
|
||||||
|
.get(&generic_function_key)
|
||||||
|
.unwrap_or_else(|| panic!("Missing Function Definition"));
|
||||||
|
|
||||||
|
println!("Function Def {:#?}", function_def);
|
||||||
|
|
||||||
|
let mut function_var_types = function_var_tipo
|
||||||
|
.arg_types()
|
||||||
|
.unwrap_or_else(|| panic!("Expected a function tipo with arg types"));
|
||||||
|
|
||||||
|
function_var_types.push(
|
||||||
|
function_var_tipo
|
||||||
|
.return_type()
|
||||||
|
.unwrap_or_else(|| panic!("Should have return type")),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut function_def_types = function_def
|
||||||
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|arg| &arg.tipo)
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
function_def_types.push(&function_def.return_type);
|
||||||
|
|
||||||
|
let mono_types: IndexMap<u64, Arc<Type>> = if !function_def_types.is_empty() {
|
||||||
|
function_def_types
|
||||||
|
.into_iter()
|
||||||
|
.zip(function_var_types.into_iter())
|
||||||
|
.flat_map(|(func_tipo, var_tipo)| {
|
||||||
|
get_generic_id_and_type(func_tipo, &var_tipo)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
IndexMap::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -2248,7 +2440,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
func,
|
func,
|
||||||
function_usage,
|
function_usage,
|
||||||
function_holder,
|
function_holder,
|
||||||
|
tree_path,
|
||||||
current_depth + 1,
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
|
@ -2256,86 +2450,345 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg,
|
arg,
|
||||||
function_usage,
|
function_usage,
|
||||||
function_holder,
|
function_holder,
|
||||||
|
tree_path,
|
||||||
current_depth + 1,
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AirExpression::Fn { params, func_body } => todo!(),
|
AirExpression::Fn { func_body, .. } => {
|
||||||
AirExpression::Builtin { func, tipo, args } => todo!(),
|
self.find_function_vars_and_depth(
|
||||||
AirExpression::BinOp {
|
func_body,
|
||||||
name,
|
function_usage,
|
||||||
tipo,
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Builtin { args, .. } => {
|
||||||
|
for arg in args {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
arg,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::BinOp { left, right, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
left,
|
left,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
right,
|
right,
|
||||||
} => todo!(),
|
function_usage,
|
||||||
AirExpression::UnOp { op, arg } => todo!(),
|
function_holder,
|
||||||
AirExpression::UnWrapData { tipo, value } => todo!(),
|
tree_path,
|
||||||
AirExpression::WrapData { tipo, value } => todo!(),
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::UnOp { arg, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
arg,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::UnWrapData { value, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
value,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::WrapData { value, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
value,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
AirExpression::When {
|
AirExpression::When {
|
||||||
tipo,
|
subject, clauses, ..
|
||||||
subject_name,
|
} => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
subject,
|
subject,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
clauses,
|
clauses,
|
||||||
} => todo!(),
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
AirExpression::Clause {
|
AirExpression::Clause {
|
||||||
tipo,
|
|
||||||
subject_name,
|
|
||||||
complex_clause,
|
|
||||||
pattern,
|
pattern,
|
||||||
then,
|
then,
|
||||||
otherwise,
|
otherwise,
|
||||||
} => todo!(),
|
..
|
||||||
|
} => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
pattern,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
otherwise,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
AirExpression::ListClause {
|
AirExpression::ListClause {
|
||||||
tipo,
|
then, otherwise, ..
|
||||||
tail_name,
|
} => {
|
||||||
next_tail_name,
|
self.find_function_vars_and_depth(
|
||||||
complex_clause,
|
|
||||||
then,
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
otherwise,
|
otherwise,
|
||||||
} => todo!(),
|
function_usage,
|
||||||
AirExpression::WrapClause { then, otherwise } => todo!(),
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::WrapClause { then, otherwise } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
otherwise,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
AirExpression::TupleClause {
|
AirExpression::TupleClause {
|
||||||
tipo,
|
then, otherwise, ..
|
||||||
indices,
|
} => {
|
||||||
predefined_indices,
|
self.find_function_vars_and_depth(
|
||||||
subject_name,
|
|
||||||
type_count,
|
|
||||||
complex_clause,
|
|
||||||
then,
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
otherwise,
|
otherwise,
|
||||||
} => todo!(),
|
function_usage,
|
||||||
AirExpression::Finally { pattern, then } => todo!(),
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Finally { pattern, then } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
pattern,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
AirExpression::If {
|
AirExpression::If {
|
||||||
tipo,
|
|
||||||
pattern,
|
pattern,
|
||||||
then,
|
then,
|
||||||
otherwise,
|
otherwise,
|
||||||
} => todo!(),
|
..
|
||||||
AirExpression::Constr { tag, tipo, args } => todo!(),
|
} => {
|
||||||
AirExpression::RecordUpdate {
|
self.find_function_vars_and_depth(
|
||||||
highest_index,
|
pattern,
|
||||||
indices,
|
function_usage,
|
||||||
tipo,
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
otherwise,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Constr { args, .. } => {
|
||||||
|
for arg in args {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
arg,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::RecordUpdate { record, args, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
record,
|
record,
|
||||||
args,
|
function_usage,
|
||||||
} => todo!(),
|
function_holder,
|
||||||
AirExpression::RecordAccess {
|
tree_path,
|
||||||
field_index,
|
current_depth + 1,
|
||||||
tipo,
|
index_count.next(),
|
||||||
|
);
|
||||||
|
for arg in args {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
arg,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::RecordAccess { record, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
record,
|
record,
|
||||||
} => todo!(),
|
function_usage,
|
||||||
AirExpression::TupleIndex {
|
function_holder,
|
||||||
tipo,
|
tree_path,
|
||||||
tuple_index,
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::TupleIndex { tuple, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
tuple,
|
tuple,
|
||||||
} => todo!(),
|
function_usage,
|
||||||
AirExpression::ErrorTerm { tipo } => todo!(),
|
function_holder,
|
||||||
AirExpression::Trace { tipo, msg, then } => todo!(),
|
tree_path,
|
||||||
AirExpression::FieldsEmpty { constr } => todo!(),
|
current_depth + 1,
|
||||||
AirExpression::ListEmpty { list } => todo!(),
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Trace { msg, then, .. } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
msg,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
then,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::FieldsEmpty { constr } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
constr,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::ListEmpty { list } => {
|
||||||
|
self.find_function_vars_and_depth(
|
||||||
|
list,
|
||||||
|
function_usage,
|
||||||
|
function_holder,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
tree_path.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ use indexmap::IndexMap;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::TypedDataType,
|
ast::TypedDataType,
|
||||||
builtins::bool,
|
builtins::bool,
|
||||||
gen_uplc::builder::{lookup_data_type_by_tipo, DataTypeKey},
|
gen_uplc::builder::{lookup_data_type_by_tipo, DataTypeKey, FunctionAccessKey},
|
||||||
tipo::TypeVar,
|
tipo::{TypeVar, ValueConstructorVariant},
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -13,7 +13,42 @@ use crate::{
|
||||||
tipo::Type,
|
tipo::Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::tree::AirTree;
|
use super::tree::{AirExpression, AirStatement, AirTree};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct TreePath {
|
||||||
|
path: Vec<(usize, usize)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TreePath {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
TreePath { path: vec![] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, depth: usize, index: usize) {
|
||||||
|
self.path.push((depth, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop(&mut self) {
|
||||||
|
self.path.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IndexCounter {
|
||||||
|
current_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IndexCounter {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
IndexCounter { current_index: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(&mut self) -> usize {
|
||||||
|
let current_index = self.current_index;
|
||||||
|
self.current_index += 1;
|
||||||
|
current_index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_generic_id_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
|
pub fn get_generic_id_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
|
||||||
let mut generics_ids = vec![];
|
let mut generics_ids = vec![];
|
||||||
|
@ -261,3 +296,401 @@ pub fn handle_clause_guard(clause_guard: &ClauseGuard<Arc<Type>>) -> AirTree {
|
||||||
ClauseGuard::Constant(constant) => constants_ir(constant),
|
ClauseGuard::Constant(constant) => constants_ir(constant),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn erase_opaque_operations(
|
||||||
|
air_tree: &mut AirTree,
|
||||||
|
data_types: &IndexMap<DataTypeKey, &TypedDataType>,
|
||||||
|
) {
|
||||||
|
traverse_tree_with(air_tree, &mut TreePath::new(), 0, 0, &|air_tree, _| {
|
||||||
|
if let AirTree::Expression(e) = air_tree {
|
||||||
|
match e {
|
||||||
|
AirExpression::Constr { tipo, args, .. } => {
|
||||||
|
if check_replaceable_opaque_type(tipo, data_types) {
|
||||||
|
*air_tree = args.pop().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::RecordAccess { tipo, record, .. } => {
|
||||||
|
if check_replaceable_opaque_type(tipo, data_types) {
|
||||||
|
*air_tree = (**record).clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else if let AirTree::Statement {
|
||||||
|
statement:
|
||||||
|
AirStatement::FieldsExpose {
|
||||||
|
record, indices, ..
|
||||||
|
},
|
||||||
|
hoisted_over: Some(hoisted_over),
|
||||||
|
} = air_tree
|
||||||
|
{
|
||||||
|
let name = indices[0].1.clone();
|
||||||
|
if check_replaceable_opaque_type(&record.get_type(), data_types) {
|
||||||
|
*air_tree = AirTree::let_assignment(name, (**record).clone())
|
||||||
|
.hoist_over((**hoisted_over).clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn traverse_tree_with(
|
||||||
|
air_tree: &mut AirTree,
|
||||||
|
tree_path: &mut TreePath,
|
||||||
|
current_depth: usize,
|
||||||
|
depth_index: usize,
|
||||||
|
with: &impl Fn(&mut AirTree, &TreePath),
|
||||||
|
) {
|
||||||
|
let mut index_count = IndexCounter::new();
|
||||||
|
tree_path.push(current_depth, depth_index);
|
||||||
|
match air_tree {
|
||||||
|
AirTree::Statement {
|
||||||
|
statement,
|
||||||
|
hoisted_over: Some(hoisted_over),
|
||||||
|
} => {
|
||||||
|
match statement {
|
||||||
|
AirStatement::Let { value, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
value,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::DefineFunc { func_body, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
func_body,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::AssertConstr { constr, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
constr,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::AssertBool { value, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
value,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ClauseGuard { pattern, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
pattern,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ListClauseGuard { .. } => {}
|
||||||
|
AirStatement::TupleGuard { .. } => {}
|
||||||
|
AirStatement::FieldsExpose { record, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
record,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ListAccessor { list, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
list,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::ListExpose { .. } => {}
|
||||||
|
AirStatement::TupleAccessor { tuple, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
tuple,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirStatement::NoOp => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
hoisted_over,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirTree::Expression(e) => match e {
|
||||||
|
AirExpression::List { items, .. } => {
|
||||||
|
for item in items {
|
||||||
|
traverse_tree_with(
|
||||||
|
item,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::Tuple { items, .. } => {
|
||||||
|
for item in items {
|
||||||
|
traverse_tree_with(
|
||||||
|
item,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::Var {
|
||||||
|
constructor,
|
||||||
|
name,
|
||||||
|
variant_name,
|
||||||
|
} => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
AirExpression::Call { func, args, .. } => {
|
||||||
|
traverse_tree_with(func, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
for arg in args {
|
||||||
|
traverse_tree_with(arg, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::Fn { func_body, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
func_body,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Builtin { args, .. } => {
|
||||||
|
for arg in args {
|
||||||
|
traverse_tree_with(arg, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::BinOp { left, right, .. } => {
|
||||||
|
traverse_tree_with(left, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
right,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::UnOp { arg, .. } => {
|
||||||
|
traverse_tree_with(arg, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
AirExpression::UnWrapData { value, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
value,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::WrapData { value, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
value,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::When {
|
||||||
|
subject, clauses, ..
|
||||||
|
} => {
|
||||||
|
traverse_tree_with(
|
||||||
|
subject,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
clauses,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Clause {
|
||||||
|
pattern,
|
||||||
|
then,
|
||||||
|
otherwise,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
traverse_tree_with(
|
||||||
|
pattern,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
otherwise,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::ListClause {
|
||||||
|
then, otherwise, ..
|
||||||
|
} => {
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
otherwise,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::WrapClause { then, otherwise } => {
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
otherwise,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::TupleClause {
|
||||||
|
then, otherwise, ..
|
||||||
|
} => {
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
otherwise,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Finally { pattern, then } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
pattern,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
AirExpression::If {
|
||||||
|
pattern,
|
||||||
|
then,
|
||||||
|
otherwise,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
traverse_tree_with(
|
||||||
|
pattern,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(
|
||||||
|
otherwise,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Constr { args, .. } => {
|
||||||
|
for arg in args {
|
||||||
|
traverse_tree_with(arg, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::RecordUpdate { record, args, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
record,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
for arg in args {
|
||||||
|
traverse_tree_with(arg, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AirExpression::RecordAccess { record, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
record,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::TupleIndex { tuple, .. } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
tuple,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::Trace { msg, then, .. } => {
|
||||||
|
traverse_tree_with(msg, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
|
||||||
|
traverse_tree_with(then, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
AirExpression::FieldsEmpty { constr } => {
|
||||||
|
traverse_tree_with(
|
||||||
|
constr,
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next(),
|
||||||
|
with,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirExpression::ListEmpty { list } => {
|
||||||
|
traverse_tree_with(list, tree_path, current_depth + 1, index_count.next(), with);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
with(air_tree, tree_path);
|
||||||
|
|
||||||
|
tree_path.pop();
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{BinOp, Span, UnOp},
|
ast::{BinOp, Span, UnOp},
|
||||||
builtins::{data, list, void},
|
builtins::{bool, byte_array, data, int, list, string, void},
|
||||||
tipo::{Type, ValueConstructor, ValueConstructorVariant},
|
tipo::{Type, ValueConstructor, ValueConstructorVariant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1130,4 +1130,50 @@ impl AirTree {
|
||||||
_ => unreachable!("FOUND UNHOISTED STATEMENT"),
|
_ => unreachable!("FOUND UNHOISTED STATEMENT"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_type(&self) -> Arc<Type> {
|
||||||
|
match self {
|
||||||
|
AirTree::Statement {
|
||||||
|
hoisted_over: Some(hoisted_over),
|
||||||
|
..
|
||||||
|
} => hoisted_over.get_type(),
|
||||||
|
AirTree::Expression(e) => match e {
|
||||||
|
AirExpression::Int { .. } => int(),
|
||||||
|
AirExpression::String { .. } => string(),
|
||||||
|
AirExpression::ByteArray { .. } => byte_array(),
|
||||||
|
AirExpression::Bool { .. } => bool(),
|
||||||
|
AirExpression::List { tipo, .. }
|
||||||
|
| AirExpression::Tuple { tipo, .. }
|
||||||
|
| AirExpression::Call { tipo, .. }
|
||||||
|
| AirExpression::Builtin { tipo, .. }
|
||||||
|
| AirExpression::BinOp { tipo, .. }
|
||||||
|
| AirExpression::UnWrapData { tipo, .. }
|
||||||
|
| AirExpression::When { tipo, .. }
|
||||||
|
| AirExpression::If { tipo, .. }
|
||||||
|
| AirExpression::Constr { tipo, .. }
|
||||||
|
| AirExpression::RecordUpdate { tipo, .. }
|
||||||
|
| AirExpression::RecordAccess { tipo, .. }
|
||||||
|
| AirExpression::TupleIndex { tipo, .. }
|
||||||
|
| AirExpression::ErrorTerm { tipo }
|
||||||
|
| AirExpression::Trace { tipo, .. } => tipo.clone(),
|
||||||
|
AirExpression::Void => void(),
|
||||||
|
AirExpression::Var { constructor, .. } => constructor.tipo.clone(),
|
||||||
|
AirExpression::Fn { func_body, .. } => func_body.get_type(),
|
||||||
|
AirExpression::UnOp { op, .. } => match op {
|
||||||
|
UnOp::Not => bool(),
|
||||||
|
UnOp::Negate => int(),
|
||||||
|
},
|
||||||
|
AirExpression::WrapData { .. } => data(),
|
||||||
|
AirExpression::Clause { then, .. }
|
||||||
|
| AirExpression::ListClause { then, .. }
|
||||||
|
| AirExpression::WrapClause { then, .. }
|
||||||
|
| AirExpression::TupleClause { then, .. }
|
||||||
|
| AirExpression::Finally { then, .. } => then.get_type(),
|
||||||
|
|
||||||
|
AirExpression::FieldsEmpty { constr } => todo!(),
|
||||||
|
AirExpression::ListEmpty { list } => todo!(),
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue