feat: add tuples and streamline conversion of types to and from data

This commit is contained in:
Kasey White 2022-12-07 04:35:41 -05:00 committed by Lucas
parent d8ff574045
commit 2f7131e9b8
7 changed files with 643 additions and 325 deletions

View File

@ -45,20 +45,16 @@ pub enum Air {
tail: bool, tail: bool,
}, },
Tail {
scope: Vec<u64>,
name: String,
prev_tail_name: String,
},
ListAccessor { ListAccessor {
scope: Vec<u64>, scope: Vec<u64>,
tipo: Arc<Type>,
names: Vec<String>, names: Vec<String>,
tail: bool, tail: bool,
}, },
ListExpose { ListExpose {
scope: Vec<u64>, scope: Vec<u64>,
tipo: Arc<Type>,
tail_head_names: Vec<(String, String)>, tail_head_names: Vec<(String, String)>,
tail: Option<(String, String)>, tail: Option<(String, String)>,
}, },
@ -120,13 +116,6 @@ pub enum Air {
name: String, name: String,
}, },
// Try {
// scope: Vec<u64>,
// tipo: Arc<Type>,
// value: Box<Self>,
// then: Box<Self>,
// pattern: Pattern<PatternConstructor, Arc<Type>>,
// },
When { When {
scope: Vec<u64>, scope: Vec<u64>,
tipo: Arc<Type>, tipo: Arc<Type>,
@ -196,13 +185,11 @@ pub enum Air {
// module_alias: String, // module_alias: String,
// constructor: ModuleValueConstructor, // constructor: ModuleValueConstructor,
// }, // },
Tuple {
// Tuple { scope: Vec<u64>,
// scope: Vec<u64>, tipo: Arc<Type>,
// count: usize,
// tipo: Arc<Type>, },
// elems: Vec<Self>,
// },
// TupleIndex { // TupleIndex {
// scope: Vec<u64>, // scope: Vec<u64>,
@ -242,7 +229,6 @@ impl Air {
| Air::ByteArray { scope, .. } | Air::ByteArray { scope, .. }
| Air::Var { scope, .. } | Air::Var { scope, .. }
| Air::List { scope, .. } | Air::List { scope, .. }
| Air::Tail { scope, .. }
| Air::ListAccessor { scope, .. } | Air::ListAccessor { scope, .. }
| Air::ListExpose { scope, .. } | Air::ListExpose { scope, .. }
| Air::Call { scope, .. } | Air::Call { scope, .. }
@ -265,6 +251,7 @@ impl Air {
| Air::Fields { scope, .. } | Air::Fields { scope, .. }
| Air::RecordAccess { scope, .. } | Air::RecordAccess { scope, .. }
| Air::FieldsExpose { scope, .. } | Air::FieldsExpose { scope, .. }
| Air::Tuple { scope, .. }
| Air::Todo { scope, .. } | Air::Todo { scope, .. }
| Air::Record { scope, .. } | Air::Record { scope, .. }
| Air::RecordUpdate { scope, .. } | Air::RecordUpdate { scope, .. }

View File

@ -135,6 +135,43 @@ impl Type {
} }
} }
pub fn is_map(&self) -> bool {
match self {
Self::App {
module, name, args, ..
} if "List" == name && module.is_empty() => {
if let Type::Tuple { elems } = &*args[0] {
elems.len() == 2
} else {
false
}
}
Self::Var { tipo } => tipo.borrow().is_map(),
_ => false,
}
}
pub fn is_tuple(&self) -> bool {
matches!(self, Self::Tuple { .. })
}
pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
if self.is_list() {
match self {
Self::App { args, .. } => args.clone(),
Self::Var { tipo } => tipo.borrow().get_inner_type(),
_ => vec![],
}
} else if self.is_tuple() {
match self {
Self::Tuple { elems } => elems.to_vec(),
_ => vec![],
}
} else {
vec![]
}
}
pub fn get_uplc_type(&self) -> UplcType { pub fn get_uplc_type(&self) -> UplcType {
if self.is_int() { if self.is_int() {
UplcType::Integer UplcType::Integer
@ -144,21 +181,21 @@ impl Type {
UplcType::String UplcType::String
} else if self.is_bool() { } else if self.is_bool() {
UplcType::Bool UplcType::Bool
} else if self.is_map() {
UplcType::List(UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()).into())
} else if self.is_list() { } else if self.is_list() {
let args_type = match self { UplcType::List(UplcType::Data.into())
Self::App { } else if self.is_tuple() {
module, name, args, .. match self {
} if "List" == name && module.is_empty() => args[0].clone(), Self::Tuple { elems } => {
Self::Var { tipo } => { if elems.len() == 2 {
if let TypeVar::Link { tipo } = tipo.borrow().clone() { UplcType::Pair(UplcType::Data.into(), UplcType::Data.into())
tipo
} else { } else {
todo!() UplcType::List(UplcType::Data.into())
} }
} }
_ => todo!(), _ => todo!(),
}; }
UplcType::List(Box::new(args_type.get_uplc_type()))
} else { } else {
UplcType::Data UplcType::Data
} }
@ -334,6 +371,20 @@ impl TypeVar {
_ => false, _ => false,
} }
} }
pub fn is_map(&self) -> bool {
match self {
Self::Link { tipo } => tipo.is_map(),
_ => false,
}
}
pub fn get_inner_type(&self) -> Vec<Arc<Type>> {
match self {
Self::Link { tipo } => tipo.get_inner_type(),
_ => vec![],
}
}
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ use crate::{
pub mod cost_model; pub mod cost_model;
mod error; mod error;
mod runtime; pub mod runtime;
use cost_model::{ExBudget, StepKind}; use cost_model::{ExBudget, StepKind};
pub use error::Error; pub use error::Error;

View File

@ -853,7 +853,7 @@ impl DefaultFunction {
} }
} }
fn convert_tag_to_constr(tag: i128) -> i128 { pub fn convert_tag_to_constr(tag: i128) -> i128 {
if tag < 128 { if tag < 128 {
tag - 121 tag - 121
} else if (1280..1401).contains(&tag) { } else if (1280..1401).contains(&tag) {
@ -863,7 +863,7 @@ fn convert_tag_to_constr(tag: i128) -> i128 {
} }
} }
fn convert_constr_to_tag(constr: u64) -> u64 { pub fn convert_constr_to_tag(constr: u64) -> u64 {
if constr < 7 { if constr < 7 {
constr + 121 constr + 121
} else if constr < 128 { } else if constr < 128 {

View File

@ -18,29 +18,44 @@
(lam (lam
__constr_get_field __constr_get_field
[ [
[ (lam
x
[ [
(force (builtin ifThenElse))
[ [
(builtin equalsByteString)
[ [
(builtin equalsByteString) (builtin unBData)
[ [
(builtin unBData)
[ [
[ __constr_get_field
__constr_get_field [ __constr_fields_exposer datum ]
[ __constr_fields_exposer datum ]
]
(con integer 0)
] ]
(con integer 0)
] ]
] ]
(con bytestring #0102) ]
[
(builtin unBData)
[
[
__constr_get_field
[ __constr_fields_exposer rdmr ]
]
(con integer 0)
]
] ]
] ]
(con bool False) )
[
[
(builtin mkCons)
[ (builtin bData) (con bytestring #f4) ]
]
[
[ (builtin mkCons) rdmr ]
[ [ (builtin mkCons) datum ] (con listdata []) ]
]
] ]
(con bool True)
] ]
) )
(lam (lam

View File

@ -1,5 +1,7 @@
use sample use sample
pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool { pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool {
let x = #(datum, rdmr, #[244])
datum.random == rdmr.signer datum.random == rdmr.signer
} }