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 {
scope: Vec<u64>,
name: String,
prev_tail_name: String,
},
ListAccessor {
scope: Vec<u64>,
tipo: Arc<Type>,
names: Vec<String>,
tail: bool,
},
ListExpose {
scope: Vec<u64>,
tipo: Arc<Type>,
tail_head_names: Vec<(String, String)>,
tail: Option<(String, String)>,
},
@ -120,13 +116,6 @@ pub enum Air {
name: String,
},
// Try {
// scope: Vec<u64>,
// tipo: Arc<Type>,
// value: Box<Self>,
// then: Box<Self>,
// pattern: Pattern<PatternConstructor, Arc<Type>>,
// },
When {
scope: Vec<u64>,
tipo: Arc<Type>,
@ -196,13 +185,11 @@ pub enum Air {
// module_alias: String,
// constructor: ModuleValueConstructor,
// },
// Tuple {
// scope: Vec<u64>,
//
// tipo: Arc<Type>,
// elems: Vec<Self>,
// },
Tuple {
scope: Vec<u64>,
tipo: Arc<Type>,
count: usize,
},
// TupleIndex {
// scope: Vec<u64>,
@ -242,7 +229,6 @@ impl Air {
| Air::ByteArray { scope, .. }
| Air::Var { scope, .. }
| Air::List { scope, .. }
| Air::Tail { scope, .. }
| Air::ListAccessor { scope, .. }
| Air::ListExpose { scope, .. }
| Air::Call { scope, .. }
@ -265,6 +251,7 @@ impl Air {
| Air::Fields { scope, .. }
| Air::RecordAccess { scope, .. }
| Air::FieldsExpose { scope, .. }
| Air::Tuple { scope, .. }
| Air::Todo { scope, .. }
| Air::Record { 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 {
if self.is_int() {
UplcType::Integer
@ -144,21 +181,21 @@ impl Type {
UplcType::String
} else if self.is_bool() {
UplcType::Bool
} else if self.is_map() {
UplcType::List(UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()).into())
} else if self.is_list() {
let args_type = match self {
Self::App {
module, name, args, ..
} if "List" == name && module.is_empty() => args[0].clone(),
Self::Var { tipo } => {
if let TypeVar::Link { tipo } = tipo.borrow().clone() {
tipo
UplcType::List(UplcType::Data.into())
} else if self.is_tuple() {
match self {
Self::Tuple { elems } => {
if elems.len() == 2 {
UplcType::Pair(UplcType::Data.into(), UplcType::Data.into())
} else {
todo!()
UplcType::List(UplcType::Data.into())
}
}
_ => todo!(),
};
UplcType::List(Box::new(args_type.get_uplc_type()))
}
} else {
UplcType::Data
}
@ -334,6 +371,20 @@ impl TypeVar {
_ => 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)]

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ use crate::{
pub mod cost_model;
mod error;
mod runtime;
pub mod runtime;
use cost_model::{ExBudget, StepKind};
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 {
tag - 121
} 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 {
constr + 121
} else if constr < 128 {

View File

@ -18,29 +18,44 @@
(lam
__constr_get_field
[
[
(lam
x
[
(force (builtin ifThenElse))
[
(builtin equalsByteString)
[
(builtin equalsByteString)
(builtin unBData)
[
(builtin unBData)
[
[
__constr_get_field
[ __constr_fields_exposer datum ]
]
(con integer 0)
__constr_get_field
[ __constr_fields_exposer datum ]
]
(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

View File

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