support generics
This commit is contained in:
parent
16fbf5bbcd
commit
e4d9ca4586
|
@ -157,6 +157,33 @@ impl Type {
|
||||||
matches!(self, Self::Tuple { .. })
|
matches!(self, Self::Tuple { .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_generic(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Type::App {
|
||||||
|
public,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
} => {
|
||||||
|
let mut is_a_generic = false;
|
||||||
|
for arg in args {
|
||||||
|
is_a_generic = is_a_generic || arg.is_generic();
|
||||||
|
}
|
||||||
|
is_a_generic
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Var { tipo } => tipo.borrow().is_generic(),
|
||||||
|
Type::Tuple { elems } => {
|
||||||
|
let mut is_a_generic = false;
|
||||||
|
for elem in elems {
|
||||||
|
is_a_generic = is_a_generic || elem.is_generic();
|
||||||
|
}
|
||||||
|
is_a_generic
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
|
pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
|
||||||
if self.is_list() {
|
if self.is_list() {
|
||||||
match self {
|
match self {
|
||||||
|
@ -381,6 +408,14 @@ impl TypeVar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_generic(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
TypeVar::Generic { .. } => true,
|
||||||
|
TypeVar::Link { tipo } => tipo.is_generic(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
|
pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Link { tipo } => tipo.get_inner_type(),
|
Self::Link { tipo } => tipo.get_inner_type(),
|
||||||
|
|
|
@ -3277,65 +3277,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
params: depend_comp.args.clone(),
|
params: depend_comp.args.clone(),
|
||||||
recursive: depend_comp.recursive,
|
recursive: depend_comp.recursive,
|
||||||
}];
|
}];
|
||||||
let mut new_ir = depend_comp.ir.clone();
|
|
||||||
|
|
||||||
if depend_comp.recursive {
|
temp_ir.extend(depend_comp.ir.clone());
|
||||||
let mut insert_var_vec = vec![];
|
|
||||||
println!("FOund HERE");
|
|
||||||
for (index, air) in depend_comp.ir.clone().into_iter().enumerate().rev() {
|
|
||||||
if let Air::Var {
|
|
||||||
scope,
|
|
||||||
constructor,
|
|
||||||
name,
|
|
||||||
} = air
|
|
||||||
{
|
|
||||||
println!("found a var at index: {}", index);
|
|
||||||
if let ValueConstructorVariant::ModuleFn {
|
|
||||||
name: func_name,
|
|
||||||
module,
|
|
||||||
..
|
|
||||||
} = constructor.clone().variant
|
|
||||||
{
|
|
||||||
println!(
|
|
||||||
"Func Name: {func_name}, Dependency Name: {}",
|
|
||||||
dependency.function_name
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"Module Name: {module}, Dependency Module: {}",
|
|
||||||
dependency.module_name
|
|
||||||
);
|
|
||||||
if func_name.clone() == dependency.function_name.clone()
|
|
||||||
&& module == dependency.module_name.clone()
|
|
||||||
{
|
|
||||||
insert_var_vec.push((
|
|
||||||
index,
|
|
||||||
Air::Var {
|
|
||||||
scope: scope.clone(),
|
|
||||||
constructor: constructor.clone(),
|
|
||||||
name: func_name.clone(),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index, ir) in insert_var_vec {
|
|
||||||
new_ir.insert(index, ir);
|
|
||||||
let current_call = new_ir[index - 1].clone();
|
|
||||||
match current_call {
|
|
||||||
Air::Call { scope, count } => {
|
|
||||||
new_ir[index - 1] = Air::Call {
|
|
||||||
scope,
|
|
||||||
count: count + 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_ir.extend(new_ir);
|
|
||||||
|
|
||||||
temp_ir.append(&mut dep_ir);
|
temp_ir.append(&mut dep_ir);
|
||||||
|
|
||||||
|
@ -3374,8 +3317,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut func_comp =
|
let mut func_comp =
|
||||||
func_components.get(function_access_key).unwrap().clone();
|
func_components.get(function_access_key).unwrap().clone();
|
||||||
|
|
||||||
dbg!(&func_comp);
|
|
||||||
|
|
||||||
full_func_ir.push(Air::DefineFunc {
|
full_func_ir.push(Air::DefineFunc {
|
||||||
scope: scopes.clone(),
|
scope: scopes.clone(),
|
||||||
func_name: function_access_key.function_name.clone(),
|
func_name: function_access_key.function_name.clone(),
|
||||||
|
@ -3385,13 +3326,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut insert_var_vec = vec![];
|
let mut insert_var_vec = vec![];
|
||||||
println!("FOund HERE");
|
|
||||||
|
|
||||||
for (index, air) in func_comp.ir.clone().into_iter().enumerate().rev() {
|
for (index, air) in func_comp.ir.clone().into_iter().enumerate().rev() {
|
||||||
if let Air::Var {
|
if let Air::Var {
|
||||||
scope,
|
scope, constructor, ..
|
||||||
constructor,
|
|
||||||
name,
|
|
||||||
} = air
|
} = air
|
||||||
{
|
{
|
||||||
println!("found a var at index: {}", index);
|
println!("found a var at index: {}", index);
|
||||||
|
@ -3550,7 +3487,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} = &constructor.variant
|
} = &constructor.variant
|
||||||
{
|
{
|
||||||
if builtin.is_none() {
|
if builtin.is_none() {
|
||||||
let function_key = FunctionAccessKey {
|
let mut function_key = FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: name.clone(),
|
function_name: name.clone(),
|
||||||
};
|
};
|
||||||
|
@ -3568,6 +3505,33 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.build_ir(&function.body, &mut func_ir, scope.to_vec());
|
self.build_ir(&function.body, &mut func_ir, scope.to_vec());
|
||||||
|
|
||||||
|
let (param_types, _) = constructor.tipo.function_types().unwrap();
|
||||||
|
|
||||||
|
let mut param_name_types = vec![];
|
||||||
|
|
||||||
|
for (index, arg) in function.arguments.iter().enumerate() {
|
||||||
|
if arg.tipo.is_generic() {
|
||||||
|
param_name_types.push((
|
||||||
|
arg.arg_name
|
||||||
|
.get_variable_name()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string(),
|
||||||
|
param_types[index].clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (variant_name, func_ir) =
|
||||||
|
self.monomorphize(func_ir, param_name_types);
|
||||||
|
|
||||||
|
function_key = FunctionAccessKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
function_name: format!(
|
||||||
|
"{}_{variant_name}",
|
||||||
|
function_key.function_name
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
to_be_defined_map.insert(function_key.clone(), scope.to_vec());
|
to_be_defined_map.insert(function_key.clone(), scope.to_vec());
|
||||||
let mut func_calls = vec![];
|
let mut func_calls = vec![];
|
||||||
|
|
||||||
|
@ -3588,8 +3552,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
{
|
{
|
||||||
func_calls.push(FunctionAccessKey {
|
func_calls.push(FunctionAccessKey {
|
||||||
module_name: module.clone(),
|
module_name: module.clone(),
|
||||||
function_name: func_name.clone(),
|
function_name: format!("{func_name}_{variant_name}"),
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3604,9 +3568,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let recursive =
|
let recursive = if let Ok(index) =
|
||||||
if let Ok(index) = func_calls.binary_search(&function_key) {
|
func_calls.binary_search(&function_key)
|
||||||
|
{
|
||||||
func_calls.remove(index);
|
func_calls.remove(index);
|
||||||
|
while let Ok(index) = func_calls.binary_search(&function_key) {
|
||||||
|
func_calls.remove(index);
|
||||||
|
}
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -3656,6 +3624,80 @@ impl<'a> CodeGenerator<'a> {
|
||||||
func_index_map.insert(func.0.clone(), get_common_ancestor(func.1, index_scope));
|
func_index_map.insert(func.0.clone(), get_common_ancestor(func.1, index_scope));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn monomorphize(
|
||||||
|
&mut self,
|
||||||
|
ir: Vec<Air>,
|
||||||
|
param_types: Vec<(String, Arc<Type>)>,
|
||||||
|
) -> (String, Vec<Air>) {
|
||||||
|
let mut used_param_to_type = vec![];
|
||||||
|
let mut new_air = ir.clone();
|
||||||
|
|
||||||
|
for (index, ir) in ir.into_iter().enumerate() {
|
||||||
|
if let Air::Var {
|
||||||
|
scope,
|
||||||
|
constructor:
|
||||||
|
ValueConstructor {
|
||||||
|
public, variant, ..
|
||||||
|
},
|
||||||
|
name,
|
||||||
|
} = ir
|
||||||
|
{
|
||||||
|
let exists = param_types.iter().find(|(n, _)| n == &name);
|
||||||
|
|
||||||
|
if let Some((n, t)) = exists {
|
||||||
|
used_param_to_type.push((n.clone(), t.clone()));
|
||||||
|
|
||||||
|
new_air[index] = Air::Var {
|
||||||
|
scope,
|
||||||
|
constructor: ValueConstructor {
|
||||||
|
public,
|
||||||
|
variant,
|
||||||
|
tipo: t.clone(),
|
||||||
|
},
|
||||||
|
name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_name = String::new();
|
||||||
|
|
||||||
|
for (_, t) in used_param_to_type {
|
||||||
|
get_variant_name(&mut new_name, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
(new_name, new_air)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_variant_name(new_name: &mut String, t: Arc<Type>) {
|
||||||
|
new_name.push_str(&format!(
|
||||||
|
"_{}",
|
||||||
|
if t.is_string() {
|
||||||
|
"string".to_string()
|
||||||
|
} else if t.is_int() {
|
||||||
|
"int".to_string()
|
||||||
|
} else if t.is_bool() {
|
||||||
|
"bool".to_string()
|
||||||
|
} else if t.is_map() {
|
||||||
|
let mut full_type = "map".to_string();
|
||||||
|
let pair_type = &t.get_inner_type()[0];
|
||||||
|
let fst_type = &pair_type.get_inner_type()[0];
|
||||||
|
let snd_type = &pair_type.get_inner_type()[1];
|
||||||
|
|
||||||
|
get_variant_name(&mut full_type, fst_type.clone());
|
||||||
|
get_variant_name(&mut full_type, snd_type.clone());
|
||||||
|
full_type
|
||||||
|
} else if t.is_list() {
|
||||||
|
let mut full_type = "list".to_string();
|
||||||
|
let list_type = &t.get_inner_type()[0];
|
||||||
|
get_variant_name(&mut full_type, list_type.clone());
|
||||||
|
full_type
|
||||||
|
} else {
|
||||||
|
"data".to_string()
|
||||||
|
}
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant> {
|
fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant> {
|
||||||
|
|
Loading…
Reference in New Issue