Refactors:
Add test 40 refactor how we get data type from type Call contains type now to handle certain record cases
This commit is contained in:
parent
2b26d9a0c1
commit
1721c3945b
|
@ -3,7 +3,7 @@ use std::{collections::HashSet, sync::Arc};
|
||||||
use uplc::builtins::DefaultFunction;
|
use uplc::builtins::DefaultFunction;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AssignmentKind, BinOp, UnOp},
|
ast::{BinOp, UnOp},
|
||||||
tipo::{Type, ValueConstructor},
|
tipo::{Type, ValueConstructor},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ pub enum Air {
|
||||||
Call {
|
Call {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
count: usize,
|
count: usize,
|
||||||
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Builtin {
|
Builtin {
|
||||||
|
@ -77,7 +78,10 @@ pub enum Air {
|
||||||
Assignment {
|
Assignment {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
name: String,
|
name: String,
|
||||||
kind: AssignmentKind,
|
},
|
||||||
|
|
||||||
|
Assert {
|
||||||
|
scope: Vec<u64>,
|
||||||
},
|
},
|
||||||
|
|
||||||
DefineFunc {
|
DefineFunc {
|
||||||
|
@ -89,27 +93,6 @@ pub enum Air {
|
||||||
variant_name: String,
|
variant_name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
DefineConst {
|
|
||||||
scope: Vec<u64>,
|
|
||||||
func_name: String,
|
|
||||||
module_name: String,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
|
|
||||||
DefineConstrFields {
|
|
||||||
scope: Vec<u64>,
|
|
||||||
func_name: String,
|
|
||||||
module_name: String,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
|
|
||||||
DefineConstrFieldAccess {
|
|
||||||
scope: Vec<u64>,
|
|
||||||
func_name: String,
|
|
||||||
module_name: String,
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
|
|
||||||
Lam {
|
Lam {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -224,10 +207,6 @@ pub enum Air {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Record {
|
|
||||||
scope: Vec<u64>,
|
|
||||||
},
|
|
||||||
|
|
||||||
RecordUpdate {
|
RecordUpdate {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
highest_index: usize,
|
highest_index: usize,
|
||||||
|
@ -261,10 +240,8 @@ impl Air {
|
||||||
| Air::Builtin { scope, .. }
|
| Air::Builtin { scope, .. }
|
||||||
| Air::BinOp { scope, .. }
|
| Air::BinOp { scope, .. }
|
||||||
| Air::Assignment { scope, .. }
|
| Air::Assignment { scope, .. }
|
||||||
|
| Air::Assert { scope }
|
||||||
| Air::DefineFunc { scope, .. }
|
| Air::DefineFunc { scope, .. }
|
||||||
| Air::DefineConst { scope, .. }
|
|
||||||
| Air::DefineConstrFields { scope, .. }
|
|
||||||
| Air::DefineConstrFieldAccess { scope, .. }
|
|
||||||
| Air::Lam { scope, .. }
|
| Air::Lam { scope, .. }
|
||||||
| Air::When { scope, .. }
|
| Air::When { scope, .. }
|
||||||
| Air::Clause { scope, .. }
|
| Air::Clause { scope, .. }
|
||||||
|
@ -281,7 +258,6 @@ impl Air {
|
||||||
| Air::Tuple { scope, .. }
|
| Air::Tuple { scope, .. }
|
||||||
| Air::Todo { scope, .. }
|
| Air::Todo { scope, .. }
|
||||||
| Air::ErrorTerm { scope, .. }
|
| Air::ErrorTerm { scope, .. }
|
||||||
| Air::Record { scope, .. }
|
|
||||||
| Air::RecordUpdate { scope, .. }
|
| Air::RecordUpdate { scope, .. }
|
||||||
| Air::UnOp { scope, .. }
|
| Air::UnOp { scope, .. }
|
||||||
| Air::Trace { scope, .. }
|
| Air::Trace { scope, .. }
|
||||||
|
|
|
@ -1123,6 +1123,15 @@ pub fn monomorphize(
|
||||||
}
|
}
|
||||||
// TODO check on assignment if type is needed
|
// TODO check on assignment if type is needed
|
||||||
Air::Assignment { .. } => {}
|
Air::Assignment { .. } => {}
|
||||||
|
Air::Call { scope, count, tipo } => {
|
||||||
|
if tipo.is_generic() {
|
||||||
|
let mut tipo = tipo.clone();
|
||||||
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
|
new_air[index] = Air::Call { scope, count, tipo };
|
||||||
|
needs_variant = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Air::When {
|
Air::When {
|
||||||
scope,
|
scope,
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -1445,10 +1454,11 @@ pub fn handle_recursion_ir(
|
||||||
let current_call = recursion_ir[index - 1].clone();
|
let current_call = recursion_ir[index - 1].clone();
|
||||||
|
|
||||||
match current_call {
|
match current_call {
|
||||||
Air::Call { scope, count } => {
|
Air::Call { scope, count, tipo } => {
|
||||||
recursion_ir[index - 1] = Air::Call {
|
recursion_ir[index - 1] = Air::Call {
|
||||||
scope,
|
scope,
|
||||||
count: count + 1,
|
count: count + 1,
|
||||||
|
tipo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
ops::Deref,
|
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
vec,
|
vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::tipo::TypeVar;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
|
@ -23,7 +23,7 @@ use uplc::{
|
||||||
use crate::{
|
use crate::{
|
||||||
air::Air,
|
air::Air,
|
||||||
ast::{
|
ast::{
|
||||||
ArgName, AssignmentKind, BinOp, Clause, Pattern, Span, TypedArg, TypedDataType,
|
ArgName, AssignmentKind, BinOp, Clause, DataType, Pattern, Span, TypedArg, TypedDataType,
|
||||||
TypedFunction, UnOp,
|
TypedFunction, UnOp,
|
||||||
},
|
},
|
||||||
builder::{
|
builder::{
|
||||||
|
@ -207,10 +207,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
self.build_ir(tail, ir_stack, scope);
|
self.build_ir(tail, ir_stack, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedExpr::Call { fun, args, .. } => {
|
TypedExpr::Call {
|
||||||
|
fun, args, tipo, ..
|
||||||
|
} => {
|
||||||
ir_stack.push(Air::Call {
|
ir_stack.push(Air::Call {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
count: args.len(),
|
count: args.len(),
|
||||||
|
tipo: tipo.clone(),
|
||||||
});
|
});
|
||||||
let mut scope_fun = scope.clone();
|
let mut scope_fun = scope.clone();
|
||||||
scope_fun.push(self.id_gen.next());
|
scope_fun.push(self.id_gen.next());
|
||||||
|
@ -811,22 +814,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find data type definition
|
// find data type definition
|
||||||
let data_type_key = match tipo {
|
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
||||||
Type::Fn { ret, .. } => match ret.as_ref() {
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
|
||||||
|
|
||||||
let (index, _) = data_type
|
let (index, _) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
|
@ -1002,22 +990,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type_key = match tipo.as_ref() {
|
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
||||||
Type::Fn { ret, .. } => match &**ret {
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
|
||||||
let (_, constructor_type) = data_type
|
let (_, constructor_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1027,9 +1001,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut nested_pattern = vec![];
|
let mut nested_pattern = vec![];
|
||||||
if *is_record {
|
if *is_record {
|
||||||
let field_map = match constructor {
|
let field_map = match constructor {
|
||||||
tipo::PatternConstructor::Record { field_map, .. } => {
|
PatternConstructor::Record { field_map, .. } => field_map.clone().unwrap(),
|
||||||
field_map.clone().unwrap()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut type_map: HashMap<String, Arc<Type>> = HashMap::new();
|
let mut type_map: HashMap<String, Arc<Type>> = HashMap::new();
|
||||||
|
@ -1336,22 +1308,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} => {
|
} => {
|
||||||
let id = self.id_gen.next();
|
let id = self.id_gen.next();
|
||||||
let constr_var_name = format!("{constr_name}_{id}");
|
let constr_var_name = format!("{constr_name}_{id}");
|
||||||
let data_type_key = match tipo.as_ref() {
|
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
||||||
Type::Fn { ret, .. } => match &**ret {
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
|
||||||
|
|
||||||
if data_type.constructors.len() > 1 {
|
if data_type.constructors.len() > 1 {
|
||||||
pattern_vec.push(Air::ClauseGuard {
|
pattern_vec.push(Air::ClauseGuard {
|
||||||
|
@ -1441,7 +1398,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
pattern_vec.push(Air::Assignment {
|
pattern_vec.push(Air::Assignment {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
kind,
|
|
||||||
scope,
|
scope,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1549,22 +1505,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type_key = match tipo.as_ref() {
|
let data_type = self.lookup_data_type_by_tipo(tipo).unwrap();
|
||||||
Type::Fn { ret, .. } => match &**ret {
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.clone(),
|
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
|
||||||
let (_, constructor_type) = data_type
|
let (_, constructor_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -2299,29 +2240,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arity,
|
arity,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type_key = match &*constructor.tipo {
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.to_string(),
|
|
||||||
defined_type: name.to_string(),
|
|
||||||
},
|
|
||||||
Type::Fn { ret, .. } => match ret.deref() {
|
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
|
||||||
module_name: module.to_string(),
|
|
||||||
defined_type: name.to_string(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
Type::Var { .. } => todo!(),
|
|
||||||
Type::Tuple { .. } => todo!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if constructor.tipo.is_bool() {
|
if constructor.tipo.is_bool() {
|
||||||
arg_stack
|
arg_stack
|
||||||
.push(Term::Constant(UplcConstant::Bool(constr_name == "True")));
|
.push(Term::Constant(UplcConstant::Bool(constr_name == "True")));
|
||||||
} else if constructor.tipo.is_void() {
|
} else if constructor.tipo.is_void() {
|
||||||
arg_stack.push(Term::Constant(UplcConstant::Unit));
|
arg_stack.push(Term::Constant(UplcConstant::Unit));
|
||||||
} else {
|
} else {
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
let data_type =
|
||||||
|
self.lookup_data_type_by_tipo(&constructor.tipo).unwrap();
|
||||||
|
|
||||||
let (constr_index, _) = data_type
|
let (constr_index, _) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
|
@ -3033,6 +2959,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
Air::Assert { .. } => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
Air::DefineFunc {
|
Air::DefineFunc {
|
||||||
func_name,
|
func_name,
|
||||||
params,
|
params,
|
||||||
|
@ -3115,9 +3044,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::DefineConst { .. } => todo!(),
|
|
||||||
Air::DefineConstrFields { .. } => todo!(),
|
|
||||||
Air::DefineConstrFieldAccess { .. } => todo!(),
|
|
||||||
Air::Lam { name, .. } => {
|
Air::Lam { name, .. } => {
|
||||||
let arg = arg_stack.pop().unwrap();
|
let arg = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
@ -3708,7 +3634,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
Air::Record { .. } => todo!(),
|
|
||||||
Air::RecordUpdate {
|
Air::RecordUpdate {
|
||||||
highest_index,
|
highest_index,
|
||||||
indices,
|
indices,
|
||||||
|
@ -4177,4 +4102,35 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lookup_data_type_by_tipo(&self, tipo: &Type) -> Option<&&DataType<Arc<Type>>> {
|
||||||
|
match tipo {
|
||||||
|
Type::Fn { ret, .. } => match ret.as_ref() {
|
||||||
|
Type::App { module, name, .. } => {
|
||||||
|
let data_type_key = DataTypeKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
defined_type: name.clone(),
|
||||||
|
};
|
||||||
|
self.data_types.get(&data_type_key)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
Type::App { module, name, .. } => {
|
||||||
|
let data_type_key = DataTypeKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
defined_type: name.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.data_types.get(&data_type_key)
|
||||||
|
}
|
||||||
|
Type::Var { tipo } => {
|
||||||
|
if let TypeVar::Link { tipo } = &*tipo.borrow() {
|
||||||
|
self.lookup_data_type_by_tipo(tipo)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file was generated by Aiken
|
||||||
|
# You typically do not need to edit this file
|
||||||
|
|
||||||
|
requirements = []
|
||||||
|
packages = []
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = "aiken-lang/acceptance_test_039"
|
||||||
|
version = "0.0.0"
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub type Car{
|
||||||
|
Honda { remote_connect: ByteArray, owner: ByteArray, wheels: Int}
|
||||||
|
Ford { remote_connect: ByteArray, owner: ByteArray, wheels: Int, truck_bed_limit: Int }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test update_owner1(){
|
||||||
|
let initial_car: Data = Ford{remote_connect: #[], owner: #[], wheels: 4, truck_bed_limit: 10000}
|
||||||
|
assert Ford{ owner, ..} = initial_car
|
||||||
|
owner == #[]
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue