feat: add tuples and streamline conversion of types to and from data
This commit is contained in:
parent
d8ff574045
commit
2f7131e9b8
|
@ -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, .. }
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -8,7 +8,9 @@ use uplc::{
|
||||||
Constant as UplcConstant, Name, Program, Term, Type as UplcType,
|
Constant as UplcConstant, Name, Program, Term, Type as UplcType,
|
||||||
},
|
},
|
||||||
builtins::DefaultFunction,
|
builtins::DefaultFunction,
|
||||||
|
machine::runtime::convert_constr_to_tag,
|
||||||
parser::interner::Interner,
|
parser::interner::Interner,
|
||||||
|
BigInt, Constr, PlutusData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -525,7 +527,23 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
TypedExpr::RecordUpdate { .. } => todo!(),
|
TypedExpr::RecordUpdate { .. } => todo!(),
|
||||||
TypedExpr::Negate { .. } => todo!(),
|
TypedExpr::Negate { .. } => todo!(),
|
||||||
TypedExpr::Tuple { .. } => todo!(),
|
TypedExpr::Tuple { elems, tipo, .. } => {
|
||||||
|
ir_stack.push(Air::Tuple {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: tipo.clone(),
|
||||||
|
count: elems.len(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut elems_air = vec![];
|
||||||
|
|
||||||
|
for elem in elems {
|
||||||
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
self.build_ir(elem, &mut elems_air, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_stack.append(&mut elems_air);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +749,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec: &mut Vec<Air>,
|
pattern_vec: &mut Vec<Air>,
|
||||||
values: &mut Vec<Air>,
|
values: &mut Vec<Air>,
|
||||||
clause_properties: ClauseProperties,
|
clause_properties: ClauseProperties,
|
||||||
_tipo: &Type,
|
tipo: &Type,
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match pattern {
|
match pattern {
|
||||||
|
@ -821,12 +839,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
pattern_vec.push(Air::ListExpose {
|
pattern_vec.push(Air::ListExpose {
|
||||||
scope,
|
scope,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
tail_head_names,
|
tail_head_names,
|
||||||
tail: Some((tail_var, tail_name)),
|
tail: Some((tail_var, tail_name)),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
pattern_vec.push(Air::ListExpose {
|
pattern_vec.push(Air::ListExpose {
|
||||||
scope,
|
scope,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
tail_head_names,
|
tail_head_names,
|
||||||
tail: None,
|
tail: None,
|
||||||
});
|
});
|
||||||
|
@ -1066,13 +1086,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern: &Pattern<tipo::PatternConstructor, Arc<Type>>,
|
pattern: &Pattern<tipo::PatternConstructor, Arc<Type>>,
|
||||||
pattern_vec: &mut Vec<Air>,
|
pattern_vec: &mut Vec<Air>,
|
||||||
value_vec: &mut Vec<Air>,
|
value_vec: &mut Vec<Air>,
|
||||||
_tipo: &Type,
|
tipo: &Type,
|
||||||
kind: AssignmentKind,
|
kind: AssignmentKind,
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Int { .. } => todo!(),
|
Pattern::Int { .. } | Pattern::String { .. } => unreachable!(),
|
||||||
Pattern::String { .. } => todo!(),
|
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
pattern_vec.push(Air::Assignment {
|
pattern_vec.push(Air::Assignment {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
|
@ -1084,12 +1103,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
Pattern::VarUsage { .. } => todo!(),
|
Pattern::VarUsage { .. } => todo!(),
|
||||||
Pattern::Assign { .. } => todo!(),
|
Pattern::Assign { .. } => todo!(),
|
||||||
Pattern::Discard { .. } => todo!(),
|
Pattern::Discard { .. } => {
|
||||||
|
self.pattern_ir(pattern, pattern_vec, value_vec, tipo, scope)
|
||||||
|
}
|
||||||
list @ Pattern::List { .. } => {
|
list @ Pattern::List { .. } => {
|
||||||
self.pattern_ir(list, pattern_vec, value_vec, scope);
|
self.pattern_ir(list, pattern_vec, value_vec, tipo, scope);
|
||||||
}
|
}
|
||||||
Pattern::Constructor { .. } => {
|
Pattern::Constructor { .. } => {
|
||||||
self.pattern_ir(pattern, pattern_vec, value_vec, scope);
|
self.pattern_ir(pattern, pattern_vec, value_vec, tipo, scope);
|
||||||
}
|
}
|
||||||
Pattern::Tuple { .. } => todo!(),
|
Pattern::Tuple { .. } => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -1100,6 +1121,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern: &Pattern<tipo::PatternConstructor, Arc<tipo::Type>>,
|
pattern: &Pattern<tipo::PatternConstructor, Arc<tipo::Type>>,
|
||||||
pattern_vec: &mut Vec<Air>,
|
pattern_vec: &mut Vec<Air>,
|
||||||
values: &mut Vec<Air>,
|
values: &mut Vec<Air>,
|
||||||
|
tipo: &Type,
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
match pattern {
|
match pattern {
|
||||||
|
@ -1142,7 +1164,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
name: item_name,
|
name: item_name,
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
});
|
});
|
||||||
self.pattern_ir(a, &mut elements_vec, &mut var_vec, scope.clone());
|
self.pattern_ir(
|
||||||
|
a,
|
||||||
|
&mut elements_vec,
|
||||||
|
&mut var_vec,
|
||||||
|
&tipo.get_inner_type()[0],
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -1160,6 +1188,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
names,
|
names,
|
||||||
tail: tail.is_some(),
|
tail: tail.is_some(),
|
||||||
scope,
|
scope,
|
||||||
|
tipo: tipo.clone().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
|
@ -1241,6 +1270,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
),
|
),
|
||||||
name: constr_name.clone(),
|
name: constr_name.clone(),
|
||||||
}],
|
}],
|
||||||
|
tipo,
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1305,6 +1335,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
),
|
),
|
||||||
name: constr_name.clone(),
|
name: constr_name.clone(),
|
||||||
}],
|
}],
|
||||||
|
tipo,
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1371,11 +1402,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
Air::Var {
|
Air::Var {
|
||||||
name, constructor, ..
|
name, constructor, ..
|
||||||
} => match constructor.variant {
|
} => {
|
||||||
ValueConstructorVariant::LocalVariable { .. } => arg_stack.push(Term::Var(Name {
|
match constructor.variant {
|
||||||
|
ValueConstructorVariant::LocalVariable { .. } => {
|
||||||
|
arg_stack.push(Term::Var(Name {
|
||||||
text: name,
|
text: name,
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})),
|
}))
|
||||||
|
}
|
||||||
ValueConstructorVariant::ModuleConstant { .. } => {
|
ValueConstructorVariant::ModuleConstant { .. } => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
@ -1416,7 +1450,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if data_type_key.defined_type == "Bool" {
|
if data_type_key.defined_type == "Bool" {
|
||||||
arg_stack.push(Term::Constant(UplcConstant::Bool(constr_name == "True")));
|
arg_stack
|
||||||
|
.push(Term::Constant(UplcConstant::Bool(constr_name == "True")));
|
||||||
} else {
|
} else {
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
let data_type = self.data_types.get(&data_type_key).unwrap();
|
||||||
let (constr_index, _constr) = data_type
|
let (constr_index, _constr) = data_type
|
||||||
|
@ -1445,60 +1480,19 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.zip(args_type)
|
.zip(args_type)
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
let arg_to_data = if field.1.as_ref().is_bytearray() {
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::BData).into(),
|
|
||||||
argument: Term::Var(Name {
|
|
||||||
text: field.0 .0.clone(),
|
|
||||||
unique: 0.into(),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if field.1.as_ref().is_int() {
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::IData).into(),
|
|
||||||
argument: Term::Var(Name {
|
|
||||||
text: field.0 .0.clone(),
|
|
||||||
unique: 0.into(),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if field.1.as_ref().is_list() {
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::ListData).into(),
|
|
||||||
argument: Term::Var(Name {
|
|
||||||
text: field.0 .0.clone(),
|
|
||||||
unique: 0.into(),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if field.1.as_ref().is_string() {
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::BData).into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::DecodeUtf8)
|
|
||||||
.into(),
|
|
||||||
argument: Term::Var(Name {
|
|
||||||
text: field.0 .0.clone(),
|
|
||||||
unique: 0.into(),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Term::Var(Name {
|
|
||||||
text: field.0 .0.clone(),
|
|
||||||
unique: 0.into(),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
fields = Term::Apply {
|
fields = Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
function: Term::Builtin(DefaultFunction::MkCons)
|
function: Term::Builtin(DefaultFunction::MkCons)
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
.into(),
|
.into(),
|
||||||
argument: arg_to_data.into(),
|
argument: convert_type_to_data(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: field.0 .0.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
field.1,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: fields.into(),
|
argument: fields.into(),
|
||||||
|
@ -1538,7 +1532,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
}
|
||||||
Air::Discard { .. } => {
|
Air::Discard { .. } => {
|
||||||
arg_stack.push(Term::Constant(UplcConstant::Unit));
|
arg_stack.push(Term::Constant(UplcConstant::Unit));
|
||||||
}
|
}
|
||||||
|
@ -1558,15 +1553,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let list_type = match tipo.deref() {
|
let list_type = tipo.get_inner_type()[0].clone();
|
||||||
Type::App { args, .. } => &args[0],
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if constants.len() == args.len() && !tail {
|
if constants.len() == args.len() && !tail {
|
||||||
let list = Term::Constant(UplcConstant::ProtoList(
|
let list = Term::Constant(UplcConstant::ProtoList(
|
||||||
list_type.get_uplc_type(),
|
UplcType::Data,
|
||||||
constants,
|
convert_constants_to_data(constants),
|
||||||
));
|
));
|
||||||
|
|
||||||
arg_stack.push(list);
|
arg_stack.push(list);
|
||||||
|
@ -1574,7 +1566,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut term = if tail {
|
let mut term = if tail {
|
||||||
arg_stack.pop().unwrap()
|
arg_stack.pop().unwrap()
|
||||||
} else {
|
} else {
|
||||||
Term::Constant(UplcConstant::ProtoList(list_type.get_uplc_type(), vec![]))
|
Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]))
|
||||||
};
|
};
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
|
@ -1584,7 +1576,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Term::Builtin(DefaultFunction::MkCons).into(),
|
Term::Builtin(DefaultFunction::MkCons).into(),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
argument: arg.into(),
|
argument: convert_type_to_data(arg, &list_type).into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: term.into(),
|
argument: term.into(),
|
||||||
|
@ -1593,9 +1585,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Air::ListAccessor {
|
||||||
Air::Tail { .. } => todo!(),
|
names, tail, tipo, ..
|
||||||
Air::ListAccessor { names, tail, .. } => {
|
} => {
|
||||||
let value = arg_stack.pop().unwrap();
|
let value = arg_stack.pop().unwrap();
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
@ -1621,6 +1613,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tail,
|
tail,
|
||||||
current_index,
|
current_index,
|
||||||
term,
|
term,
|
||||||
|
&tipo.get_inner_type()[0],
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Apply {
|
argument: Term::Apply {
|
||||||
|
@ -1635,11 +1628,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Apply {
|
argument: convert_data_to_type(
|
||||||
|
Term::Apply {
|
||||||
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
|
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
|
||||||
.into(),
|
.into(),
|
||||||
argument: value.into(),
|
argument: value.into(),
|
||||||
}
|
},
|
||||||
|
&tipo.get_inner_type()[0],
|
||||||
|
)
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1648,10 +1644,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Air::ListExpose {
|
Air::ListExpose {
|
||||||
tail_head_names,
|
tail_head_names,
|
||||||
tail,
|
tail,
|
||||||
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let list_type = tipo.get_inner_type()[0].clone();
|
||||||
|
|
||||||
if let Some((tail_var, tail_name)) = tail {
|
if let Some((tail_var, tail_name)) = tail {
|
||||||
term = Term::Apply {
|
term = Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
|
@ -1683,14 +1682,19 @@ impl<'a> CodeGenerator<'a> {
|
||||||
body: term.into(),
|
body: term.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Apply {
|
argument: convert_data_to_type(
|
||||||
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
argument: Term::Var(Name {
|
argument: Term::Var(Name {
|
||||||
text: tail_var,
|
text: tail_var,
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
}
|
},
|
||||||
|
&list_type,
|
||||||
|
)
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2391,7 +2395,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
} else if tipo.is_list() {
|
} else if tipo.is_list() {
|
||||||
unreachable!()
|
todo!()
|
||||||
} else {
|
} else {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: DefaultFunction::EqualsInteger.into(),
|
function: DefaultFunction::EqualsInteger.into(),
|
||||||
|
@ -2483,22 +2487,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
argument: Term::Constant(UplcConstant::Integer(index.into())).into(),
|
argument: Term::Constant(UplcConstant::Integer(index.into())).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if tipo.is_int() {
|
term = convert_data_to_type(term, &tipo);
|
||||||
term = Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::UnIData).into(),
|
|
||||||
argument: term.into(),
|
|
||||||
};
|
|
||||||
} else if tipo.is_bytearray() {
|
|
||||||
term = Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::UnBData).into(),
|
|
||||||
argument: term.into(),
|
|
||||||
};
|
|
||||||
} else if tipo.is_list() {
|
|
||||||
term = Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::UnListData).into(),
|
|
||||||
argument: term.into(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
@ -2530,40 +2519,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let unwrapper = if highest.2.is_int() {
|
|
||||||
Term::Apply {
|
|
||||||
function: DefaultFunction::UnIData.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
|
||||||
argument: last_prev_tail.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if highest.2.is_bytearray() {
|
|
||||||
Term::Apply {
|
|
||||||
function: DefaultFunction::UnBData.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
|
||||||
argument: last_prev_tail.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if highest.2.is_list() {
|
|
||||||
Term::Apply {
|
|
||||||
function: DefaultFunction::UnListData.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
|
||||||
argument: last_prev_tail.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
|
||||||
argument: last_prev_tail.into(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
body = Term::Apply {
|
body = Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
parameter_name: Name {
|
parameter_name: Name {
|
||||||
|
@ -2573,7 +2528,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
body: body.into(),
|
body: body.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: unwrapper.into(),
|
argument: convert_data_to_type(
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
||||||
|
argument: last_prev_tail.into(),
|
||||||
|
},
|
||||||
|
&highest.2,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut current_field = None;
|
let mut current_field = None;
|
||||||
|
@ -2600,47 +2562,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
if let Some(ref field) = current_field {
|
if let Some(ref field) = current_field {
|
||||||
if field.0 == index {
|
if field.0 == index {
|
||||||
let unwrapper = if field.2.is_int() {
|
let unwrapper = convert_data_to_type(
|
||||||
Term::Apply {
|
|
||||||
function: DefaultFunction::UnIData.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: prev_tail.clone().into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if field.2.is_bytearray() {
|
|
||||||
Term::Apply {
|
|
||||||
function: DefaultFunction::UnBData.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: prev_tail.clone().into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else if field.2.is_list() {
|
|
||||||
Term::Apply {
|
|
||||||
function: DefaultFunction::UnListData.into(),
|
|
||||||
argument: Term::Apply {
|
|
||||||
function: Term::Builtin(DefaultFunction::HeadList)
|
|
||||||
.force_wrap()
|
|
||||||
.into(),
|
|
||||||
argument: prev_tail.clone().into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Builtin(DefaultFunction::HeadList)
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
.force_wrap()
|
.force_wrap()
|
||||||
.into(),
|
.into(),
|
||||||
argument: prev_tail.clone().into(),
|
argument: prev_tail.clone().into(),
|
||||||
}
|
},
|
||||||
};
|
&field.2,
|
||||||
|
);
|
||||||
|
|
||||||
body = Term::Apply {
|
body = Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
|
@ -2740,6 +2670,64 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(body);
|
arg_stack.push(body);
|
||||||
}
|
}
|
||||||
|
Air::Tuple { tipo, count, .. } => {
|
||||||
|
let mut args = vec![];
|
||||||
|
|
||||||
|
for _ in 0..count {
|
||||||
|
let arg = arg_stack.pop().unwrap();
|
||||||
|
args.push(arg);
|
||||||
|
}
|
||||||
|
let mut constants = vec![];
|
||||||
|
for arg in &args {
|
||||||
|
if let Term::Constant(c) = arg {
|
||||||
|
constants.push(c.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let tuple_sub_types = tipo.get_inner_type();
|
||||||
|
|
||||||
|
if constants.len() == args.len() {
|
||||||
|
let data_constants = convert_constants_to_data(constants);
|
||||||
|
|
||||||
|
if count == 2 {
|
||||||
|
let term = Term::Constant(UplcConstant::ProtoPair(
|
||||||
|
UplcType::Data,
|
||||||
|
UplcType::Data,
|
||||||
|
data_constants[0].clone().into(),
|
||||||
|
data_constants[1].clone().into(),
|
||||||
|
));
|
||||||
|
arg_stack.push(term);
|
||||||
|
} else {
|
||||||
|
let term =
|
||||||
|
Term::Constant(UplcConstant::ProtoList(UplcType::Data, data_constants));
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
|
} else if count == 2 {
|
||||||
|
let term = Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: DefaultFunction::MkPairData.into(),
|
||||||
|
argument: convert_type_to_data(args[0].clone(), &tuple_sub_types[0])
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: convert_type_to_data(args[1].clone(), &tuple_sub_types[1]).into(),
|
||||||
|
};
|
||||||
|
arg_stack.push(term);
|
||||||
|
} else {
|
||||||
|
let mut term = Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]));
|
||||||
|
for (arg, tipo) in args.into_iter().zip(tuple_sub_types.into_iter()) {
|
||||||
|
term = Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::MkCons).into(),
|
||||||
|
argument: convert_type_to_data(arg, &tipo).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
|
}
|
||||||
Air::Todo { .. } => {
|
Air::Todo { .. } => {
|
||||||
arg_stack.push(Term::Error);
|
arg_stack.push(Term::Error);
|
||||||
}
|
}
|
||||||
|
@ -3055,6 +3043,35 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant> {
|
||||||
|
let mut new_constants = vec![];
|
||||||
|
for constant in constants {
|
||||||
|
let constant = match constant {
|
||||||
|
UplcConstant::Integer(i) => {
|
||||||
|
UplcConstant::Data(PlutusData::BigInt(BigInt::Int((i).try_into().unwrap())))
|
||||||
|
}
|
||||||
|
UplcConstant::ByteString(b) => {
|
||||||
|
UplcConstant::Data(PlutusData::BoundedBytes(b.try_into().unwrap()))
|
||||||
|
}
|
||||||
|
UplcConstant::String(s) => UplcConstant::Data(PlutusData::BoundedBytes(
|
||||||
|
s.as_bytes().to_vec().try_into().unwrap(),
|
||||||
|
)),
|
||||||
|
|
||||||
|
UplcConstant::Bool(b) => UplcConstant::Data(PlutusData::Constr(Constr {
|
||||||
|
tag: u64::from(b),
|
||||||
|
any_constructor: None,
|
||||||
|
fields: vec![],
|
||||||
|
})),
|
||||||
|
UplcConstant::ProtoList(_, _) => todo!(),
|
||||||
|
UplcConstant::ProtoPair(_, _, _, _) => todo!(),
|
||||||
|
UplcConstant::Data(_) => todo!(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
new_constants.push(constant);
|
||||||
|
}
|
||||||
|
new_constants
|
||||||
|
}
|
||||||
|
|
||||||
fn constants_ir(literal: &Constant<Arc<Type>, String>, ir_stack: &mut Vec<Air>, scope: Vec<u64>) {
|
fn constants_ir(literal: &Constant<Arc<Type>, String>, ir_stack: &mut Vec<Air>, scope: Vec<u64>) {
|
||||||
match literal {
|
match literal {
|
||||||
Constant::Int { value, .. } => {
|
Constant::Int { value, .. } => {
|
||||||
|
@ -3149,6 +3166,7 @@ fn list_access_to_uplc(
|
||||||
tail: bool,
|
tail: bool,
|
||||||
current_index: usize,
|
current_index: usize,
|
||||||
term: Term<Name>,
|
term: Term<Name>,
|
||||||
|
tipo: &Type,
|
||||||
) -> Term<Name> {
|
) -> Term<Name> {
|
||||||
let (first, names) = names.split_first().unwrap();
|
let (first, names) = names.split_first().unwrap();
|
||||||
|
|
||||||
|
@ -3190,14 +3208,21 @@ fn list_access_to_uplc(
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Apply {
|
argument: convert_data_to_type(
|
||||||
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(),
|
Term::Apply {
|
||||||
|
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
|
||||||
|
.into(),
|
||||||
argument: Term::Var(Name {
|
argument: Term::Var(Name {
|
||||||
text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
|
text: format!(
|
||||||
|
"tail_index_{}_{}",
|
||||||
|
current_index, id_list[current_index]
|
||||||
|
),
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
}
|
},
|
||||||
|
&Arc::new(tipo.clone()),
|
||||||
|
)
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -3248,6 +3273,7 @@ fn list_access_to_uplc(
|
||||||
tail,
|
tail,
|
||||||
current_index + 1,
|
current_index + 1,
|
||||||
term,
|
term,
|
||||||
|
tipo,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Apply {
|
argument: Term::Apply {
|
||||||
|
@ -3436,3 +3462,240 @@ fn rearrange_clauses(
|
||||||
|
|
||||||
final_clauses
|
final_clauses
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> {
|
||||||
|
if field_type.is_bytearray() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::BData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_int() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::IData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_map() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::MapData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_list() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::ListData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_string() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::BData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: DefaultFunction::EncodeUtf8.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_tuple() {
|
||||||
|
match field_type.get_uplc_type() {
|
||||||
|
UplcType::List(_) => Term::Apply {
|
||||||
|
function: DefaultFunction::ListData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
},
|
||||||
|
UplcType::Pair(_, _) => Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: "__pair".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: Term::Apply {
|
||||||
|
function: DefaultFunction::ListData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::MkCons)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::FstPair)
|
||||||
|
.force_wrap()
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: "__pair".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::MkCons)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::SndPair)
|
||||||
|
.force_wrap()
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: "__pair".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(UplcConstant::ProtoList(
|
||||||
|
UplcType::Data,
|
||||||
|
vec![],
|
||||||
|
))
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_bool() {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr {
|
||||||
|
tag: convert_constr_to_tag(1),
|
||||||
|
any_constructor: None,
|
||||||
|
fields: vec![],
|
||||||
|
})))
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr {
|
||||||
|
tag: convert_constr_to_tag(0),
|
||||||
|
any_constructor: None,
|
||||||
|
fields: vec![],
|
||||||
|
})))
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
term
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name> {
|
||||||
|
if field_type.is_int() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnIData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_bytearray() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnBData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_map() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnMapData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_list() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnListData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_string() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::DecodeUtf8.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: DefaultFunction::UnBData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else if field_type.is_tuple() {
|
||||||
|
match field_type.get_uplc_type() {
|
||||||
|
UplcType::List(_) => Term::Apply {
|
||||||
|
function: DefaultFunction::UnListData.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
},
|
||||||
|
UplcType::Pair(_, _) => Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: "__list_data".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: "__tail".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::MkPairData).into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: "__list_data".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: "__tail".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: "__list_data".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::UnListData)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
term
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
(lam
|
(lam
|
||||||
__constr_get_field
|
__constr_get_field
|
||||||
[
|
[
|
||||||
[
|
(lam
|
||||||
[
|
x
|
||||||
(force (builtin ifThenElse))
|
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
(builtin equalsByteString)
|
(builtin equalsByteString)
|
||||||
|
@ -35,12 +34,28 @@
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
(con bytestring #0102)
|
[
|
||||||
|
(builtin unBData)
|
||||||
|
[
|
||||||
|
[
|
||||||
|
__constr_get_field
|
||||||
|
[ __constr_fields_exposer rdmr ]
|
||||||
|
]
|
||||||
|
(con integer 0)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
(con bool False)
|
|
||||||
]
|
]
|
||||||
(con bool True)
|
)
|
||||||
|
[
|
||||||
|
[
|
||||||
|
(builtin mkCons)
|
||||||
|
[ (builtin bData) (con bytestring #f4) ]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[ (builtin mkCons) rdmr ]
|
||||||
|
[ [ (builtin mkCons) datum ] (con listdata []) ]
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
(lam
|
(lam
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue