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:
Kasey White 2023-01-09 01:44:51 -05:00 committed by Lucas
parent 2b26d9a0c1
commit 1721c3945b
6 changed files with 88 additions and 123 deletions

View File

@ -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, .. }

View File

@ -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!(),

View File

@ -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,
}
}
} }

View File

@ -0,0 +1,5 @@
# This file was generated by Aiken
# You typically do not need to edit this file
requirements = []
packages = []

View File

@ -0,0 +1,2 @@
name = "aiken-lang/acceptance_test_039"
version = "0.0.0"

View File

@ -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 == #[]
}