refactor away from tuples
This commit is contained in:
		
							parent
							
								
									0069c1f68a
								
							
						
					
					
						commit
						d4f3eafc22
					
				| 
						 | 
					@ -82,24 +82,59 @@ impl Default for ScopeLevels {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Eq, PartialEq, Hash)]
 | 
				
			||||||
 | 
					pub struct ConstrFieldKey {
 | 
				
			||||||
 | 
					    pub local_var: String,
 | 
				
			||||||
 | 
					    pub field_name: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Eq, PartialEq, Hash)]
 | 
				
			||||||
 | 
					pub struct DataTypeKey {
 | 
				
			||||||
 | 
					    pub module_name: String,
 | 
				
			||||||
 | 
					    pub defined_type: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub type ConstrUsageKey = String;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Eq, PartialEq, Hash)]
 | 
				
			||||||
 | 
					pub struct FunctionAccessKey {
 | 
				
			||||||
 | 
					    pub module_name: String,
 | 
				
			||||||
 | 
					    pub function_name: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub struct ConstrConversionInfo {
 | 
				
			||||||
 | 
					    local_var: String,
 | 
				
			||||||
 | 
					    field: Option<String>,
 | 
				
			||||||
 | 
					    scope: ScopeLevels,
 | 
				
			||||||
 | 
					    index: Option<u64>,
 | 
				
			||||||
 | 
					    returning_type: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub struct ScopedExpr {
 | 
				
			||||||
 | 
					    scope: ScopeLevels,
 | 
				
			||||||
 | 
					    expr: TypedExpr,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct CodeGenerator<'a> {
 | 
					pub struct CodeGenerator<'a> {
 | 
				
			||||||
    uplc_function_holder: Vec<(String, Term<Name>)>,
 | 
					    uplc_function_holder: Vec<(String, Term<Name>)>,
 | 
				
			||||||
    uplc_function_holder_lookup: IndexMap<(String, String), ScopeLevels>,
 | 
					    uplc_function_holder_lookup: IndexMap<FunctionAccessKey, ScopeLevels>,
 | 
				
			||||||
    uplc_data_holder_lookup: IndexMap<(String, String, String), (ScopeLevels, TypedExpr)>,
 | 
					    uplc_data_holder_lookup: IndexMap<ConstrFieldKey, ScopedExpr>,
 | 
				
			||||||
    uplc_data_constr_lookup: IndexMap<(String, String), ScopeLevels>,
 | 
					    uplc_data_constr_lookup: IndexMap<DataTypeKey, ScopeLevels>,
 | 
				
			||||||
    uplc_data_usage_holder_lookup: IndexMap<(String, String), ScopeLevels>,
 | 
					    uplc_data_usage_holder_lookup: IndexMap<ConstrUsageKey, ScopeLevels>,
 | 
				
			||||||
    functions: &'a HashMap<(String, String), &'a Function<Arc<tipo::Type>, TypedExpr>>,
 | 
					    functions: &'a HashMap<FunctionAccessKey, &'a Function<Arc<tipo::Type>, TypedExpr>>,
 | 
				
			||||||
    // type_aliases: &'a HashMap<(String, String), &'a TypeAlias<Arc<tipo::Type>>>,
 | 
					    // type_aliases: &'a HashMap<(String, String), &'a TypeAlias<Arc<tipo::Type>>>,
 | 
				
			||||||
    data_types: &'a HashMap<(String, String), &'a DataType<Arc<tipo::Type>>>,
 | 
					    data_types: &'a HashMap<DataTypeKey, &'a DataType<Arc<tipo::Type>>>,
 | 
				
			||||||
    // imports: &'a HashMap<(String, String), &'a Use<String>>,
 | 
					    // imports: &'a HashMap<(String, String), &'a Use<String>>,
 | 
				
			||||||
    // constants: &'a HashMap<(String, String), &'a ModuleConstant<Arc<tipo::Type>, String>>,
 | 
					    // constants: &'a HashMap<(String, String), &'a ModuleConstant<Arc<tipo::Type>, String>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> CodeGenerator<'a> {
 | 
					impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
    pub fn new(
 | 
					    pub fn new(
 | 
				
			||||||
        functions: &'a HashMap<(String, String), &'a Function<Arc<tipo::Type>, TypedExpr>>,
 | 
					        functions: &'a HashMap<FunctionAccessKey, &'a Function<Arc<tipo::Type>, TypedExpr>>,
 | 
				
			||||||
        // type_aliases: &'a HashMap<(String, String), &'a TypeAlias<Arc<tipo::Type>>>,
 | 
					        // type_aliases: &'a HashMap<(String, String), &'a TypeAlias<Arc<tipo::Type>>>,
 | 
				
			||||||
        data_types: &'a HashMap<(String, String), &'a DataType<Arc<tipo::Type>>>,
 | 
					        data_types: &'a HashMap<DataTypeKey, &'a DataType<Arc<tipo::Type>>>,
 | 
				
			||||||
        // imports: &'a HashMap<(String, String), &'a Use<String>>,
 | 
					        // imports: &'a HashMap<(String, String), &'a Use<String>>,
 | 
				
			||||||
        // constants: &'a HashMap<(String, String), &'a ModuleConstant<Arc<tipo::Type>, String>>,
 | 
					        // constants: &'a HashMap<(String, String), &'a ModuleConstant<Arc<tipo::Type>, String>>,
 | 
				
			||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
| 
						 | 
					@ -232,26 +267,45 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    ValueConstructorVariant::ModuleFn { name, module, .. } => {
 | 
					                    ValueConstructorVariant::ModuleFn { name, module, .. } => {
 | 
				
			||||||
                        if self
 | 
					                        if self
 | 
				
			||||||
                            .uplc_function_holder_lookup
 | 
					                            .uplc_function_holder_lookup
 | 
				
			||||||
                            .get(&(module.to_string(), name.to_string()))
 | 
					                            .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                function_name: name.to_string(),
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
                            .is_none()
 | 
					                            .is_none()
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            let func_def = self
 | 
					                            let func_def = self
 | 
				
			||||||
                                .functions
 | 
					                                .functions
 | 
				
			||||||
                                .get(&(module.to_string(), name.to_string()))
 | 
					                                .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                                    module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                    function_name: name.to_string(),
 | 
				
			||||||
 | 
					                                })
 | 
				
			||||||
                                .unwrap();
 | 
					                                .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            self.recurse_scope_level(&func_def.body, scope_level.clone());
 | 
					                            self.recurse_scope_level(&func_def.body, scope_level.clone());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            self.uplc_function_holder_lookup
 | 
					                            self.uplc_function_holder_lookup.insert(
 | 
				
			||||||
                                .insert((module, name), scope_level);
 | 
					                                FunctionAccessKey {
 | 
				
			||||||
 | 
					                                    module_name: module,
 | 
				
			||||||
 | 
					                                    function_name: name,
 | 
				
			||||||
 | 
					                                },
 | 
				
			||||||
 | 
					                                scope_level,
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
                        } else if scope_level.is_less_than(
 | 
					                        } else if scope_level.is_less_than(
 | 
				
			||||||
                            self.uplc_function_holder_lookup
 | 
					                            self.uplc_function_holder_lookup
 | 
				
			||||||
                                .get(&(module.to_string(), name.to_string()))
 | 
					                                .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                                    module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                    function_name: name.to_string(),
 | 
				
			||||||
 | 
					                                })
 | 
				
			||||||
                                .unwrap(),
 | 
					                                .unwrap(),
 | 
				
			||||||
                            false,
 | 
					                            false,
 | 
				
			||||||
                        ) {
 | 
					                        ) {
 | 
				
			||||||
                            self.uplc_function_holder_lookup
 | 
					                            self.uplc_function_holder_lookup.insert(
 | 
				
			||||||
                                .insert((module, name), scope_level);
 | 
					                                FunctionAccessKey {
 | 
				
			||||||
 | 
					                                    module_name: module,
 | 
				
			||||||
 | 
					                                    function_name: name,
 | 
				
			||||||
 | 
					                                },
 | 
				
			||||||
 | 
					                                scope_level,
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    ValueConstructorVariant::Record { .. } => {
 | 
					                    ValueConstructorVariant::Record { .. } => {
 | 
				
			||||||
| 
						 | 
					@ -321,11 +375,10 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    self.recurse_scope_level(&branch.body, scope_level.scope_increment_sequence(1));
 | 
					                    self.recurse_scope_level(&branch.body, scope_level.scope_increment_sequence(1));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            a @ TypedExpr::RecordAccess { label, record, .. } => {
 | 
					            expr @ TypedExpr::RecordAccess { label, record, .. } => {
 | 
				
			||||||
                self.recurse_scope_level(record, scope_level.clone());
 | 
					                self.recurse_scope_level(record, scope_level.clone());
 | 
				
			||||||
                let mut is_var = false;
 | 
					                let mut is_var = false;
 | 
				
			||||||
                let mut current_var_name = "".to_string();
 | 
					                let mut current_var_name = String::new();
 | 
				
			||||||
                let mut module = "".to_string();
 | 
					 | 
				
			||||||
                let mut current_record = *record.clone();
 | 
					                let mut current_record = *record.clone();
 | 
				
			||||||
                let mut current_scope = scope_level;
 | 
					                let mut current_scope = scope_level;
 | 
				
			||||||
                while !is_var {
 | 
					                while !is_var {
 | 
				
			||||||
| 
						 | 
					@ -336,19 +389,13 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                            constructor.clone().variant.clone(),
 | 
					                            constructor.clone().variant.clone(),
 | 
				
			||||||
                            (*constructor.tipo).clone(),
 | 
					                            (*constructor.tipo).clone(),
 | 
				
			||||||
                        ) {
 | 
					                        ) {
 | 
				
			||||||
                            (
 | 
					                            (ValueConstructorVariant::LocalVariable { .. }, Type::App { .. }) => {
 | 
				
			||||||
                                ValueConstructorVariant::LocalVariable { .. },
 | 
					 | 
				
			||||||
                                Type::App {
 | 
					 | 
				
			||||||
                                    module: app_module, ..
 | 
					 | 
				
			||||||
                                },
 | 
					 | 
				
			||||||
                            ) => {
 | 
					 | 
				
			||||||
                                current_var_name = if current_var_name.is_empty() {
 | 
					                                current_var_name = if current_var_name.is_empty() {
 | 
				
			||||||
                                    name
 | 
					                                    name
 | 
				
			||||||
                                } else {
 | 
					                                } else {
 | 
				
			||||||
                                    format!("{name}_field_{current_var_name}")
 | 
					                                    format!("{name}_field_{current_var_name}")
 | 
				
			||||||
                                };
 | 
					                                };
 | 
				
			||||||
                                is_var = true;
 | 
					                                is_var = true;
 | 
				
			||||||
                                module = app_module.to_string();
 | 
					 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            _ => todo!(),
 | 
					                            _ => todo!(),
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
| 
						 | 
					@ -365,35 +412,46 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if let Some(val) = self.uplc_data_holder_lookup.get(&(
 | 
					                if let Some(val) = self.uplc_data_holder_lookup.get(&ConstrFieldKey {
 | 
				
			||||||
                    module.to_string(),
 | 
					                    local_var: current_var_name.clone(),
 | 
				
			||||||
                    current_var_name.clone(),
 | 
					                    field_name: label.clone(),
 | 
				
			||||||
                    label.clone(),
 | 
					                }) {
 | 
				
			||||||
                )) {
 | 
					                    if current_scope.is_less_than(&val.scope, false) {
 | 
				
			||||||
                    if current_scope.is_less_than(&val.0, false) {
 | 
					 | 
				
			||||||
                        self.uplc_data_holder_lookup.insert(
 | 
					                        self.uplc_data_holder_lookup.insert(
 | 
				
			||||||
                            (module.to_string(), current_var_name.clone(), label.clone()),
 | 
					                            ConstrFieldKey {
 | 
				
			||||||
                            (current_scope.clone(), a.clone()),
 | 
					                                local_var: current_var_name.clone(),
 | 
				
			||||||
 | 
					                                field_name: label.clone(),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            ScopedExpr {
 | 
				
			||||||
 | 
					                                scope: current_scope.clone(),
 | 
				
			||||||
 | 
					                                expr: expr.clone(),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    self.uplc_data_holder_lookup.insert(
 | 
					                    self.uplc_data_holder_lookup.insert(
 | 
				
			||||||
                        (module.to_string(), current_var_name.clone(), label.clone()),
 | 
					                        ConstrFieldKey {
 | 
				
			||||||
                        (current_scope.clone(), a.clone()),
 | 
					                            local_var: current_var_name.clone(),
 | 
				
			||||||
 | 
					                            field_name: label.clone(),
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        ScopedExpr {
 | 
				
			||||||
 | 
					                            scope: current_scope.clone(),
 | 
				
			||||||
 | 
					                            expr: expr.clone(),
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if let Some(val) = self
 | 
					                if let Some(val) = self
 | 
				
			||||||
                    .uplc_data_usage_holder_lookup
 | 
					                    .uplc_data_usage_holder_lookup
 | 
				
			||||||
                    .get(&(module.to_string(), current_var_name.clone()))
 | 
					                    .get(¤t_var_name.clone())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if current_scope.is_less_than(val, false) {
 | 
					                    if current_scope.is_less_than(val, false) {
 | 
				
			||||||
                        self.uplc_data_usage_holder_lookup
 | 
					                        self.uplc_data_usage_holder_lookup
 | 
				
			||||||
                            .insert((module, current_var_name), current_scope);
 | 
					                            .insert(current_var_name, current_scope);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    self.uplc_data_usage_holder_lookup
 | 
					                    self.uplc_data_usage_holder_lookup
 | 
				
			||||||
                        .insert((module, current_var_name), current_scope);
 | 
					                        .insert(current_var_name, current_scope);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TypedExpr::ModuleSelect { constructor, .. } => match constructor {
 | 
					            TypedExpr::ModuleSelect { constructor, .. } => match constructor {
 | 
				
			||||||
| 
						 | 
					@ -401,12 +459,18 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                ModuleValueConstructor::Fn { module, name, .. } => {
 | 
					                ModuleValueConstructor::Fn { module, name, .. } => {
 | 
				
			||||||
                    if self
 | 
					                    if self
 | 
				
			||||||
                        .uplc_function_holder_lookup
 | 
					                        .uplc_function_holder_lookup
 | 
				
			||||||
                        .get(&(module.to_string(), name.to_string()))
 | 
					                        .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                            module_name: module.to_string(),
 | 
				
			||||||
 | 
					                            function_name: name.to_string(),
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
                        .is_none()
 | 
					                        .is_none()
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        let func_def = self
 | 
					                        let func_def = self
 | 
				
			||||||
                            .functions
 | 
					                            .functions
 | 
				
			||||||
                            .get(&(module.to_string(), name.to_string()))
 | 
					                            .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                function_name: name.to_string(),
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
                            .unwrap();
 | 
					                            .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        self.recurse_scope_level(
 | 
					                        self.recurse_scope_level(
 | 
				
			||||||
| 
						 | 
					@ -415,21 +479,35 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                                .scope_increment_sequence(func_def.arguments.len() as i32 + 1),
 | 
					                                .scope_increment_sequence(func_def.arguments.len() as i32 + 1),
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        self.uplc_function_holder_lookup
 | 
					                        self.uplc_function_holder_lookup.insert(
 | 
				
			||||||
                            .insert((module.to_string(), name.to_string()), scope_level);
 | 
					                            FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                function_name: name.to_string(),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            scope_level,
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
                    } else if scope_level.is_less_than(
 | 
					                    } else if scope_level.is_less_than(
 | 
				
			||||||
                        self.uplc_function_holder_lookup
 | 
					                        self.uplc_function_holder_lookup
 | 
				
			||||||
                            .get(&(module.to_string(), name.to_string()))
 | 
					                            .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                function_name: name.to_string(),
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
                            .unwrap(),
 | 
					                            .unwrap(),
 | 
				
			||||||
                        false,
 | 
					                        false,
 | 
				
			||||||
                    ) {
 | 
					                    ) {
 | 
				
			||||||
                        let func_def = self
 | 
					                        let func_def = self
 | 
				
			||||||
                            .functions
 | 
					                            .functions
 | 
				
			||||||
                            .get(&(module.to_string(), name.to_string()))
 | 
					                            .get(&FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                function_name: name.to_string(),
 | 
				
			||||||
 | 
					                            })
 | 
				
			||||||
                            .unwrap();
 | 
					                            .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        self.uplc_function_holder_lookup.insert(
 | 
					                        self.uplc_function_holder_lookup.insert(
 | 
				
			||||||
                            (module.to_string(), name.to_string()),
 | 
					                            FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                function_name: name.to_string(),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
                            scope_level
 | 
					                            scope_level
 | 
				
			||||||
                                .scope_increment_sequence(func_def.arguments.len() as i32 + 1),
 | 
					                                .scope_increment_sequence(func_def.arguments.len() as i32 + 1),
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
| 
						 | 
					@ -471,17 +549,27 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                match &**tipo {
 | 
					                match &**tipo {
 | 
				
			||||||
                    Type::App { module, name, .. } => {
 | 
					                    Type::App { module, name, .. } => {
 | 
				
			||||||
                        if let Some(val) = self
 | 
					                        if let Some(val) = self.uplc_data_constr_lookup.get(&DataTypeKey {
 | 
				
			||||||
                            .uplc_data_constr_lookup
 | 
					                            module_name: module.to_string(),
 | 
				
			||||||
                            .get(&(module.to_string(), name.clone()))
 | 
					                            defined_type: name.clone(),
 | 
				
			||||||
                        {
 | 
					                        }) {
 | 
				
			||||||
                            if scope_level.is_less_than(val, false) {
 | 
					                            if scope_level.is_less_than(val, false) {
 | 
				
			||||||
                                self.uplc_data_constr_lookup
 | 
					                                self.uplc_data_constr_lookup.insert(
 | 
				
			||||||
                                    .insert((module.to_string(), name.clone()), scope_level);
 | 
					                                    DataTypeKey {
 | 
				
			||||||
 | 
					                                        module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                        defined_type: name.clone(),
 | 
				
			||||||
 | 
					                                    },
 | 
				
			||||||
 | 
					                                    scope_level,
 | 
				
			||||||
 | 
					                                );
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            self.uplc_data_constr_lookup
 | 
					                            self.uplc_data_constr_lookup.insert(
 | 
				
			||||||
                                .insert((module.to_string(), name.clone()), scope_level);
 | 
					                                DataTypeKey {
 | 
				
			||||||
 | 
					                                    module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                    defined_type: name.clone(),
 | 
				
			||||||
 | 
					                                },
 | 
				
			||||||
 | 
					                                scope_level,
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Type::Fn { .. } => {
 | 
					                    Type::Fn { .. } => {
 | 
				
			||||||
| 
						 | 
					@ -507,7 +595,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                            rest => todo!("implement: {:#?}", rest),
 | 
					                            rest => todo!("implement: {:#?}", rest),
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        let mut type_name = "".to_string();
 | 
					                        let mut type_name = String::new();
 | 
				
			||||||
                        let mut is_app = false;
 | 
					                        let mut is_app = false;
 | 
				
			||||||
                        let current_tipo = &*tipo;
 | 
					                        let current_tipo = &*tipo;
 | 
				
			||||||
                        while !is_app {
 | 
					                        while !is_app {
 | 
				
			||||||
| 
						 | 
					@ -584,61 +672,70 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                                        kind: AssignmentKind::Let,
 | 
					                                        kind: AssignmentKind::Let,
 | 
				
			||||||
                                    };
 | 
					                                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                    if let Some(val) = self.uplc_data_holder_lookup.get(&(
 | 
					                                    if let Some(val) =
 | 
				
			||||||
                                        module.to_string(),
 | 
					                                        self.uplc_data_holder_lookup.get(&ConstrFieldKey {
 | 
				
			||||||
                                        var_name.clone(),
 | 
					                                            local_var: var_name.clone(),
 | 
				
			||||||
                                        label.clone(),
 | 
					                                            field_name: label.clone(),
 | 
				
			||||||
                                    )) {
 | 
					                                        })
 | 
				
			||||||
                                        if scope_level.is_less_than(&val.0, false) {
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        if scope_level.is_less_than(&val.scope, false) {
 | 
				
			||||||
                                            self.uplc_data_holder_lookup.insert(
 | 
					                                            self.uplc_data_holder_lookup.insert(
 | 
				
			||||||
                                                (
 | 
					                                                ConstrFieldKey {
 | 
				
			||||||
                                                    module.to_string(),
 | 
					                                                    local_var: var_name.clone(),
 | 
				
			||||||
                                                    var_name.clone(),
 | 
					                                                    field_name: label.clone(),
 | 
				
			||||||
                                                    label.clone(),
 | 
					                                                },
 | 
				
			||||||
                                                ),
 | 
					                                                ScopedExpr {
 | 
				
			||||||
                                                (
 | 
					                                                    scope: scope_level.scope_increment(1),
 | 
				
			||||||
                                                    scope_level.scope_increment(1),
 | 
					                                                    expr: record_access.clone(),
 | 
				
			||||||
                                                    record_access.clone(),
 | 
					                                                },
 | 
				
			||||||
                                                ),
 | 
					 | 
				
			||||||
                                            );
 | 
					                                            );
 | 
				
			||||||
                                        }
 | 
					                                        }
 | 
				
			||||||
                                    } else {
 | 
					                                    } else {
 | 
				
			||||||
                                        self.uplc_data_holder_lookup.insert(
 | 
					                                        self.uplc_data_holder_lookup.insert(
 | 
				
			||||||
                                            (module.to_string(), var_name.clone(), label.clone()),
 | 
					                                            ConstrFieldKey {
 | 
				
			||||||
                                            (scope_level.scope_increment(1), record_access.clone()),
 | 
					                                                local_var: var_name.clone(),
 | 
				
			||||||
 | 
					                                                field_name: label.clone(),
 | 
				
			||||||
 | 
					                                            },
 | 
				
			||||||
 | 
					                                            ScopedExpr {
 | 
				
			||||||
 | 
					                                                scope: scope_level.scope_increment(1),
 | 
				
			||||||
 | 
					                                                expr: record_access.clone(),
 | 
				
			||||||
 | 
					                                            },
 | 
				
			||||||
                                        );
 | 
					                                        );
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                    if let Some(val) = self
 | 
					                                    if let Some(val) =
 | 
				
			||||||
                                        .uplc_data_usage_holder_lookup
 | 
					                                        self.uplc_data_usage_holder_lookup.get(&var_name.clone())
 | 
				
			||||||
                                        .get(&(module.to_string(), var_name.clone()))
 | 
					 | 
				
			||||||
                                    {
 | 
					                                    {
 | 
				
			||||||
                                        if scope_level.is_less_than(val, false) {
 | 
					                                        if scope_level.is_less_than(val, false) {
 | 
				
			||||||
                                            self.uplc_data_usage_holder_lookup.insert(
 | 
					                                            self.uplc_data_usage_holder_lookup
 | 
				
			||||||
                                                (module.to_string(), var_name.clone()),
 | 
					                                                .insert(var_name.clone(), scope_level.clone());
 | 
				
			||||||
                                                scope_level.clone(),
 | 
					 | 
				
			||||||
                                            );
 | 
					 | 
				
			||||||
                                        }
 | 
					                                        }
 | 
				
			||||||
                                    } else {
 | 
					                                    } else {
 | 
				
			||||||
                                        self.uplc_data_usage_holder_lookup.insert(
 | 
					                                        self.uplc_data_usage_holder_lookup
 | 
				
			||||||
                                            (module.to_string(), var_name.clone()),
 | 
					                                            .insert(var_name.clone(), scope_level.clone());
 | 
				
			||||||
                                            scope_level.clone(),
 | 
					 | 
				
			||||||
                                        );
 | 
					 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                    if let Some(val) = self
 | 
					                                    if let Some(val) =
 | 
				
			||||||
                                        .uplc_data_constr_lookup
 | 
					                                        self.uplc_data_constr_lookup.get(&DataTypeKey {
 | 
				
			||||||
                                        .get(&(module.to_string(), type_name.clone()))
 | 
					                                            module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                            defined_type: type_name.clone(),
 | 
				
			||||||
 | 
					                                        })
 | 
				
			||||||
                                    {
 | 
					                                    {
 | 
				
			||||||
                                        if scope_level.is_less_than(val, false) {
 | 
					                                        if scope_level.is_less_than(val, false) {
 | 
				
			||||||
                                            self.uplc_data_constr_lookup.insert(
 | 
					                                            self.uplc_data_constr_lookup.insert(
 | 
				
			||||||
                                                (module.to_string(), type_name.clone()),
 | 
					                                                DataTypeKey {
 | 
				
			||||||
 | 
					                                                    module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                                    defined_type: type_name.clone(),
 | 
				
			||||||
 | 
					                                                },
 | 
				
			||||||
                                                scope_level.clone(),
 | 
					                                                scope_level.clone(),
 | 
				
			||||||
                                            );
 | 
					                                            );
 | 
				
			||||||
                                        }
 | 
					                                        }
 | 
				
			||||||
                                    } else {
 | 
					                                    } else {
 | 
				
			||||||
                                        self.uplc_data_constr_lookup.insert(
 | 
					                                        self.uplc_data_constr_lookup.insert(
 | 
				
			||||||
                                            (module.to_string(), type_name.clone()),
 | 
					                                            DataTypeKey {
 | 
				
			||||||
 | 
					                                                module_name: module.to_string(),
 | 
				
			||||||
 | 
					                                                defined_type: type_name.clone(),
 | 
				
			||||||
 | 
					                                            },
 | 
				
			||||||
                                            scope_level.clone(),
 | 
					                                            scope_level.clone(),
 | 
				
			||||||
                                        );
 | 
					                                        );
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
| 
						 | 
					@ -671,7 +768,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                        .maybe_insert_def(term, scope_level.scope_increment_sequence(i as i32 + 1));
 | 
					                        .maybe_insert_def(term, scope_level.scope_increment_sequence(i as i32 + 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    self.uplc_function_holder
 | 
					                    self.uplc_function_holder
 | 
				
			||||||
                        .push(("".to_string(), term.clone()));
 | 
					                        .push((String::new(), term.clone()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                self.uplc_function_holder.pop().unwrap().1
 | 
					                self.uplc_function_holder.pop().unwrap().1
 | 
				
			||||||
| 
						 | 
					@ -711,9 +808,10 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    let mut term: Term<Name> =
 | 
					                    let mut term: Term<Name> =
 | 
				
			||||||
                        Term::Constant(Constant::ProtoList(uplc::ast::Type::Data, vec![]));
 | 
					                        Term::Constant(Constant::ProtoList(uplc::ast::Type::Data, vec![]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if let Some(data_type) =
 | 
					                    if let Some(data_type) = self.data_types.get(&DataTypeKey {
 | 
				
			||||||
                        self.data_types.get(&(module.to_string(), name.to_string()))
 | 
					                        module_name: module.to_string(),
 | 
				
			||||||
                    {
 | 
					                        defined_type: name.to_string(),
 | 
				
			||||||
 | 
					                    }) {
 | 
				
			||||||
                        let constr = data_type
 | 
					                        let constr = data_type
 | 
				
			||||||
                            .constructors
 | 
					                            .constructors
 | 
				
			||||||
                            .iter()
 | 
					                            .iter()
 | 
				
			||||||
| 
						 | 
					@ -1075,7 +1173,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut is_var = false;
 | 
					                let mut is_var = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut current_var_name = "".to_string();
 | 
					                let mut current_var_name = String::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut current_subject = subject.clone();
 | 
					                let mut current_subject = subject.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1111,7 +1209,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let current_clauses = clauses.clone();
 | 
					                let current_clauses = clauses.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut current_module = "".to_string();
 | 
					                let mut current_module = String::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut total_constr_length = 0;
 | 
					                let mut total_constr_length = 0;
 | 
				
			||||||
                let pattern = &clauses[0].pattern[0];
 | 
					                let pattern = &clauses[0].pattern[0];
 | 
				
			||||||
| 
						 | 
					@ -1120,12 +1218,16 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    Pattern::Constructor { tipo, .. } => {
 | 
					                    Pattern::Constructor { tipo, .. } => {
 | 
				
			||||||
                        let mut is_app = false;
 | 
					                        let mut is_app = false;
 | 
				
			||||||
                        let mut tipo = &**tipo;
 | 
					                        let mut tipo = &**tipo;
 | 
				
			||||||
                        let mut key: (String, String) = ("".to_string(), "".to_string());
 | 
					                        let mut key = DataTypeKey {
 | 
				
			||||||
 | 
					                            module_name: String::new(),
 | 
				
			||||||
 | 
					                            defined_type: String::new(),
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
                        while !is_app {
 | 
					                        while !is_app {
 | 
				
			||||||
                            match tipo {
 | 
					                            match tipo {
 | 
				
			||||||
                                Type::App { module, name, .. } => {
 | 
					                                Type::App { module, name, .. } => {
 | 
				
			||||||
                                    is_app = true;
 | 
					                                    is_app = true;
 | 
				
			||||||
                                    key = (module.clone(), name.clone());
 | 
					                                    key.module_name = module.clone();
 | 
				
			||||||
 | 
					                                    key.defined_type = name.clone();
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                Type::Fn { ret, .. } => {
 | 
					                                Type::Fn { ret, .. } => {
 | 
				
			||||||
                                    tipo = ret;
 | 
					                                    tipo = ret;
 | 
				
			||||||
| 
						 | 
					@ -1161,13 +1263,13 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                                        let label =
 | 
					                                        let label =
 | 
				
			||||||
                                            field.clone().label.unwrap_or(format!("{index}"));
 | 
					                                            field.clone().label.unwrap_or(format!("{index}"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                        if let Some((_, TypedExpr::Assignment { pattern, .. })) =
 | 
					                                        if let Some(ScopedExpr {
 | 
				
			||||||
                                            self.uplc_data_holder_lookup.get(&(
 | 
					                                            expr: TypedExpr::Assignment { pattern, .. },
 | 
				
			||||||
                                                key.0.clone(),
 | 
					                                            ..
 | 
				
			||||||
                                                current_var_name.to_string(),
 | 
					                                        }) = self.uplc_data_holder_lookup.get(&ConstrFieldKey {
 | 
				
			||||||
                                                label.clone(),
 | 
					                                            local_var: current_var_name.to_string(),
 | 
				
			||||||
                                            ))
 | 
					                                            field_name: label.clone(),
 | 
				
			||||||
                                        {
 | 
					                                        }) {
 | 
				
			||||||
                                            let var_name = match pattern {
 | 
					                                            let var_name = match pattern {
 | 
				
			||||||
                                                Pattern::Var { name, .. } => name,
 | 
					                                                Pattern::Var { name, .. } => name,
 | 
				
			||||||
                                                _ => todo!(),
 | 
					                                                _ => todo!(),
 | 
				
			||||||
| 
						 | 
					@ -1384,7 +1486,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TypedExpr::RecordAccess { label, record, .. } => {
 | 
					            TypedExpr::RecordAccess { label, record, .. } => {
 | 
				
			||||||
                let mut is_var = false;
 | 
					                let mut is_var = false;
 | 
				
			||||||
                let mut current_var_name = "".to_string();
 | 
					                let mut current_var_name = String::new();
 | 
				
			||||||
                let mut current_record = *record.clone();
 | 
					                let mut current_record = *record.clone();
 | 
				
			||||||
                while !is_var {
 | 
					                while !is_var {
 | 
				
			||||||
                    match current_record.clone() {
 | 
					                    match current_record.clone() {
 | 
				
			||||||
| 
						 | 
					@ -1442,15 +1544,15 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
        let mut term = current_term;
 | 
					        let mut term = current_term;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // attempt to insert function definitions where needed
 | 
					        // attempt to insert function definitions where needed
 | 
				
			||||||
        for func in self.uplc_function_holder_lookup.clone().keys() {
 | 
					        for func_key in self.uplc_function_holder_lookup.clone().keys() {
 | 
				
			||||||
            if scope_level.is_less_than(
 | 
					            if scope_level.is_less_than(
 | 
				
			||||||
                self.uplc_function_holder_lookup.clone().get(func).unwrap(),
 | 
					                self.uplc_function_holder_lookup
 | 
				
			||||||
 | 
					                    .clone()
 | 
				
			||||||
 | 
					                    .get(func_key)
 | 
				
			||||||
 | 
					                    .unwrap(),
 | 
				
			||||||
                false,
 | 
					                false,
 | 
				
			||||||
            ) {
 | 
					            ) {
 | 
				
			||||||
                let func_def = self
 | 
					                let func_def = self.functions.get(func_key).unwrap();
 | 
				
			||||||
                    .functions
 | 
					 | 
				
			||||||
                    .get(&(func.0.to_string(), func.1.to_string()))
 | 
					 | 
				
			||||||
                    .unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut function_body = self.recurse_code_gen(
 | 
					                let mut function_body = self.recurse_code_gen(
 | 
				
			||||||
                    &func_def.body,
 | 
					                    &func_def.body,
 | 
				
			||||||
| 
						 | 
					@ -1470,7 +1572,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                term = Term::Apply {
 | 
					                term = Term::Apply {
 | 
				
			||||||
                    function: Term::Lambda {
 | 
					                    function: Term::Lambda {
 | 
				
			||||||
                        parameter_name: Name {
 | 
					                        parameter_name: Name {
 | 
				
			||||||
                            text: format!("{}_{}", func.0, func.1),
 | 
					                            text: format!("{}_{}", func_key.module_name, func_key.function_name),
 | 
				
			||||||
                            unique: 0.into(),
 | 
					                            unique: 0.into(),
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        body: term.into(),
 | 
					                        body: term.into(),
 | 
				
			||||||
| 
						 | 
					@ -1478,7 +1580,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    .into(),
 | 
					                    .into(),
 | 
				
			||||||
                    argument: function_body.into(),
 | 
					                    argument: function_body.into(),
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                self.uplc_function_holder_lookup.shift_remove(func);
 | 
					                self.uplc_function_holder_lookup.shift_remove(func_key);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1577,7 +1679,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    .into(),
 | 
					                    .into(),
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                let module = &key.0;
 | 
					                let module = &key.module_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                term = Term::Apply {
 | 
					                term = Term::Apply {
 | 
				
			||||||
                    function: Term::Lambda {
 | 
					                    function: Term::Lambda {
 | 
				
			||||||
| 
						 | 
					@ -1594,28 +1696,37 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Pull out all uplc data holder and data usage, filter by Scope Level, Sort By Scope Depth, Then Apply
 | 
					        // Pull out all uplc data holder fields and data usage, filter by Scope Level, Sort By Scope Depth, Then Apply
 | 
				
			||||||
        #[allow(clippy::type_complexity)]
 | 
					        let mut data_holder: Vec<ConstrConversionInfo> = self
 | 
				
			||||||
        let mut data_holder: Vec<((String, String, String), (ScopeLevels, i128, String))> = self
 | 
					 | 
				
			||||||
            .uplc_data_usage_holder_lookup
 | 
					            .uplc_data_usage_holder_lookup
 | 
				
			||||||
            .iter()
 | 
					            .clone()
 | 
				
			||||||
            .filter(|record_scope| scope_level.is_less_than(record_scope.1, false))
 | 
					            .into_iter()
 | 
				
			||||||
            .map(|((module, name), scope)| {
 | 
					            .filter(|record_scope| scope_level.is_less_than(&record_scope.1, false))
 | 
				
			||||||
                (
 | 
					            .map(|(var_name, scope)| ConstrConversionInfo {
 | 
				
			||||||
                    (module.to_string(), name.to_string(), "".to_string()),
 | 
					                local_var: var_name,
 | 
				
			||||||
                    (scope.clone(), -1, "".to_string()),
 | 
					                field: None,
 | 
				
			||||||
                )
 | 
					                scope,
 | 
				
			||||||
 | 
					                index: None,
 | 
				
			||||||
 | 
					                returning_type: String::new(),
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            .collect();
 | 
					            .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data_holder.extend(
 | 
					        data_holder.extend(
 | 
				
			||||||
            self.uplc_data_holder_lookup
 | 
					            self.uplc_data_holder_lookup
 | 
				
			||||||
                .iter()
 | 
					                .clone()
 | 
				
			||||||
                .filter(|record_scope| scope_level.is_less_than(&record_scope.1 .0, false))
 | 
					                .into_iter()
 | 
				
			||||||
                .map(|((module, name, label), (scope, expr))| {
 | 
					                .filter(|record_scope| scope_level.is_less_than(&record_scope.1.scope, false))
 | 
				
			||||||
 | 
					                .map(
 | 
				
			||||||
 | 
					                    |(
 | 
				
			||||||
 | 
					                        ConstrFieldKey {
 | 
				
			||||||
 | 
					                            local_var,
 | 
				
			||||||
 | 
					                            field_name,
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        ScopedExpr { scope, expr },
 | 
				
			||||||
 | 
					                    )| {
 | 
				
			||||||
                        let index_type = match expr {
 | 
					                        let index_type = match expr {
 | 
				
			||||||
                            TypedExpr::RecordAccess { index, tipo, .. } => {
 | 
					                            TypedExpr::RecordAccess { index, tipo, .. } => {
 | 
				
			||||||
                            let tipo = &**tipo;
 | 
					                                let tipo = &*tipo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                let name = match tipo {
 | 
					                                let name = match tipo {
 | 
				
			||||||
                                    Type::App { name, .. } => name,
 | 
					                                    Type::App { name, .. } => name,
 | 
				
			||||||
| 
						 | 
					@ -1624,9 +1735,9 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                                };
 | 
					                                };
 | 
				
			||||||
                                (index, name.clone())
 | 
					                                (index, name.clone())
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        TypedExpr::Assignment { value, .. } => match &**value {
 | 
					                            TypedExpr::Assignment { value, .. } => match *value {
 | 
				
			||||||
                                TypedExpr::RecordAccess { index, tipo, .. } => {
 | 
					                                TypedExpr::RecordAccess { index, tipo, .. } => {
 | 
				
			||||||
                                let tipo = &**tipo;
 | 
					                                    let tipo = &*tipo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                    let name = match tipo {
 | 
					                                    let name = match tipo {
 | 
				
			||||||
                                        Type::App { name, .. } => name,
 | 
					                                        Type::App { name, .. } => name,
 | 
				
			||||||
| 
						 | 
					@ -1640,57 +1751,40 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                            _ => todo!(),
 | 
					                            _ => todo!(),
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    (
 | 
					                        ConstrConversionInfo {
 | 
				
			||||||
                        (module.to_string(), name.to_string(), label.to_string()),
 | 
					                            local_var,
 | 
				
			||||||
                        (scope.clone(), *index_type.0 as i128, index_type.1),
 | 
					                            field: Some(field_name),
 | 
				
			||||||
 | 
					                            scope,
 | 
				
			||||||
 | 
					                            index: Some(index_type.0),
 | 
				
			||||||
 | 
					                            returning_type: index_type.1,
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                })
 | 
					                .collect::<Vec<ConstrConversionInfo>>(),
 | 
				
			||||||
                .collect::<Vec<((String, String, String), (ScopeLevels, i128, String))>>(),
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        data_holder.sort_by(|item1, item2| {
 | 
					        data_holder.sort_by(|item1, item2| {
 | 
				
			||||||
            if item1.1 .0.is_less_than(&item2.1 .0, true) {
 | 
					            if item1.scope.is_less_than(&item2.scope, true) {
 | 
				
			||||||
                Ordering::Less
 | 
					                Ordering::Less
 | 
				
			||||||
            } else if item2.1 .0.is_less_than(&item1.1 .0, true) {
 | 
					            } else if item2.scope.is_less_than(&item1.scope, true) {
 | 
				
			||||||
                Ordering::Greater
 | 
					                Ordering::Greater
 | 
				
			||||||
            } else if item1.1 .1 < item2.1 .1 {
 | 
					            } else if item1.index < item2.index {
 | 
				
			||||||
                Ordering::Less
 | 
					                Ordering::Less
 | 
				
			||||||
            } else if item2.1 .1 < item1.1 .1 {
 | 
					            } else if item2.index < item1.index {
 | 
				
			||||||
                Ordering::Greater
 | 
					                Ordering::Greater
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                Ordering::Equal
 | 
					                Ordering::Equal
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (key @ (module, name, label), (_, index, tipo)) in data_holder.iter().rev() {
 | 
					        for ConstrConversionInfo {
 | 
				
			||||||
            if index < &0 {
 | 
					            local_var,
 | 
				
			||||||
                term = Term::Apply {
 | 
					            field,
 | 
				
			||||||
                    function: Term::Lambda {
 | 
					            index,
 | 
				
			||||||
                        parameter_name: Name {
 | 
					            returning_type,
 | 
				
			||||||
                            text: format!("{name}_fields"),
 | 
					            ..
 | 
				
			||||||
                            unique: 0.into(),
 | 
					        } in data_holder.into_iter().rev()
 | 
				
			||||||
                        },
 | 
					        {
 | 
				
			||||||
                        body: term.into(),
 | 
					            if let (Some(index), Some(field)) = (index, field) {
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    .into(),
 | 
					 | 
				
			||||||
                    // TODO: Find proper scope for this function if at all.
 | 
					 | 
				
			||||||
                    argument: Term::Apply {
 | 
					 | 
				
			||||||
                        function: Term::Var(Name {
 | 
					 | 
				
			||||||
                            text: "constr_fields_exposer".to_string(),
 | 
					 | 
				
			||||||
                            unique: 0.into(),
 | 
					 | 
				
			||||||
                        })
 | 
					 | 
				
			||||||
                        .into(),
 | 
					 | 
				
			||||||
                        argument: Term::Var(Name {
 | 
					 | 
				
			||||||
                            text: name.to_string(),
 | 
					 | 
				
			||||||
                            unique: 0.into(),
 | 
					 | 
				
			||||||
                        })
 | 
					 | 
				
			||||||
                        .into(),
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    .into(),
 | 
					 | 
				
			||||||
                };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                self.uplc_data_usage_holder_lookup
 | 
					 | 
				
			||||||
                    .shift_remove(&(module.clone(), name.clone()));
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                let var_term = Term::Apply {
 | 
					                let var_term = Term::Apply {
 | 
				
			||||||
                    function: Term::Apply {
 | 
					                    function: Term::Apply {
 | 
				
			||||||
                        function: Term::Var(Name {
 | 
					                        function: Term::Var(Name {
 | 
				
			||||||
| 
						 | 
					@ -1699,16 +1793,16 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                        })
 | 
					                        })
 | 
				
			||||||
                        .into(),
 | 
					                        .into(),
 | 
				
			||||||
                        argument: Term::Var(Name {
 | 
					                        argument: Term::Var(Name {
 | 
				
			||||||
                            text: format!("{name}_fields"),
 | 
					                            text: format!("{local_var}_fields"),
 | 
				
			||||||
                            unique: 0.into(),
 | 
					                            unique: 0.into(),
 | 
				
			||||||
                        })
 | 
					                        })
 | 
				
			||||||
                        .into(),
 | 
					                        .into(),
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    .into(),
 | 
					                    .into(),
 | 
				
			||||||
                    argument: Term::Constant(Constant::Integer(*index as i128)).into(),
 | 
					                    argument: Term::Constant(Constant::Integer(index as i128)).into(),
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let type_conversion = match tipo.as_str() {
 | 
					                let type_conversion = match returning_type.as_str() {
 | 
				
			||||||
                    "ByteArray" => Term::Apply {
 | 
					                    "ByteArray" => Term::Apply {
 | 
				
			||||||
                        function: Term::Builtin(DefaultFunction::UnBData).into(),
 | 
					                        function: Term::Builtin(DefaultFunction::UnBData).into(),
 | 
				
			||||||
                        argument: var_term.into(),
 | 
					                        argument: var_term.into(),
 | 
				
			||||||
| 
						 | 
					@ -1723,7 +1817,7 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                term = Term::Apply {
 | 
					                term = Term::Apply {
 | 
				
			||||||
                    function: Term::Lambda {
 | 
					                    function: Term::Lambda {
 | 
				
			||||||
                        parameter_name: Name {
 | 
					                        parameter_name: Name {
 | 
				
			||||||
                            text: format!("{name}_field_{label}"),
 | 
					                            text: format!("{local_var}_field_{field}"),
 | 
				
			||||||
                            unique: 0.into(),
 | 
					                            unique: 0.into(),
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        body: term.into(),
 | 
					                        body: term.into(),
 | 
				
			||||||
| 
						 | 
					@ -1731,7 +1825,37 @@ impl<'a> CodeGenerator<'a> {
 | 
				
			||||||
                    .into(),
 | 
					                    .into(),
 | 
				
			||||||
                    argument: type_conversion.into(),
 | 
					                    argument: type_conversion.into(),
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                self.uplc_data_holder_lookup.shift_remove(key);
 | 
					                self.uplc_data_holder_lookup.shift_remove(&ConstrFieldKey {
 | 
				
			||||||
 | 
					                    local_var,
 | 
				
			||||||
 | 
					                    field_name: field,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                term = Term::Apply {
 | 
				
			||||||
 | 
					                    function: Term::Lambda {
 | 
				
			||||||
 | 
					                        parameter_name: Name {
 | 
				
			||||||
 | 
					                            text: format!("{local_var}_fields"),
 | 
				
			||||||
 | 
					                            unique: 0.into(),
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        body: term.into(),
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    .into(),
 | 
				
			||||||
 | 
					                    // TODO: Find proper scope for this function if at all.
 | 
				
			||||||
 | 
					                    argument: Term::Apply {
 | 
				
			||||||
 | 
					                        function: Term::Var(Name {
 | 
				
			||||||
 | 
					                            text: "constr_fields_exposer".to_string(),
 | 
				
			||||||
 | 
					                            unique: 0.into(),
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                        .into(),
 | 
				
			||||||
 | 
					                        argument: Term::Var(Name {
 | 
				
			||||||
 | 
					                            text: local_var.to_string(),
 | 
				
			||||||
 | 
					                            unique: 0.into(),
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                        .into(),
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    .into(),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                self.uplc_data_usage_holder_lookup.shift_remove(&local_var);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ use aiken_lang::{
 | 
				
			||||||
    ast::{Definition, Function, ModuleKind, TypedFunction},
 | 
					    ast::{Definition, Function, ModuleKind, TypedFunction},
 | 
				
			||||||
    builtins,
 | 
					    builtins,
 | 
				
			||||||
    tipo::TypeInfo,
 | 
					    tipo::TypeInfo,
 | 
				
			||||||
    uplc::CodeGenerator,
 | 
					    uplc::{CodeGenerator, DataTypeKey, FunctionAccessKey},
 | 
				
			||||||
    IdGenerator,
 | 
					    IdGenerator,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use pallas::{
 | 
					use pallas::{
 | 
				
			||||||
| 
						 | 
					@ -312,13 +312,25 @@ impl Project {
 | 
				
			||||||
            for def in module.ast.definitions() {
 | 
					            for def in module.ast.definitions() {
 | 
				
			||||||
                match def {
 | 
					                match def {
 | 
				
			||||||
                    Definition::Fn(func) => {
 | 
					                    Definition::Fn(func) => {
 | 
				
			||||||
                        functions.insert((module.name.clone(), func.name.clone()), func);
 | 
					                        functions.insert(
 | 
				
			||||||
 | 
					                            FunctionAccessKey {
 | 
				
			||||||
 | 
					                                module_name: module.name.clone(),
 | 
				
			||||||
 | 
					                                function_name: func.name.clone(),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            func,
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Definition::TypeAlias(ta) => {
 | 
					                    Definition::TypeAlias(ta) => {
 | 
				
			||||||
                        type_aliases.insert((module.name.clone(), ta.alias.clone()), ta);
 | 
					                        type_aliases.insert((module.name.clone(), ta.alias.clone()), ta);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Definition::DataType(dt) => {
 | 
					                    Definition::DataType(dt) => {
 | 
				
			||||||
                        data_types.insert((module.name.clone(), dt.name.clone()), dt);
 | 
					                        data_types.insert(
 | 
				
			||||||
 | 
					                            DataTypeKey {
 | 
				
			||||||
 | 
					                                module_name: module.name.clone(),
 | 
				
			||||||
 | 
					                                defined_type: dt.name.clone(),
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            dt,
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Definition::Use(import) => {
 | 
					                    Definition::Use(import) => {
 | 
				
			||||||
                        imports.insert((module.name.clone(), import.module.join("/")), import);
 | 
					                        imports.insert((module.name.clone(), import.module.join("/")), import);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue