feat: use Rc for more things, fib_iter runs almost 3 seconds faster now

This commit is contained in:
rvcas 2023-01-31 03:30:45 -05:00 committed by Lucas
parent eda3194cf0
commit c8efe60843
15 changed files with 1789 additions and 1110 deletions

View File

@ -1,4 +1,4 @@
use std::{cell::RefCell, sync::Arc}; use std::{cell::RefCell, rc::Rc, sync::Arc};
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use itertools::Itertools; use itertools::Itertools;
@ -186,7 +186,8 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
parameter_name: Name { parameter_name: Name {
text: "__pair".to_string(), text: "__pair".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: apply_wrap( body: apply_wrap(
DefaultFunction::ListData.into(), DefaultFunction::ListData.into(),
apply_wrap( apply_wrap(
@ -196,10 +197,13 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
Term::Builtin(DefaultFunction::FstPair) Term::Builtin(DefaultFunction::FstPair)
.force_wrap() .force_wrap()
.force_wrap(), .force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "__pair".to_string(), text: "__pair".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
), ),
apply_wrap( apply_wrap(
@ -209,13 +213,16 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
Term::Builtin(DefaultFunction::SndPair) Term::Builtin(DefaultFunction::SndPair)
.force_wrap() .force_wrap()
.force_wrap(), .force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "__pair".to_string(), text: "__pair".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
), ),
), ),
Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])), ),
Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]).into()),
), ),
), ),
) )
@ -228,16 +235,22 @@ pub fn convert_type_to_data(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
} else if field_type.is_bool() { } else if field_type.is_bool() {
if_else( if_else(
term, term,
Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr { Term::Constant(
UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(1), tag: convert_constr_to_tag(1),
any_constructor: None, any_constructor: None,
fields: vec![], fields: vec![],
}))), }))
Term::Constant(UplcConstant::Data(PlutusData::Constr(Constr { .into(),
),
Term::Constant(
UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(0), tag: convert_constr_to_tag(0),
any_constructor: None, any_constructor: None,
fields: vec![], fields: vec![],
}))), }))
.into(),
),
) )
} else { } else {
term term
@ -262,40 +275,51 @@ pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
parameter_name: Name { parameter_name: Name {
text: "__list_data".to_string(), text: "__list_data".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: apply_wrap( body: apply_wrap(
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__tail".to_string(), text: "__tail".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: apply_wrap( body: apply_wrap(
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::MkPairData), Term::Builtin(DefaultFunction::MkPairData),
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::HeadList).force_wrap(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "__list_data".to_string(), text: "__list_data".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
), ),
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::HeadList).force_wrap(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "__tail".to_string(), text: "__tail".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
) )
.into(), .into(),
}, },
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::TailList).force_wrap(), Term::Builtin(DefaultFunction::TailList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "__list_data".to_string(), text: "__list_data".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
) )
.into(), .into(),
@ -308,7 +332,7 @@ pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
apply_wrap( apply_wrap(
apply_wrap( apply_wrap(
DefaultFunction::EqualsInteger.into(), DefaultFunction::EqualsInteger.into(),
Term::Constant(UplcConstant::Integer(1)), Term::Constant(UplcConstant::Integer(1).into()),
), ),
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::FstPair) Term::Builtin(DefaultFunction::FstPair)
@ -493,19 +517,28 @@ pub fn list_access_to_uplc(
let head_list = if current_tipo.is_map() { let head_list = if current_tipo.is_map() {
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::HeadList).force_wrap(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
Term::Var(Name { 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(),
),
) )
} else { } else {
convert_data_to_type( convert_data_to_type(
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::HeadList).force_wrap(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
Term::Var(Name { Term::Var(
text: format!("tail_index_{}_{}", current_index, id_list[current_index]), Name {
text: format!(
"tail_index_{}_{}",
current_index, id_list[current_index]
),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
&current_tipo.to_owned(), &current_tipo.to_owned(),
) )
@ -516,30 +549,36 @@ pub fn list_access_to_uplc(
parameter_name: Name { parameter_name: 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(),
body: apply_wrap( body: apply_wrap(
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first.clone(), text: first.clone(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: apply_wrap( body: apply_wrap(
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: names[0].clone(), text: names[0].clone(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: term.into(), body: term.into(),
}, },
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::TailList).force_wrap(), Term::Builtin(DefaultFunction::TailList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
current_index, id_list[current_index] current_index, id_list[current_index]
), ),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
) )
.into(), .into(),
@ -553,33 +592,41 @@ pub fn list_access_to_uplc(
parameter_name: Name { parameter_name: 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(),
body: apply_wrap( body: apply_wrap(
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first.clone(), text: first.clone(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: if check_last_item { body: if check_last_item {
delayed_choose_list( delayed_choose_list(
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::TailList).force_wrap(), Term::Builtin(DefaultFunction::TailList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
current_index, id_list[current_index] current_index, id_list[current_index]
), ),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
term, term,
apply_wrap( apply_wrap(
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::Trace).force_wrap(), Term::Builtin(DefaultFunction::Trace).force_wrap(),
Term::Constant(UplcConstant::String( Term::Constant(
UplcConstant::String(
"List/Tuple contains more items than it should" "List/Tuple contains more items than it should"
.to_string(), .to_string(),
)), )
.into(),
),
), ),
Term::Delay(Term::Error.into()), Term::Delay(Term::Error.into()),
) )
@ -599,13 +646,15 @@ pub fn list_access_to_uplc(
parameter_name: Name { parameter_name: 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(),
body: apply_wrap( body: apply_wrap(
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first.clone(), text: first.clone(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: apply_wrap( body: apply_wrap(
list_access_to_uplc( list_access_to_uplc(
names, names,
@ -618,13 +667,16 @@ pub fn list_access_to_uplc(
), ),
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::TailList).force_wrap(), Term::Builtin(DefaultFunction::TailList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: format!( text: format!(
"tail_index_{}_{}", "tail_index_{}_{}",
current_index, id_list[current_index] current_index, id_list[current_index]
), ),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
) )
.into(), .into(),
@ -935,27 +987,28 @@ pub fn get_variant_name(new_name: &mut String, t: &Arc<Type>) {
}); });
} }
pub fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant> { pub fn convert_constants_to_data(constants: Vec<Rc<UplcConstant>>) -> Vec<UplcConstant> {
let mut new_constants = vec![]; let mut new_constants = vec![];
for constant in constants { for constant in constants {
let constant = match constant { let constant = match constant.as_ref() {
UplcConstant::Integer(i) => { UplcConstant::Integer(i) => {
UplcConstant::Data(PlutusData::BigInt(BigInt::Int((i).try_into().unwrap()))) UplcConstant::Data(PlutusData::BigInt(BigInt::Int((*i).try_into().unwrap())))
} }
UplcConstant::ByteString(b) => { UplcConstant::ByteString(b) => {
UplcConstant::Data(PlutusData::BoundedBytes(b.try_into().unwrap())) UplcConstant::Data(PlutusData::BoundedBytes(b.clone().try_into().unwrap()))
} }
UplcConstant::String(s) => UplcConstant::Data(PlutusData::BoundedBytes( UplcConstant::String(s) => UplcConstant::Data(PlutusData::BoundedBytes(
s.as_bytes().to_vec().try_into().unwrap(), s.as_bytes().to_vec().try_into().unwrap(),
)), )),
UplcConstant::Bool(b) => UplcConstant::Data(PlutusData::Constr(Constr { UplcConstant::Bool(b) => UplcConstant::Data(PlutusData::Constr(Constr {
tag: convert_constr_to_tag(b.into()), tag: convert_constr_to_tag((*b).into()),
any_constructor: None, any_constructor: None,
fields: vec![], fields: vec![],
})), })),
UplcConstant::ProtoList(_, constants) => { UplcConstant::ProtoList(_, constants) => {
let inner_constants = convert_constants_to_data(constants) let inner_constants =
convert_constants_to_data(constants.iter().cloned().map(Rc::new).collect())
.into_iter() .into_iter()
.map(|constant| match constant { .map(|constant| match constant {
UplcConstant::Data(d) => d, UplcConstant::Data(d) => d,
@ -966,7 +1019,7 @@ pub fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConsta
UplcConstant::Data(PlutusData::Array(inner_constants)) UplcConstant::Data(PlutusData::Array(inner_constants))
} }
UplcConstant::ProtoPair(_, _, left, right) => { UplcConstant::ProtoPair(_, _, left, right) => {
let inner_constants = vec![*left, *right]; let inner_constants = vec![left.clone(), right.clone()];
let inner_constants = convert_constants_to_data(inner_constants) let inner_constants = convert_constants_to_data(inner_constants)
.into_iter() .into_iter()
.map(|constant| match constant { .map(|constant| match constant {
@ -980,7 +1033,7 @@ pub fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConsta
inner_constants[1].clone(), inner_constants[1].clone(),
)]))) )])))
} }
d @ UplcConstant::Data(_) => d, d @ UplcConstant::Data(_) => d.clone(),
_ => unreachable!(), _ => unreachable!(),
}; };
new_constants.push(constant); new_constants.push(constant);
@ -997,14 +1050,18 @@ pub fn wrap_validator_args(term: Term<Name>, arguments: &[TypedArg]) -> Term<Nam
parameter_name: Name { parameter_name: Name {
text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(), text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: term.into(), body: term.into(),
}, },
convert_data_to_type( convert_data_to_type(
Term::Var(Name { Term::Var(
Name {
text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(), text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
&arg.tipo, &arg.tipo,
), ),
); );
@ -1014,7 +1071,8 @@ pub fn wrap_validator_args(term: Term<Name>, arguments: &[TypedArg]) -> Term<Nam
parameter_name: Name { parameter_name: Name {
text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(), text: arg.arg_name.get_variable_name().unwrap_or("_").to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: term.into(), body: term.into(),
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -655,7 +655,7 @@ where
.map(|script| match script.program.eval(initial_budget) { .map(|script| match script.program.eval(initial_budget) {
(Ok(result), remaining_budget, logs) => EvalInfo { (Ok(result), remaining_budget, logs) => EvalInfo {
success: result != Term::Error success: result != Term::Error
&& result != Term::Constant(Constant::Bool(false)), && result != Term::Constant(Constant::Bool(false).into()),
script, script,
spent_budget: initial_budget - remaining_budget, spent_budget: initial_budget - remaining_budget,
output: Some(result), output: Some(result),

View File

@ -74,7 +74,7 @@ where
pub fn apply_data(&self, plutus_data: PlutusData) -> Self { pub fn apply_data(&self, plutus_data: PlutusData) -> Self {
let applied_term = Term::Apply { let applied_term = Term::Apply {
function: Rc::new(self.term.clone()), function: Rc::new(self.term.clone()),
argument: Rc::new(Term::Constant(Constant::Data(plutus_data))), argument: Rc::new(Term::Constant(Constant::Data(plutus_data).into())),
}; };
Program { Program {
@ -239,7 +239,7 @@ pub enum Constant {
// tag: 5 // tag: 5
ProtoList(Type, Vec<Constant>), ProtoList(Type, Vec<Constant>),
// tag: 6 // tag: 6
ProtoPair(Type, Type, Box<Constant>, Box<Constant>), ProtoPair(Type, Type, Rc<Constant>, Rc<Constant>),
// tag: 7 // tag: 7
// Apply(Box<Constant>, Type), // Apply(Box<Constant>, Type),
// tag: 8 // tag: 8
@ -253,8 +253,8 @@ pub enum Type {
String, String,
ByteString, ByteString,
Unit, Unit,
List(Box<Type>), List(Rc<Type>),
Pair(Box<Type>, Box<Type>), Pair(Rc<Type>, Rc<Type>),
Data, Data,
} }

View File

@ -23,7 +23,7 @@ pub fn final_wrapper(term: Term<Name>) -> Term<Name> {
argument: term.into(), argument: term.into(),
} }
.into(), .into(),
argument: Term::Delay(Term::Constant(Constant::Unit).into()).into(), argument: Term::Delay(Term::Constant(Constant::Unit.into()).into()).into(),
} }
.into(), .into(),
argument: Term::Delay(Term::Error.into()).into(), argument: Term::Delay(Term::Error.into()).into(),
@ -38,24 +38,32 @@ pub fn assert_on_list(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: apply_wrap( body: apply_wrap(
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: term.into(), body: term.into(),
}, },
apply_wrap( apply_wrap(
Term::Var(Name { Term::Var(
Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}), }
Term::Var(Name { .into(),
),
Term::Var(
Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
) )
.into(), .into(),
@ -64,64 +72,88 @@ pub fn assert_on_list(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Lambda { body: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "list_to_check".to_string(), text: "list_to_check".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Lambda { body: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "check_with".to_string(), text: "check_with".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: delayed_choose_list( body: delayed_choose_list(
Term::Var(Name { Term::Var(
Name {
text: "list_to_check".to_string(), text: "list_to_check".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
Term::Constant(Constant::Unit), .into(),
),
Term::Constant(Constant::Unit.into()),
apply_wrap( apply_wrap(
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::ChooseUnit).force_wrap(), Term::Builtin(DefaultFunction::ChooseUnit).force_wrap(),
apply_wrap( apply_wrap(
Term::Var(Name { Term::Var(
Name {
text: "check_with".to_string(), text: "check_with".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::HeadList).force_wrap(), Term::Builtin(DefaultFunction::HeadList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "list_to_check".to_string(), text: "list_to_check".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
), ),
), ),
apply_wrap( apply_wrap(
apply_wrap( apply_wrap(
apply_wrap( apply_wrap(
Term::Var(Name { Term::Var(
Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}), }
Term::Var(Name { .into(),
),
Term::Var(
Name {
text: ASSERT_ON_LIST.to_string(), text: ASSERT_ON_LIST.to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
apply_wrap( apply_wrap(
Term::Builtin(DefaultFunction::TailList).force_wrap(), Term::Builtin(DefaultFunction::TailList).force_wrap(),
Term::Var(Name { Term::Var(
Name {
text: "list_to_check".to_string(), text: "list_to_check".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
), ),
), ),
Term::Var(Name { ),
Term::Var(
Name {
text: "check_with".to_string(), text: "check_with".to_string(),
unique: 0.into(), unique: 0.into(),
}), }
.into(),
),
), ),
), ),
) )
@ -140,7 +172,8 @@ pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: CONSTR_FIELDS_EXPOSER.to_string(), text: CONSTR_FIELDS_EXPOSER.to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: term.into(), body: term.into(),
} }
.into(), .into(),
@ -148,7 +181,8 @@ pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: "__constr_var".to_string(), text: "__constr_var".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Apply { body: Term::Apply {
function: Term::Force( function: Term::Force(
Term::Force(Term::Builtin(DefaultFunction::SndPair).into()).into(), Term::Force(Term::Builtin(DefaultFunction::SndPair).into()).into(),
@ -156,10 +190,13 @@ pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> {
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
function: Term::Builtin(DefaultFunction::UnConstrData).into(), function: Term::Builtin(DefaultFunction::UnConstrData).into(),
argument: Term::Var(Name { argument: Term::Var(
Name {
text: "__constr_var".to_string(), text: "__constr_var".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
@ -188,7 +225,8 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: CONSTR_GET_FIELD.to_string(), text: CONSTR_GET_FIELD.to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: term.into(), body: term.into(),
} }
.into(), .into(),
@ -196,42 +234,54 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: "__constr_list".to_string(), text: "__constr_list".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Lambda { body: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__arg_number".to_string(), text: "__arg_number".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Apply { body: Term::Apply {
function: Term::Lambda { function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__recurse".to_string(), text: "__recurse".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Apply { body: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Var(Name { function: Term::Var(
Name {
text: "__recurse".to_string(), text: "__recurse".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(), .into(),
argument: Term::Var(Name { )
.into(),
argument: Term::Var(
Name {
text: "__recurse".to_string(), text: "__recurse".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
// Start recursive with index 0 of list // Start recursive with index 0 of list
argument: Term::Constant(Constant::Integer(0.into())).into(), argument: Term::Constant(Constant::Integer(0.into()).into()).into(),
} }
.into(), .into(),
argument: Term::Var(Name { argument: Term::Var(
Name {
text: "__constr_list".to_string(), text: "__constr_list".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
@ -242,17 +292,20 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: "__self_recursor".to_string(), text: "__self_recursor".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Lambda { body: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__current_arg_number".to_string(), text: "__current_arg_number".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Lambda { body: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: "__list_of_constr_args".to_string(), text: "__list_of_constr_args".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Apply { body: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
@ -268,17 +321,24 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
DefaultFunction::EqualsInteger, DefaultFunction::EqualsInteger,
) )
.into(), .into(),
argument: Term::Var(Name { argument: Term::Var(
Name {
text: "__arg_number".to_string(), text: "__arg_number".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
argument: Term::Var(Name { argument: Term::Var(
text: "__current_arg_number".to_string(), Name {
text: "__current_arg_number"
.to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
@ -294,19 +354,26 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
parameter_name: Name { parameter_name: Name {
text: "__current_list_of_constr_args".to_string(), text: "__current_list_of_constr_args".to_string(),
unique: 0.into(), unique: 0.into(),
}, }
.into(),
body: Term::Apply { body: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Var(Name { function: Term::Var(
Name {
text: "__self_recursor".to_string(), text: "__self_recursor".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(), .into(),
argument: Term::Var(Name { )
.into(),
argument: Term::Var(
Name {
text: "__self_recursor".to_string(), text: "__self_recursor".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
@ -317,16 +384,19 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
DefaultFunction::AddInteger, DefaultFunction::AddInteger,
) )
.into(), .into(),
argument: Term::Var(Name { argument: Term::Var(
Name {
text: "__current_arg_number" text: "__current_arg_number"
.to_string(), .to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
argument: Term::Constant( argument: Term::Constant(
Constant::Integer(1.into()), Constant::Integer(1.into()).into(),
) )
.into(), .into(),
} }
@ -341,11 +411,14 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
) )
.into(), .into(),
argument: Term::Var(Name { argument: Term::Var(
Name {
text: "__current_list_of_constr_args" text: "__current_list_of_constr_args"
.to_string(), .to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),
@ -355,10 +428,13 @@ pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
.into(), .into(),
} }
.into(), .into(),
argument: Term::Var(Name { argument: Term::Var(
Name {
text: "__list_of_constr_args".to_string(), text: "__list_of_constr_args".to_string(),
unique: 0.into(), unique: 0.into(),
}) }
.into(),
)
.into(), .into(),
} }
.into(), .into(),

View File

@ -37,10 +37,13 @@ impl Converter {
term: &Term<Name>, term: &Term<Name>,
) -> Result<Term<NamedDeBruijn>, Error> { ) -> Result<Term<NamedDeBruijn>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(name) => Term::Var(NamedDeBruijn { Term::Var(name) => Term::Var(
NamedDeBruijn {
text: name.text.to_string(), text: name.text.to_string(),
index: self.get_index(name)?, index: self.get_index(name)?,
}), }
.into(),
),
Term::Delay(term) => Term::Delay(Rc::new(self.name_to_named_debruijn(term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.name_to_named_debruijn(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
@ -64,7 +67,7 @@ impl Converter {
self.remove_unique(parameter_name.unique); self.remove_unique(parameter_name.unique);
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name.into(),
body: Rc::new(body), body: Rc::new(body),
} }
} }
@ -83,7 +86,7 @@ impl Converter {
pub fn name_to_debruijn(&mut self, term: &Term<Name>) -> Result<Term<DeBruijn>, Error> { pub fn name_to_debruijn(&mut self, term: &Term<Name>) -> Result<Term<DeBruijn>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(name) => Term::Var(self.get_index(name)?), Term::Var(name) => Term::Var(self.get_index(name)?.into()),
Term::Delay(term) => Term::Delay(Rc::new(self.name_to_debruijn(term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.name_to_debruijn(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
@ -102,7 +105,7 @@ impl Converter {
self.remove_unique(parameter_name.unique); self.remove_unique(parameter_name.unique);
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name.into(),
body: Rc::new(body), body: Rc::new(body),
} }
} }
@ -124,10 +127,13 @@ impl Converter {
term: &Term<NamedDeBruijn>, term: &Term<NamedDeBruijn>,
) -> Result<Term<Name>, Error> { ) -> Result<Term<Name>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(NamedDeBruijn { text, index }) => Term::Var(Name { Term::Var(var_name) => Term::Var(
text: text.to_string(), Name {
unique: self.get_unique(*index)?, text: var_name.text.to_string(),
}), unique: self.get_unique(&var_name.index)?,
}
.into(),
),
Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_name(term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_name(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
@ -135,7 +141,7 @@ impl Converter {
} => { } => {
self.declare_binder(); self.declare_binder();
let unique = self.get_unique(parameter_name.index)?; let unique = self.get_unique(&parameter_name.index)?;
let name = Name { let name = Name {
text: parameter_name.text.to_string(), text: parameter_name.text.to_string(),
@ -149,7 +155,7 @@ impl Converter {
self.end_scope(); self.end_scope();
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name.into(),
body: Rc::new(body), body: Rc::new(body),
} }
} }
@ -169,12 +175,15 @@ impl Converter {
pub fn debruijn_to_name(&mut self, term: &Term<DeBruijn>) -> Result<Term<Name>, Error> { pub fn debruijn_to_name(&mut self, term: &Term<DeBruijn>) -> Result<Term<Name>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(index) => { Term::Var(index) => {
let unique = self.get_unique(*index)?; let unique = self.get_unique(index)?;
Term::Var(Name { Term::Var(
Name {
text: format!("i_{}", unique), text: format!("i_{}", unique),
unique, unique,
}) }
.into(),
)
} }
Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_name(term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_name(term)?)),
Term::Lambda { Term::Lambda {
@ -183,7 +192,7 @@ impl Converter {
} => { } => {
self.declare_binder(); self.declare_binder();
let unique = self.get_unique(*parameter_name)?; let unique = self.get_unique(parameter_name)?;
let name = Name { let name = Name {
text: format!("i_{}", unique), text: format!("i_{}", unique),
@ -197,7 +206,7 @@ impl Converter {
self.end_scope(); self.end_scope();
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name.into(),
body: Rc::new(body), body: Rc::new(body),
} }
} }
@ -217,13 +226,13 @@ impl Converter {
#[allow(clippy::only_used_in_recursion)] #[allow(clippy::only_used_in_recursion)]
pub fn named_debruijn_to_debruijn(&mut self, term: &Term<NamedDeBruijn>) -> Term<DeBruijn> { pub fn named_debruijn_to_debruijn(&mut self, term: &Term<NamedDeBruijn>) -> Term<DeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.clone().into()), Term::Var(name) => Term::Var(name.index.into()),
Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_debruijn(term))), Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_debruijn(term))),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.clone().into(), parameter_name: parameter_name.index.into(),
body: Rc::new(self.named_debruijn_to_debruijn(body)), body: Rc::new(self.named_debruijn_to_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
@ -240,13 +249,19 @@ impl Converter {
#[allow(clippy::only_used_in_recursion)] #[allow(clippy::only_used_in_recursion)]
pub fn debruijn_to_named_debruijn(&mut self, term: &Term<DeBruijn>) -> Term<NamedDeBruijn> { pub fn debruijn_to_named_debruijn(&mut self, term: &Term<DeBruijn>) -> Term<NamedDeBruijn> {
match term { match term {
Term::Var(name) => Term::Var((*name).into()), Term::Var(name) => Term::Var(
NamedDeBruijn {
text: format!("i_{}", name),
index: *name.as_ref(),
}
.into(),
),
Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_named_debruijn(term))), Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_named_debruijn(term))),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: (*parameter_name).into(), parameter_name: NamedDeBruijn::from(*parameter_name.as_ref()).into(),
body: Rc::new(self.debruijn_to_named_debruijn(body)), body: Rc::new(self.debruijn_to_named_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
@ -266,7 +281,7 @@ impl Converter {
term: &Term<FakeNamedDeBruijn>, term: &Term<FakeNamedDeBruijn>,
) -> Term<NamedDeBruijn> { ) -> Term<NamedDeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.clone().into()), Term::Var(name) => Term::Var(NamedDeBruijn::from(name.as_ref().clone()).into()),
Term::Delay(term) => { Term::Delay(term) => {
Term::Delay(Rc::new(self.fake_named_debruijn_to_named_debruijn(term))) Term::Delay(Rc::new(self.fake_named_debruijn_to_named_debruijn(term)))
} }
@ -274,7 +289,7 @@ impl Converter {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.clone().into(), parameter_name: NamedDeBruijn::from(parameter_name.as_ref().clone()).into(),
body: Rc::new(self.fake_named_debruijn_to_named_debruijn(body)), body: Rc::new(self.fake_named_debruijn_to_named_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
@ -296,7 +311,7 @@ impl Converter {
term: &Term<NamedDeBruijn>, term: &Term<NamedDeBruijn>,
) -> Term<FakeNamedDeBruijn> { ) -> Term<FakeNamedDeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.clone().into()), Term::Var(name) => Term::Var(FakeNamedDeBruijn::from(name.as_ref().clone()).into()),
Term::Delay(term) => { Term::Delay(term) => {
Term::Delay(Rc::new(self.named_debruijn_to_fake_named_debruijn(term))) Term::Delay(Rc::new(self.named_debruijn_to_fake_named_debruijn(term)))
} }
@ -304,7 +319,7 @@ impl Converter {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.clone().into(), parameter_name: FakeNamedDeBruijn::from(parameter_name.as_ref().clone()).into(),
body: Rc::new(self.named_debruijn_to_fake_named_debruijn(body)), body: Rc::new(self.named_debruijn_to_fake_named_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
@ -332,7 +347,7 @@ impl Converter {
Err(Error::FreeUnique(name.clone())) Err(Error::FreeUnique(name.clone()))
} }
fn get_unique(&mut self, index: DeBruijn) -> Result<Unique, Error> { fn get_unique(&mut self, index: &DeBruijn) -> Result<Unique, Error> {
for scope in self.levels.iter().rev() { for scope in self.levels.iter().rev() {
let index = Level(self.current_level.0 - index.inner()); let index = Level(self.current_level.0 - index.inner());
@ -341,7 +356,7 @@ impl Converter {
} }
} }
Err(Error::FreeIndex(index)) Err(Error::FreeIndex(*index))
} }
fn declare_unique(&mut self, unique: Unique) { fn declare_unique(&mut self, unique: Unique) {

View File

@ -179,10 +179,10 @@ where
{ {
fn decode(d: &mut Decoder) -> Result<Self, de::Error> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
match decode_term_tag(d)? { match decode_term_tag(d)? {
0 => Ok(Term::Var(T::decode(d)?)), 0 => Ok(Term::Var(T::decode(d)?.into())),
1 => Ok(Term::Delay(Rc::new(Term::decode(d)?))), 1 => Ok(Term::Delay(Rc::new(Term::decode(d)?))),
2 => Ok(Term::Lambda { 2 => Ok(Term::Lambda {
parameter_name: T::binder_decode(d)?, parameter_name: T::binder_decode(d)?.into(),
body: Rc::new(Term::decode(d)?), body: Rc::new(Term::decode(d)?),
}), }),
3 => Ok(Term::Apply { 3 => Ok(Term::Apply {
@ -190,7 +190,7 @@ where
argument: Rc::new(Term::decode(d)?), argument: Rc::new(Term::decode(d)?),
}), }),
// Need size limit for Constant // Need size limit for Constant
4 => Ok(Term::Constant(Constant::decode(d)?)), 4 => Ok(Term::Constant(Constant::decode(d)?.into())),
5 => Ok(Term::Force(Rc::new(Term::decode(d)?))), 5 => Ok(Term::Force(Rc::new(Term::decode(d)?))),
6 => Ok(Term::Error), 6 => Ok(Term::Error),
7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)), 7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)),
@ -228,7 +228,7 @@ where
match var_option { match var_option {
Ok(var) => { Ok(var) => {
state_log.push(format!("{})", var.text())); state_log.push(format!("{})", var.text()));
Ok(Term::Var(var)) Ok(Term::Var(var.into()))
} }
Err(error) => { Err(error) => {
state_log.push("parse error)".to_string()); state_log.push("parse error)".to_string());
@ -263,7 +263,7 @@ where
Ok(term) => { Ok(term) => {
state_log.push(")".to_string()); state_log.push(")".to_string());
Ok(Term::Lambda { Ok(Term::Lambda {
parameter_name: var, parameter_name: var.into(),
body: Rc::new(term), body: Rc::new(term),
}) })
} }
@ -315,7 +315,7 @@ where
match con_option { match con_option {
Ok(constant) => { Ok(constant) => {
state_log.push(format!("{})", constant.to_pretty())); state_log.push(format!("{})", constant.to_pretty()));
Ok(Term::Constant(constant)) Ok(Term::Constant(constant.into()))
} }
Err(error) => { Err(error) => {
state_log.push("parse error)".to_string()); state_log.push("parse error)".to_string());
@ -502,7 +502,7 @@ impl<'b> Decode<'b> for Constant {
let typ = decode_type(&mut rest)?; let typ = decode_type(&mut rest)?;
let list: Vec<Constant> = let list: Vec<Constant> =
d.decode_list_with(|d| decode_constant_value(typ.clone(), d))?; d.decode_list_with(|d| decode_constant_value(typ.clone().into(), d))?;
Ok(Constant::ProtoList(typ, list)) Ok(Constant::ProtoList(typ, list))
} }
@ -512,10 +512,10 @@ impl<'b> Decode<'b> for Constant {
let type1 = decode_type(&mut rest)?; let type1 = decode_type(&mut rest)?;
let type2 = decode_type(&mut rest)?; let type2 = decode_type(&mut rest)?;
let a = decode_constant_value(type1.clone(), d)?; let a = decode_constant_value(type1.clone().into(), d)?;
let b = decode_constant_value(type2.clone(), d)?; let b = decode_constant_value(type2.clone().into(), d)?;
Ok(Constant::ProtoPair(type1, type2, Box::new(a), Box::new(b))) Ok(Constant::ProtoPair(type1, type2, a.into(), b.into()))
} }
[8] => { [8] => {
let cbor = Vec::<u8>::decode(d)?; let cbor = Vec::<u8>::decode(d)?;
@ -533,8 +533,8 @@ impl<'b> Decode<'b> for Constant {
} }
} }
fn decode_constant_value(typ: Type, d: &mut Decoder) -> Result<Constant, de::Error> { fn decode_constant_value(typ: Rc<Type>, d: &mut Decoder) -> Result<Constant, de::Error> {
match typ { match typ.as_ref() {
Type::Integer => Ok(Constant::Integer(i128::decode(d)?)), Type::Integer => Ok(Constant::Integer(i128::decode(d)?)),
Type::ByteString => Ok(Constant::ByteString(Vec::<u8>::decode(d)?)), Type::ByteString => Ok(Constant::ByteString(Vec::<u8>::decode(d)?)),
Type::String => Ok(Constant::String(String::decode(d)?)), Type::String => Ok(Constant::String(String::decode(d)?)),
@ -542,19 +542,19 @@ fn decode_constant_value(typ: Type, d: &mut Decoder) -> Result<Constant, de::Err
Type::Bool => Ok(Constant::Bool(bool::decode(d)?)), Type::Bool => Ok(Constant::Bool(bool::decode(d)?)),
Type::List(sub_type) => { Type::List(sub_type) => {
let list: Vec<Constant> = let list: Vec<Constant> =
d.decode_list_with(|d| decode_constant_value(*sub_type.clone(), d))?; d.decode_list_with(|d| decode_constant_value(sub_type.clone(), d))?;
Ok(Constant::ProtoList(*sub_type, list)) Ok(Constant::ProtoList(sub_type.as_ref().clone(), list))
} }
Type::Pair(type1, type2) => { Type::Pair(type1, type2) => {
let a = decode_constant_value(*type1.clone(), d)?; let a = decode_constant_value(type1.clone(), d)?;
let b = decode_constant_value(*type2.clone(), d)?; let b = decode_constant_value(type2.clone(), d)?;
Ok(Constant::ProtoPair( Ok(Constant::ProtoPair(
*type1, type1.as_ref().clone(),
*type2, type2.as_ref().clone(),
Box::new(a), a.into(),
Box::new(b), b.into(),
)) ))
} }
Type::Data => { Type::Data => {
@ -577,13 +577,13 @@ fn decode_type(types: &mut VecDeque<u8>) -> Result<Type, de::Error> {
Some(3) => Ok(Type::Unit), Some(3) => Ok(Type::Unit),
Some(8) => Ok(Type::Data), Some(8) => Ok(Type::Data),
Some(7) => match types.pop_front() { Some(7) => match types.pop_front() {
Some(5) => Ok(Type::List(Box::new(decode_type(types)?))), Some(5) => Ok(Type::List(decode_type(types)?.into())),
Some(7) => match types.pop_front() { Some(7) => match types.pop_front() {
Some(6) => { Some(6) => {
let type1 = decode_type(types)?; let type1 = decode_type(types)?;
let type2 = decode_type(types)?; let type2 = decode_type(types)?;
Ok(Type::Pair(Box::new(type1), Box::new(type2))) Ok(Type::Pair(type1.into(), type2.into()))
} }
Some(x) => Err(de::Error::Message(format!( Some(x) => Err(de::Error::Message(format!(
"Unknown constant type tag: {}", "Unknown constant type tag: {}",
@ -818,7 +818,7 @@ mod test {
fn flat_encode_integer() { fn flat_encode_integer() {
let program = Program::<Name> { let program = Program::<Name> {
version: (11, 22, 33), version: (11, 22, 33),
term: Term::Constant(Constant::Integer(11)), term: Term::Constant(Constant::Integer(11).into()),
}; };
let expected_bytes = vec![ let expected_bytes = vec![
@ -834,13 +834,16 @@ mod test {
fn flat_encode_list_list_integer() { fn flat_encode_list_list_integer() {
let program = Program::<Name> { let program = Program::<Name> {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Constant(Constant::ProtoList( term: Term::Constant(
Type::List(Box::new(Type::Integer)), Constant::ProtoList(
Type::List(Type::Integer.into()),
vec![ vec![
Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]), Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]),
Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]), Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]),
], ],
)), )
.into(),
),
}; };
let expected_bytes = vec![ let expected_bytes = vec![
@ -857,17 +860,21 @@ mod test {
fn flat_encode_pair_pair_integer_bool_integer() { fn flat_encode_pair_pair_integer_bool_integer() {
let program = Program::<Name> { let program = Program::<Name> {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Constant(Constant::ProtoPair( term: Term::Constant(
Type::Pair(Box::new(Type::Integer), Box::new(Type::Bool)), Constant::ProtoPair(
Type::Pair(Type::Integer.into(), Type::Bool.into()),
Type::Integer, Type::Integer,
Box::new(Constant::ProtoPair( Constant::ProtoPair(
Type::Integer, Type::Integer,
Type::Bool, Type::Bool,
Box::new(Constant::Integer(11)), Constant::Integer(11).into(),
Box::new(Constant::Bool(true)), Constant::Bool(true).into(),
)), )
Box::new(Constant::Integer(11)), .into(),
)), Constant::Integer(11).into(),
)
.into(),
),
}; };
let expected_bytes = vec![ let expected_bytes = vec![
@ -889,13 +896,16 @@ mod test {
let expected_program = Program::<Name> { let expected_program = Program::<Name> {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Constant(Constant::ProtoList( term: Term::Constant(
Type::List(Box::new(Type::Integer)), Constant::ProtoList(
Type::List(Type::Integer.into()),
vec![ vec![
Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]), Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]),
Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]), Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]),
], ],
)), )
.into(),
),
}; };
let actual_program: Program<Name> = Program::unflat(&bytes).unwrap(); let actual_program: Program<Name> = Program::unflat(&bytes).unwrap();
@ -912,17 +922,21 @@ mod test {
let expected_program = Program::<Name> { let expected_program = Program::<Name> {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Constant(Constant::ProtoPair( term: Term::Constant(
Type::Pair(Box::new(Type::Integer), Box::new(Type::Bool)), Constant::ProtoPair(
Type::Pair(Type::Integer.into(), Type::Bool.into()),
Type::Integer, Type::Integer,
Box::new(Constant::ProtoPair( Constant::ProtoPair(
Type::Integer, Type::Integer,
Type::Bool, Type::Bool,
Box::new(Constant::Integer(11)), Constant::Integer(11).into(),
Box::new(Constant::Bool(true)), Constant::Bool(true).into(),
)), )
Box::new(Constant::Integer(11)), .into(),
)), Constant::Integer(11).into(),
)
.into(),
),
}; };
let actual_program: Program<Name> = Program::unflat(&bytes).unwrap(); let actual_program: Program<Name> = Program::unflat(&bytes).unwrap();
@ -938,7 +952,7 @@ mod test {
let expected_program = Program { let expected_program = Program {
version: (11, 22, 33), version: (11, 22, 33),
term: Term::Constant(Constant::Integer(11)), term: Term::Constant(Constant::Integer(11).into()),
}; };
let actual_program: Program<Name> = Program::unflat(&bytes).unwrap(); let actual_program: Program<Name> = Program::unflat(&bytes).unwrap();

View File

@ -39,7 +39,7 @@ enum PartialTerm {
// tag: 1 // tag: 1
Delay, Delay,
// tag: 2 // tag: 2
Lambda(NamedDeBruijn), Lambda(Rc<NamedDeBruijn>),
// tag: 3 // tag: 3
Apply, Apply,
// tag: 4 // tag: 4
@ -330,7 +330,7 @@ impl Machine {
fn lookup_var(&mut self, name: &NamedDeBruijn, env: Rc<Vec<Value>>) -> Result<Value, Error> { fn lookup_var(&mut self, name: &NamedDeBruijn, env: Rc<Vec<Value>>) -> Result<Value, Error> {
env.get::<usize>(env.len() - usize::from(name.index)) env.get::<usize>(env.len() - usize::from(name.index))
.cloned() .cloned()
.ok_or_else(|| Error::OpenTermEvaluated(Term::Var(name.clone()))) .ok_or_else(|| Error::OpenTermEvaluated(Term::Var(name.clone().into())))
} }
fn step_and_maybe_spend(&mut self, step: StepKind) -> Result<(), Error> { fn step_and_maybe_spend(&mut self, step: StepKind) -> Result<(), Error> {
@ -398,10 +398,7 @@ fn discharge_value(value: Value) -> Rc<Term<NamedDeBruijn>> {
0, 0,
env, env,
Term::Lambda { Term::Lambda {
parameter_name: NamedDeBruijn { parameter_name: parameter_name.clone(),
text: parameter_name.text,
index: 0.into(),
},
body, body,
} }
.into(), .into(),
@ -511,10 +508,10 @@ enum Context {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Value { pub enum Value {
Con(Constant), Con(Rc<Constant>),
Delay(Rc<Term<NamedDeBruijn>>, Rc<Vec<Value>>), Delay(Rc<Term<NamedDeBruijn>>, Rc<Vec<Value>>),
Lambda { Lambda {
parameter_name: NamedDeBruijn, parameter_name: Rc<NamedDeBruijn>,
body: Rc<Term<NamedDeBruijn>>, body: Rc<Term<NamedDeBruijn>>,
env: Rc<Vec<Value>>, env: Rc<Vec<Value>>,
}, },
@ -527,17 +524,17 @@ pub enum Value {
impl Value { impl Value {
pub fn is_integer(&self) -> bool { pub fn is_integer(&self) -> bool {
matches!(self, Value::Con(Constant::Integer(_))) matches!(self, Value::Con(i) if matches!(i.as_ref(), Constant::Integer(_)))
} }
pub fn is_bool(&self) -> bool { pub fn is_bool(&self) -> bool {
matches!(self, Value::Con(Constant::Bool(_))) matches!(self, Value::Con(b) if matches!(b.as_ref(), Constant::Bool(_)))
} }
// TODO: Make this to_ex_mem not recursive. // TODO: Make this to_ex_mem not recursive.
pub fn to_ex_mem(&self) -> i64 { pub fn to_ex_mem(&self) -> i64 {
match self { match self {
Value::Con(c) => match c { Value::Con(c) => match c.as_ref() {
Constant::Integer(i) => { Constant::Integer(i) => {
if *i == 0 { if *i == 0 {
1 1
@ -556,10 +553,10 @@ impl Value {
Constant::Unit => 1, Constant::Unit => 1,
Constant::Bool(_) => 1, Constant::Bool(_) => 1,
Constant::ProtoList(_, items) => items.iter().fold(0, |acc, constant| { Constant::ProtoList(_, items) => items.iter().fold(0, |acc, constant| {
acc + Value::Con(constant.clone()).to_ex_mem() acc + Value::Con(constant.clone().into()).to_ex_mem()
}), }),
Constant::ProtoPair(_, _, l, r) => { Constant::ProtoPair(_, _, l, r) => {
Value::Con(*l.clone()).to_ex_mem() + Value::Con(*r.clone()).to_ex_mem() Value::Con(l.clone()).to_ex_mem() + Value::Con(r.clone()).to_ex_mem()
} }
Constant::Data(item) => self.data_to_ex_mem(item), Constant::Data(item) => self.data_to_ex_mem(item),
}, },
@ -603,14 +600,14 @@ impl Value {
PlutusData::BigInt(i) => { PlutusData::BigInt(i) => {
if let BigInt::Int(g) = i { if let BigInt::Int(g) = i {
let numb: i128 = (*g).try_into().unwrap(); let numb: i128 = (*g).try_into().unwrap();
total += Value::Con(Constant::Integer(numb)).to_ex_mem(); total += Value::Con(Constant::Integer(numb).into()).to_ex_mem();
} else { } else {
unreachable!() unreachable!()
}; };
} }
PlutusData::BoundedBytes(b) => { PlutusData::BoundedBytes(b) => {
let byte_string: Vec<u8> = b.deref().clone(); let byte_string: Vec<u8> = b.deref().clone();
total += Value::Con(Constant::ByteString(byte_string)).to_ex_mem(); total += Value::Con(Constant::ByteString(byte_string).into()).to_ex_mem();
} }
PlutusData::Array(a) => { PlutusData::Array(a) => {
// create new stack with of items from the list of data // create new stack with of items from the list of data
@ -679,7 +676,7 @@ impl TryFrom<Value> for Constant {
fn try_from(value: Value) -> Result<Self, Self::Error> { fn try_from(value: Value) -> Result<Self, Self::Error> {
match value { match value {
Value::Con(constant) => Ok(constant), Value::Con(constant) => Ok(constant.as_ref().clone()),
rest => Err(Error::NotAConstant(rest)), rest => Err(Error::NotAConstant(rest)),
} }
} }
@ -693,9 +690,9 @@ impl From<&Constant> for Type {
Constant::String(_) => Type::String, Constant::String(_) => Type::String,
Constant::Unit => Type::Unit, Constant::Unit => Type::Unit,
Constant::Bool(_) => Type::Bool, Constant::Bool(_) => Type::Bool,
Constant::ProtoList(t, _) => Type::List(Box::new(t.clone())), Constant::ProtoList(t, _) => Type::List(Rc::new(t.clone())),
Constant::ProtoPair(t1, t2, _, _) => { Constant::ProtoPair(t1, t2, _, _) => {
Type::Pair(Box::new(t1.clone()), Box::new(t2.clone())) Type::Pair(Rc::new(t1.clone()), Rc::new(t2.clone()))
} }
Constant::Data(_) => Type::Data, Constant::Data(_) => Type::Data,
} }

View File

@ -1,4 +1,4 @@
use std::ops::Deref; use std::{ops::Deref, rc::Rc};
use pallas_primitives::babbage::{BigInt, Constr, PlutusData}; use pallas_primitives::babbage::{BigInt, Constr, PlutusData};
@ -281,7 +281,7 @@ impl DefaultFunction {
} else { } else {
let first = args[0].clone(); let first = args[0].clone();
arg.expect_type(Type::List(Box::new(first.try_into()?))) arg.expect_type(Type::List(Rc::new(first.try_into()?)))
} }
} }
DefaultFunction::HeadList => arg.expect_list(), DefaultFunction::HeadList => arg.expect_list(),
@ -298,14 +298,14 @@ impl DefaultFunction {
if args.is_empty() { if args.is_empty() {
arg.expect_type(Type::Integer) arg.expect_type(Type::Integer)
} else { } else {
arg.expect_type(Type::List(Box::new(Type::Data))) arg.expect_type(Type::List(Rc::new(Type::Data)))
} }
} }
DefaultFunction::MapData => arg.expect_type(Type::List(Box::new(Type::Pair( DefaultFunction::MapData => arg.expect_type(Type::List(Rc::new(Type::Pair(
Box::new(Type::Data), Rc::new(Type::Data),
Box::new(Type::Data), Rc::new(Type::Data),
)))), )))),
DefaultFunction::ListData => arg.expect_type(Type::List(Box::new(Type::Data))), DefaultFunction::ListData => arg.expect_type(Type::List(Rc::new(Type::Data))),
DefaultFunction::IData => arg.expect_type(Type::Integer), DefaultFunction::IData => arg.expect_type(Type::Integer),
DefaultFunction::BData => arg.expect_type(Type::ByteString), DefaultFunction::BData => arg.expect_type(Type::ByteString),
DefaultFunction::UnConstrData => arg.expect_type(Type::Data), DefaultFunction::UnConstrData => arg.expect_type(Type::Data),
@ -327,176 +327,262 @@ impl DefaultFunction {
pub fn call(&self, args: &[Value], logs: &mut Vec<String>) -> Result<Value, Error> { pub fn call(&self, args: &[Value], logs: &mut Vec<String>) -> Result<Value, Error> {
match self { match self {
DefaultFunction::AddInteger => match (&args[0], &args[1]) { DefaultFunction::AddInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
match arg1.checked_add(*arg2) { match arg1.checked_add(*arg2) {
Some(res) => Ok(Value::Con(Constant::Integer(res))), Some(res) => Ok(Value::Con(Constant::Integer(res).into())),
None => Err(Error::OverflowError), None => Err(Error::OverflowError),
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::SubtractInteger => match (&args[0], &args[1]) { DefaultFunction::SubtractInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
match arg1.checked_sub(*arg2) { match arg1.checked_sub(*arg2) {
Some(res) => Ok(Value::Con(Constant::Integer(res))), Some(res) => Ok(Value::Con(Constant::Integer(res).into())),
None => Err(Error::OverflowError), None => Err(Error::OverflowError),
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::MultiplyInteger => match (&args[0], &args[1]) { DefaultFunction::MultiplyInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
match arg1.checked_mul(*arg2) { match arg1.checked_mul(*arg2) {
Some(res) => Ok(Value::Con(Constant::Integer(res))), Some(res) => Ok(Value::Con(Constant::Integer(res).into())),
None => Err(Error::OverflowError), None => Err(Error::OverflowError),
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::DivideInteger => match (&args[0], &args[1]) { DefaultFunction::DivideInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
if *arg2 != 0 { if *arg2 != 0 {
let ret = (*arg1 as f64) / (*arg2 as f64); let ret = (*arg1 as f64) / (*arg2 as f64);
Ok(Value::Con(Constant::Integer(ret.floor() as i128))) Ok(Value::Con(Constant::Integer(ret.floor() as i128).into()))
} else { } else {
Err(Error::DivideByZero(*arg1, *arg2)) Err(Error::DivideByZero(*arg1, *arg2))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::QuotientInteger => match (&args[0], &args[1]) { DefaultFunction::QuotientInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
if *arg2 != 0 { if *arg2 != 0 {
let ret = (*arg1 as f64) / (*arg2 as f64); let ret = (*arg1 as f64) / (*arg2 as f64);
let ret = if ret < 0. { ret.ceil() } else { ret.floor() }; let ret = if ret < 0. { ret.ceil() } else { ret.floor() };
Ok(Value::Con(Constant::Integer(ret as i128))) Ok(Value::Con(Constant::Integer(ret as i128).into()))
} else { } else {
Err(Error::DivideByZero(*arg1, *arg2)) Err(Error::DivideByZero(*arg1, *arg2))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::RemainderInteger => match (&args[0], &args[1]) { DefaultFunction::RemainderInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
if *arg2 != 0 { if *arg2 != 0 {
let ret = arg1 % arg2; let ret = arg1 % arg2;
Ok(Value::Con(Constant::Integer(ret))) Ok(Value::Con(Constant::Integer(ret).into()))
} else { } else {
Err(Error::DivideByZero(*arg1, *arg2)) Err(Error::DivideByZero(*arg1, *arg2))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::ModInteger => match (&args[0], &args[1]) { DefaultFunction::ModInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
if *arg2 != 0 { if *arg2 != 0 {
let ret = arg1 % arg2; let ret = arg1 % arg2;
Ok(Value::Con(Constant::Integer(ret.abs()))) Ok(Value::Con(Constant::Integer(ret.abs()).into()))
} else { } else {
Err(Error::DivideByZero(*arg1, *arg2)) Err(Error::DivideByZero(*arg1, *arg2))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::EqualsInteger => match (&args[0], &args[1]) { DefaultFunction::EqualsInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
Ok(Value::Con(Constant::Bool(arg1 == arg2))) match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
Ok(Value::Con(Constant::Bool(arg1 == arg2).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::LessThanInteger => match (&args[0], &args[1]) { DefaultFunction::LessThanInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
Ok(Value::Con(Constant::Bool(arg1 < arg2))) match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
Ok(Value::Con(Constant::Bool(arg1 < arg2).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::LessThanEqualsInteger => match (&args[0], &args[1]) { DefaultFunction::LessThanEqualsInteger => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(integer1), Value::Con(integer2)) => {
Ok(Value::Con(Constant::Bool(arg1 <= arg2))) match (integer1.as_ref(), integer2.as_ref()) {
(Constant::Integer(arg1), Constant::Integer(arg2)) => {
Ok(Value::Con(Constant::Bool(arg1 <= arg2).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::AppendByteString => match (&args[0], &args[1]) { DefaultFunction::AppendByteString => match (&args[0], &args[1]) {
( (Value::Con(byte_string1), Value::Con(byte_string2)) => {
Value::Con(Constant::ByteString(arg1)), match (byte_string1.as_ref(), byte_string2.as_ref()) {
Value::Con(Constant::ByteString(arg2)), (Constant::ByteString(arg1), Constant::ByteString(arg2)) => Ok(Value::Con(
) => Ok(Value::Con(Constant::ByteString( Constant::ByteString(
arg1.iter().copied().chain(arg2.iter().copied()).collect(), arg1.iter().copied().chain(arg2.iter().copied()).collect(),
))), )
.into(),
)),
_ => unreachable!(),
}
}
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::ConsByteString => match (&args[0], &args[1]) { DefaultFunction::ConsByteString => match (&args[0], &args[1]) {
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::ByteString(arg2))) => { (Value::Con(integer), Value::Con(byte_string)) => {
match (integer.as_ref(), byte_string.as_ref()) {
(Constant::Integer(arg1), Constant::ByteString(arg2)) => {
let mut ret = vec![(arg1 % 256) as u8]; let mut ret = vec![(arg1 % 256) as u8];
ret.extend(arg2.clone()); ret.extend(arg2.clone());
Ok(Value::Con(Constant::ByteString(ret))) Ok(Value::Con(Constant::ByteString(ret).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::SliceByteString => match (&args[0], &args[1], &args[2]) { DefaultFunction::SliceByteString => match (&args[0], &args[1], &args[2]) {
(Value::Con(integer1), Value::Con(integer2), Value::Con(byte_string)) => {
match (integer1.as_ref(), integer2.as_ref(), byte_string.as_ref()) {
( (
Value::Con(Constant::Integer(arg1)), Constant::Integer(arg1),
Value::Con(Constant::Integer(arg2)), Constant::Integer(arg2),
Value::Con(Constant::ByteString(arg3)), Constant::ByteString(arg3),
) => { ) => {
let skip = if 0 > *arg1 { 0 } else { *arg1 as usize }; let skip = if 0 > *arg1 { 0 } else { *arg1 as usize };
let take = if 0 > *arg2 { 0 } else { *arg2 as usize }; let take = if 0 > *arg2 { 0 } else { *arg2 as usize };
let ret: Vec<u8> = arg3.iter().skip(skip).take(take).cloned().collect(); let ret: Vec<u8> = arg3.iter().skip(skip).take(take).cloned().collect();
Ok(Value::Con(Constant::ByteString(ret))) Ok(Value::Con(Constant::ByteString(ret).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::LengthOfByteString => match &args[0] { DefaultFunction::LengthOfByteString => match &args[0] {
Value::Con(Constant::ByteString(arg1)) => { Value::Con(byte_string) => match byte_string.as_ref() {
Ok(Value::Con(Constant::Integer(arg1.len() as i128))) Constant::ByteString(arg1) => {
Ok(Value::Con(Constant::Integer(arg1.len() as i128).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::IndexByteString => match (&args[0], &args[1]) { DefaultFunction::IndexByteString => match (&args[0], &args[1]) {
(Value::Con(Constant::ByteString(arg1)), Value::Con(Constant::Integer(arg2))) => { (Value::Con(byte_string), Value::Con(integer)) => {
match (byte_string.as_ref(), integer.as_ref()) {
(Constant::ByteString(arg1), Constant::Integer(arg2)) => {
let index = *arg2 as usize; let index = *arg2 as usize;
if 0 <= *arg2 && index < arg1.len() { if 0 <= *arg2 && index < arg1.len() {
let ret = arg1[index] as i128; let ret = arg1[index] as i128;
Ok(Value::Con(Constant::Integer(ret))) Ok(Value::Con(Constant::Integer(ret).into()))
} else { } else {
Err(Error::ByteStringOutOfBounds(*arg2, arg1.to_vec())) Err(Error::ByteStringOutOfBounds(*arg2, arg1.to_vec()))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}
}
_ => unreachable!(),
}, },
DefaultFunction::EqualsByteString => match (&args[0], &args[1]) { DefaultFunction::EqualsByteString => match (&args[0], &args[1]) {
( (Value::Con(byte_string1), Value::Con(byte_string2)) => {
Value::Con(Constant::ByteString(arg1)), match (byte_string1.as_ref(), byte_string2.as_ref()) {
Value::Con(Constant::ByteString(arg2)), (Constant::ByteString(arg1), Constant::ByteString(arg2)) => {
) => Ok(Value::Con(Constant::Bool(arg1 == arg2))), Ok(Value::Con(Constant::Bool(arg1 == arg2).into()))
}
_ => unreachable!(),
}
}
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::LessThanByteString => match (&args[0], &args[1]) { DefaultFunction::LessThanByteString => match (&args[0], &args[1]) {
( (Value::Con(byte_string1), Value::Con(byte_string2)) => {
Value::Con(Constant::ByteString(arg1)), match (byte_string1.as_ref(), byte_string2.as_ref()) {
Value::Con(Constant::ByteString(arg2)), (Constant::ByteString(arg1), Constant::ByteString(arg2)) => {
) => Ok(Value::Con(Constant::Bool(arg1 < arg2))), Ok(Value::Con(Constant::Bool(arg1 < arg2).into()))
}
_ => unreachable!(),
}
}
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::LessThanEqualsByteString => match (&args[0], &args[1]) { DefaultFunction::LessThanEqualsByteString => match (&args[0], &args[1]) {
( (Value::Con(byte_string1), Value::Con(byte_string2)) => {
Value::Con(Constant::ByteString(arg1)), match (byte_string1.as_ref(), byte_string2.as_ref()) {
Value::Con(Constant::ByteString(arg2)), (Constant::ByteString(arg1), Constant::ByteString(arg2)) => {
) => Ok(Value::Con(Constant::Bool(arg1 <= arg2))), Ok(Value::Con(Constant::Bool(arg1 <= arg2).into()))
}
_ => unreachable!(),
}
}
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::Sha2_256 => match &args[0] { DefaultFunction::Sha2_256 => match &args[0] {
Value::Con(Constant::ByteString(arg1)) => { Value::Con(byte_string) => match byte_string.as_ref() {
Constant::ByteString(arg1) => {
use cryptoxide::{digest::Digest, sha2::Sha256}; use cryptoxide::{digest::Digest, sha2::Sha256};
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
@ -507,12 +593,15 @@ impl DefaultFunction {
hasher.result(&mut bytes); hasher.result(&mut bytes);
Ok(Value::Con(Constant::ByteString(bytes))) Ok(Value::Con(Constant::ByteString(bytes).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::Sha3_256 => match &args[0] { DefaultFunction::Sha3_256 => match &args[0] {
Value::Con(Constant::ByteString(arg1)) => { Value::Con(byte_string) => match byte_string.as_ref() {
Constant::ByteString(arg1) => {
use cryptoxide::{digest::Digest, sha3::Sha3_256}; use cryptoxide::{digest::Digest, sha3::Sha3_256};
let mut hasher = Sha3_256::new(); let mut hasher = Sha3_256::new();
@ -523,12 +612,15 @@ impl DefaultFunction {
hasher.result(&mut bytes); hasher.result(&mut bytes);
Ok(Value::Con(Constant::ByteString(bytes))) Ok(Value::Con(Constant::ByteString(bytes).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::Blake2b_256 => match &args[0] { DefaultFunction::Blake2b_256 => match &args[0] {
Value::Con(Constant::ByteString(arg1)) => { Value::Con(byte_string) => match byte_string.as_ref() {
Constant::ByteString(arg1) => {
use cryptoxide::{blake2b::Blake2b, digest::Digest}; use cryptoxide::{blake2b::Blake2b, digest::Digest};
let mut digest = [0u8; 32]; let mut digest = [0u8; 32];
@ -537,67 +629,91 @@ impl DefaultFunction {
context.input(arg1); context.input(arg1);
context.result(&mut digest); context.result(&mut digest);
Ok(Value::Con(Constant::ByteString(digest.to_vec()))) Ok(Value::Con(Constant::ByteString(digest.to_vec()).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::VerifyEd25519Signature => match (&args[0], &args[1], &args[2]) { DefaultFunction::VerifyEd25519Signature => match (&args[0], &args[1], &args[2]) {
(Value::Con(public_key), Value::Con(message), Value::Con(signature)) => {
match (public_key.as_ref(), message.as_ref(), signature.as_ref()) {
( (
Value::Con(Constant::ByteString(public_key)), Constant::ByteString(public_key),
Value::Con(Constant::ByteString(message)), Constant::ByteString(message),
Value::Con(Constant::ByteString(signature)), Constant::ByteString(signature),
) => { ) => {
use cryptoxide::ed25519; use cryptoxide::ed25519;
let public_key: [u8; 32] = public_key let public_key: [u8; 32] =
.clone() public_key.clone().try_into().map_err(|e: Vec<u8>| {
.try_into() Error::UnexpectedEd25519PublicKeyLength(e.len())
.map_err(|e: Vec<u8>| Error::UnexpectedEd25519PublicKeyLength(e.len()))?; })?;
let signature: [u8; 64] = signature let signature: [u8; 64] =
.clone() signature.clone().try_into().map_err(|e: Vec<u8>| {
.try_into() Error::UnexpectedEd25519SignatureLength(e.len())
.map_err(|e: Vec<u8>| Error::UnexpectedEd25519SignatureLength(e.len()))?; })?;
let valid = ed25519::verify(message, &public_key, &signature); let valid = ed25519::verify(message, &public_key, &signature);
Ok(Value::Con(Constant::Bool(valid))) Ok(Value::Con(Constant::Bool(valid).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(), DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(), DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
DefaultFunction::AppendString => match (&args[0], &args[1]) { DefaultFunction::AppendString => match (&args[0], &args[1]) {
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => { (Value::Con(string1), Value::Con(string2)) => {
Ok(Value::Con(Constant::String(format!("{}{}", arg1, arg2)))) match (string1.as_ref(), string2.as_ref()) {
(Constant::String(arg1), Constant::String(arg2)) => Ok(Value::Con(
Constant::String(format!("{}{}", arg1, arg2)).into(),
)),
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::EqualsString => match (&args[0], &args[1]) { DefaultFunction::EqualsString => match (&args[0], &args[1]) {
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => { (Value::Con(string1), Value::Con(string2)) => {
Ok(Value::Con(Constant::Bool(arg1 == arg2))) match (string1.as_ref(), string2.as_ref()) {
(Constant::String(arg1), Constant::String(arg2)) => {
Ok(Value::Con(Constant::Bool(arg1 == arg2).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::EncodeUtf8 => match &args[0] { DefaultFunction::EncodeUtf8 => match &args[0] {
Value::Con(Constant::String(arg1)) => { Value::Con(string) => match string.as_ref() {
Constant::String(arg1) => {
let bytes = arg1.as_bytes().to_vec(); let bytes = arg1.as_bytes().to_vec();
Ok(Value::Con(Constant::ByteString(bytes))) Ok(Value::Con(Constant::ByteString(bytes).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::DecodeUtf8 => match &args[0] { DefaultFunction::DecodeUtf8 => match &args[0] {
Value::Con(Constant::ByteString(arg1)) => { Value::Con(byte_string) => match byte_string.as_ref() {
Constant::ByteString(arg1) => {
let string = String::from_utf8(arg1.clone())?; let string = String::from_utf8(arg1.clone())?;
Ok(Value::Con(Constant::String(string))) Ok(Value::Con(Constant::String(string).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::IfThenElse => match args[0] { _ => unreachable!(),
Value::Con(Constant::Bool(condition)) => { },
if condition { DefaultFunction::IfThenElse => match &args[0] {
Value::Con(boolean) => match boolean.as_ref() {
Constant::Bool(condition) => {
if *condition {
Ok(args[1].clone()) Ok(args[1].clone())
} else { } else {
Ok(args[2].clone()) Ok(args[2].clone())
@ -605,28 +721,47 @@ impl DefaultFunction {
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::ChooseUnit => match &args[0] { DefaultFunction::ChooseUnit => match &args[0] {
Value::Con(Constant::Unit) => Ok(args[1].clone()), Value::Con(unit) => match unit.as_ref() {
Constant::Unit => Ok(args[1].clone()),
_ => unreachable!(),
},
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::Trace => match &args[0] { DefaultFunction::Trace => match &args[0] {
Value::Con(Constant::String(arg1)) => { Value::Con(string) => match string.as_ref() {
Constant::String(arg1) => {
logs.push(arg1.clone()); logs.push(arg1.clone());
Ok(args[1].clone()) Ok(args[1].clone())
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::FstPair => match &args[0] { DefaultFunction::FstPair => match &args[0] {
Value::Con(Constant::ProtoPair(_, _, first, _)) => Ok(Value::Con(*first.clone())), Value::Con(pair) => match pair.as_ref() {
Constant::ProtoPair(_, _, first, _) => {
Ok(Value::Con(first.as_ref().clone().into()))
}
_ => unreachable!(),
},
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::SndPair => match &args[0] { DefaultFunction::SndPair => match &args[0] {
Value::Con(Constant::ProtoPair(_, _, _, second)) => Ok(Value::Con(*second.clone())), Value::Con(pair) => match pair.as_ref() {
Constant::ProtoPair(_, _, _, second) => {
Ok(Value::Con(second.as_ref().clone().into()))
}
_ => unreachable!(),
},
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::ChooseList => match &args[0] { DefaultFunction::ChooseList => match &args[0] {
Value::Con(Constant::ProtoList(_, list)) => { Value::Con(list) => match list.as_ref() {
Constant::ProtoList(_, list) => {
if list.is_empty() { if list.is_empty() {
Ok(args[1].clone()) Ok(args[1].clone())
} else { } else {
@ -635,57 +770,72 @@ impl DefaultFunction {
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::MkCons => match (&args[0], &args[1]) { DefaultFunction::MkCons => match (&args[0], &args[1]) {
(Value::Con(item), Value::Con(Constant::ProtoList(r#type, list))) => { (Value::Con(item), Value::Con(list)) => match list.as_ref() {
let mut ret = vec![item.clone()]; Constant::ProtoList(r#type, list) => {
let mut ret = vec![item.as_ref().clone()];
ret.extend(list.clone()); ret.extend(list.clone());
Ok(Value::Con(Constant::ProtoList(r#type.clone(), ret))) Ok(Value::Con(Constant::ProtoList(r#type.clone(), ret).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::HeadList => match &args[0] { DefaultFunction::HeadList => match &args[0] {
c @ Value::Con(Constant::ProtoList(_, list)) => { c @ Value::Con(list) => match list.as_ref() {
Constant::ProtoList(_, list) => {
if list.is_empty() { if list.is_empty() {
Err(Error::EmptyList(c.clone())) Err(Error::EmptyList(c.clone()))
} else { } else {
Ok(Value::Con(list[0].clone())) Ok(Value::Con(list[0].clone().into()))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::TailList => match &args[0] { DefaultFunction::TailList => match &args[0] {
c @ Value::Con(Constant::ProtoList(r#type, list)) => { c @ Value::Con(list) => match list.as_ref() {
Constant::ProtoList(r#type, list) => {
if list.is_empty() { if list.is_empty() {
Err(Error::EmptyList(c.clone())) Err(Error::EmptyList(c.clone()))
} else { } else {
Ok(Value::Con(Constant::ProtoList( Ok(Value::Con(
r#type.clone(), Constant::ProtoList(r#type.clone(), list[1..].to_vec()).into(),
list[1..].to_vec(), ))
)))
} }
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::NullList => match &args[0] { DefaultFunction::NullList => match &args[0] {
Value::Con(Constant::ProtoList(_, list)) => { Value::Con(list) => match list.as_ref() {
Ok(Value::Con(Constant::Bool(list.is_empty()))) Constant::ProtoList(_, list) => {
Ok(Value::Con(Constant::Bool(list.is_empty()).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::ChooseData => match &args[0] { DefaultFunction::ChooseData => match &args[0] {
Value::Con(Constant::Data(PlutusData::Constr(_))) => Ok(args[1].clone()), Value::Con(con) => match con.as_ref() {
Value::Con(Constant::Data(PlutusData::Map(_))) => Ok(args[2].clone()), Constant::Data(PlutusData::Constr(_)) => Ok(args[1].clone()),
Value::Con(Constant::Data(PlutusData::Array(_))) => Ok(args[3].clone()), Constant::Data(PlutusData::Map(_)) => Ok(args[2].clone()),
Value::Con(Constant::Data(PlutusData::BigInt(_))) => Ok(args[4].clone()), Constant::Data(PlutusData::Array(_)) => Ok(args[3].clone()),
Value::Con(Constant::Data(PlutusData::BoundedBytes(_))) => Ok(args[5].clone()), Constant::Data(PlutusData::BigInt(_)) => Ok(args[4].clone()),
Constant::Data(PlutusData::BoundedBytes(_)) => Ok(args[5].clone()),
_ => unreachable!(),
},
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::ConstrData => match (&args[0], &args[1]) { DefaultFunction::ConstrData => match (&args[0], &args[1]) {
( (Value::Con(integer), Value::Con(list)) => {
Value::Con(Constant::Integer(i)), match (integer.as_ref(), list.as_ref()) {
Value::Con(Constant::ProtoList(Type::Data, l)), (Constant::Integer(i), Constant::ProtoList(Type::Data, l)) => {
) => {
let data_list: Vec<PlutusData> = l let data_list: Vec<PlutusData> = l
.iter() .iter()
.map(|item| match item { .map(|item| match item {
@ -700,20 +850,25 @@ impl DefaultFunction {
any_constructor: None, any_constructor: None,
fields: data_list, fields: data_list,
}); });
Ok(Value::Con(Constant::Data(constr_data)))
Ok(Value::Con(Constant::Data(constr_data).into()))
}
_ => unreachable!(),
}
} }
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::MapData => match &args[0] { DefaultFunction::MapData => match &args[0] {
Value::Con(Constant::ProtoList(_, list)) => { Value::Con(list) => match list.as_ref() {
Constant::ProtoList(_, list) => {
let mut map = Vec::new(); let mut map = Vec::new();
for item in list { for item in list {
match item { match item {
Constant::ProtoPair(Type::Data, Type::Data, left, right) => { Constant::ProtoPair(Type::Data, Type::Data, left, right) => {
match (*left.clone(), *right.clone()) { match (left.as_ref(), right.as_ref()) {
(Constant::Data(key), Constant::Data(value)) => { (Constant::Data(key), Constant::Data(value)) => {
map.push((key, value)); map.push((key.clone(), value.clone()));
} }
_ => unreachable!(), _ => unreachable!(),
} }
@ -722,12 +877,17 @@ impl DefaultFunction {
} }
} }
Ok(Value::Con(Constant::Data(PlutusData::Map(map.into())))) Ok(Value::Con(
Constant::Data(PlutusData::Map(map.into())).into(),
))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::ListData => match &args[0] { DefaultFunction::ListData => match &args[0] {
Value::Con(Constant::ProtoList(_, list)) => { Value::Con(list) => match list.as_ref() {
Constant::ProtoList(_, list) => {
let data_list: Vec<PlutusData> = list let data_list: Vec<PlutusData> = list
.iter() .iter()
.map(|item| match item { .map(|item| match item {
@ -736,30 +896,44 @@ impl DefaultFunction {
}) })
.collect(); .collect();
Ok(Value::Con(Constant::Data(PlutusData::Array(data_list)))) Ok(Value::Con(
Constant::Data(PlutusData::Array(data_list)).into(),
))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::IData => match &args[0] { DefaultFunction::IData => match &args[0] {
Value::Con(Constant::Integer(i)) => Ok(Value::Con(Constant::Data( Value::Con(integer) => match integer.as_ref() {
PlutusData::BigInt(BigInt::Int((*i).try_into().unwrap())), Constant::Integer(i) => Ok(Value::Con(
))), Constant::Data(PlutusData::BigInt(BigInt::Int((*i).try_into().unwrap())))
.into(),
)),
_ => unreachable!(),
},
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::BData => match &args[0] { DefaultFunction::BData => match &args[0] {
Value::Con(Constant::ByteString(b)) => Ok(Value::Con(Constant::Data( Value::Con(byte_string) => match byte_string.as_ref() {
PlutusData::BoundedBytes(b.clone().try_into().unwrap()), Constant::ByteString(b) => Ok(Value::Con(
))), Constant::Data(PlutusData::BoundedBytes(b.clone().try_into().unwrap()))
.into(),
)),
_ => unreachable!(),
},
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::UnConstrData => match &args[0] { DefaultFunction::UnConstrData => match &args[0] {
Value::Con(Constant::Data(PlutusData::Constr(c))) => { Value::Con(con) => match con.as_ref() {
Ok(Value::Con(Constant::ProtoPair( Constant::Data(PlutusData::Constr(c)) => {
Ok(Value::Con(
Constant::ProtoPair(
Type::Integer, Type::Integer,
Type::List(Box::new(Type::Data)), Type::List(Rc::new(Type::Data)),
// TODO: handle other types of constructor tags // TODO: handle other types of constructor tags
Box::new(Constant::Integer(convert_tag_to_constr(c.tag as i128))), Rc::new(Constant::Integer(convert_tag_to_constr(c.tag as i128))),
Box::new(Constant::ProtoList( Rc::new(Constant::ProtoList(
Type::Data, Type::Data,
c.fields c.fields
.deref() .deref()
@ -767,103 +941,148 @@ impl DefaultFunction {
.map(|d| Constant::Data(d.clone())) .map(|d| Constant::Data(d.clone()))
.collect(), .collect(),
)), )),
))) )
.into(),
))
} }
v => Err(Error::DeserialisationError(
"UnConstrData".to_string(),
Value::Con(v.clone().into()),
)),
},
v => Err(Error::DeserialisationError( v => Err(Error::DeserialisationError(
"UnConstrData".to_string(), "UnConstrData".to_string(),
v.clone(), v.clone(),
)), )),
}, },
DefaultFunction::UnMapData => match &args[0] { DefaultFunction::UnMapData => match &args[0] {
Value::Con(Constant::Data(PlutusData::Map(m))) => { Value::Con(data) => match data.as_ref() {
Ok(Value::Con(Constant::ProtoList( Constant::Data(PlutusData::Map(m)) => Ok(Value::Con(
Type::Pair(Box::new(Type::Data), Box::new(Type::Data)), Constant::ProtoList(
Type::Pair(Rc::new(Type::Data), Rc::new(Type::Data)),
m.deref() m.deref()
.iter() .iter()
.map(|p| -> Constant { .map(|p| -> Constant {
Constant::ProtoPair( Constant::ProtoPair(
Type::Data, Type::Data,
Type::Data, Type::Data,
Box::new(Constant::Data(p.0.clone())), Rc::new(Constant::Data(p.0.clone())),
Box::new(Constant::Data(p.1.clone())), Rc::new(Constant::Data(p.1.clone())),
) )
}) })
.collect(), .collect(),
))) )
} .into(),
)),
v => Err(Error::DeserialisationError(
"UnMapData".to_string(),
Value::Con(v.clone().into()),
)),
},
v => Err(Error::DeserialisationError( v => Err(Error::DeserialisationError(
"UnMapData".to_string(), "UnMapData".to_string(),
v.clone(), v.clone(),
)), )),
}, },
DefaultFunction::UnListData => match &args[0] { DefaultFunction::UnListData => match &args[0] {
Value::Con(Constant::Data(PlutusData::Array(l))) => { Value::Con(data) => match data.as_ref() {
Ok(Value::Con(Constant::ProtoList( Constant::Data(PlutusData::Array(l)) => Ok(Value::Con(
Constant::ProtoList(
Type::Data, Type::Data,
l.deref() l.deref()
.iter() .iter()
.map(|d| Constant::Data(d.clone())) .map(|d| Constant::Data(d.clone()))
.collect(), .collect(),
))) )
} .into(),
)),
v => Err(Error::DeserialisationError(
"UnMapData".to_string(),
Value::Con(v.clone().into()),
)),
},
v => Err(Error::DeserialisationError( v => Err(Error::DeserialisationError(
"UnListData".to_string(), "UnListData".to_string(),
v.clone(), v.clone(),
)), )),
}, },
DefaultFunction::UnIData => match &args[0] { DefaultFunction::UnIData => match &args[0] {
Value::Con(Constant::Data(PlutusData::BigInt(b))) => { Value::Con(data) => match data.as_ref() {
Constant::Data(PlutusData::BigInt(b)) => {
if let BigInt::Int(i) = b { if let BigInt::Int(i) = b {
let x: i128 = (*i).try_into().unwrap(); let x: i128 = (*i).try_into().unwrap();
Ok(Value::Con(Constant::Integer(x))) Ok(Value::Con(Constant::Integer(x).into()))
} else { } else {
unreachable!() unreachable!()
} }
} }
v => Err(Error::DeserialisationError(
"UnMapData".to_string(),
Value::Con(v.clone().into()),
)),
},
v => Err(Error::DeserialisationError( v => Err(Error::DeserialisationError(
"UnIData".to_string(), "UnIData".to_string(),
v.clone(), v.clone(),
)), )),
}, },
DefaultFunction::UnBData => match &args[0] { DefaultFunction::UnBData => match &args[0] {
Value::Con(Constant::Data(PlutusData::BoundedBytes(b))) => { Value::Con(data) => match data.as_ref() {
Ok(Value::Con(Constant::ByteString(b.to_vec()))) Constant::Data(PlutusData::BoundedBytes(b)) => {
Ok(Value::Con(Constant::ByteString(b.to_vec()).into()))
} }
v => Err(Error::DeserialisationError(
"UnMapData".to_string(),
Value::Con(v.clone().into()),
)),
},
v => Err(Error::DeserialisationError( v => Err(Error::DeserialisationError(
"UnBData".to_string(), "UnBData".to_string(),
v.clone(), v.clone(),
)), )),
}, },
DefaultFunction::EqualsData => match (&args[0], &args[1]) { DefaultFunction::EqualsData => match (&args[0], &args[1]) {
(Value::Con(Constant::Data(d1)), Value::Con(Constant::Data(d2))) => { (Value::Con(data1), Value::Con(data2)) => match (data1.as_ref(), data2.as_ref()) {
Ok(Value::Con(Constant::Bool(d1.eq(d2)))) (Constant::Data(d1), Constant::Data(d2)) => {
Ok(Value::Con(Constant::Bool(d1.eq(d2)).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::SerialiseData => match &args[0] { DefaultFunction::SerialiseData => match &args[0] {
Value::Con(Constant::Data(d)) => { Value::Con(data) => match data.as_ref() {
Constant::Data(d) => {
let serialized_data = plutus_data_to_bytes(d).unwrap(); let serialized_data = plutus_data_to_bytes(d).unwrap();
Ok(Value::Con(Constant::ByteString(serialized_data))) Ok(Value::Con(Constant::ByteString(serialized_data).into()))
} }
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(),
},
DefaultFunction::MkPairData => match (&args[0], &args[1]) { DefaultFunction::MkPairData => match (&args[0], &args[1]) {
(Value::Con(Constant::Data(d1)), Value::Con(Constant::Data(d2))) => { (Value::Con(data1), Value::Con(data2)) => match (data1.as_ref(), data2.as_ref()) {
Ok(Value::Con(Constant::ProtoPair( (Constant::Data(d1), Constant::Data(d2)) => Ok(Value::Con(
Constant::ProtoPair(
Type::Data, Type::Data,
Type::Data, Type::Data,
Box::new(Constant::Data(d1.clone())), Rc::new(Constant::Data(d1.clone())),
Box::new(Constant::Data(d2.clone())), Rc::new(Constant::Data(d2.clone())),
))) )
} .into(),
)),
_ => unreachable!(), _ => unreachable!(),
}, },
DefaultFunction::MkNilData => Ok(Value::Con(Constant::ProtoList(Type::Data, vec![]))), _ => unreachable!(),
DefaultFunction::MkNilPairData => Ok(Value::Con(Constant::ProtoList( },
Type::Pair(Box::new(Type::Data), Box::new(Type::Data)), DefaultFunction::MkNilData => {
vec![], Ok(Value::Con(Constant::ProtoList(Type::Data, vec![]).into()))
))), }
DefaultFunction::MkNilPairData => Ok(Value::Con(
Constant::ProtoList(Type::Pair(Rc::new(Type::Data), Rc::new(Type::Data)), vec![])
.into(),
)),
} }
} }
} }

View File

@ -87,7 +87,7 @@ peg::parser! {
/ constant_list() / constant_list()
/ constant_pair() / constant_pair()
) _* ")" { ) _* ")" {
Term::Constant(con) Term::Constant(con.into())
} }
rule builtin() -> Term<Name> rule builtin() -> Term<Name>
@ -96,11 +96,11 @@ peg::parser! {
} }
rule var() -> Term<Name> rule var() -> Term<Name>
= n:name() { Term::Var(n) } = n:name() { Term::Var(n.into()) }
rule lambda() -> Term<Name> rule lambda() -> Term<Name>
= "(" _* "lam" _+ parameter_name:name() _+ t:term() _* ")" { = "(" _* "lam" _+ parameter_name:name() _+ t:term() _* ")" {
Term::Lambda { parameter_name, body: Rc::new(t) } Term::Lambda { parameter_name: parameter_name.into(), body: Rc::new(t) }
} }
#[cache_left_rec] #[cache_left_rec]
@ -148,7 +148,7 @@ peg::parser! {
rule constant_pair() -> Constant rule constant_pair() -> Constant
= "pair" _* "<" _* l:type_info() _* "," r:type_info() _* ">" _+ p:pair(Some((&l, &r))) { = "pair" _* "<" _* l:type_info() _* "," r:type_info() _* ">" _+ p:pair(Some((&l, &r))) {
Constant::ProtoPair(l, r, Box::new(p.0), Box::new(p.1)) Constant::ProtoPair(l, r, p.0.into(), p.1.into())
} }
rule pair(type_info: Option<(&Type, &Type)>) -> (Constant, Constant) rule pair(type_info: Option<(&Type, &Type)>) -> (Constant, Constant)
@ -218,13 +218,13 @@ peg::parser! {
} }
/ ls:list(list_sub_type(type_info)) {? / ls:list(list_sub_type(type_info)) {?
match type_info { match type_info {
Some(Type::List(t)) => Ok(Constant::ProtoList(*t.clone(), ls)), Some(Type::List(t)) => Ok(Constant::ProtoList(t.as_ref().clone(), ls)),
_ => Err("found 'List' instead of expected type") _ => Err("found 'List' instead of expected type")
} }
} }
/ p:pair(pair_sub_type(type_info)) {? / p:pair(pair_sub_type(type_info)) {?
match type_info { match type_info {
Some(Type::Pair(l, r)) => Ok(Constant::ProtoPair(*l.clone(), *r.clone(), Box::new(p.0), Box::new(p.1))), Some(Type::Pair(l, r)) => Ok(Constant::ProtoPair(l.as_ref().clone(), r.as_ref().clone(), p.0.into(), p.1.into())),
_ => Err("found 'Pair' instead of expected type") _ => Err("found 'Pair' instead of expected type")
} }
} }
@ -237,10 +237,10 @@ peg::parser! {
/ _* "string" { Type::String } / _* "string" { Type::String }
/ _* "data" { Type::Data } / _* "data" { Type::Data }
/ _* "list" _* "<" _* t:type_info() _* ">" { / _* "list" _* "<" _* t:type_info() _* ">" {
Type::List(Box::new(t)) Type::List(t.into())
} }
/ _* "pair" _* "<" l:type_info() "," r:type_info() ">" { / _* "pair" _* "<" l:type_info() "," r:type_info() ">" {
Type::Pair(Box::new(l), Box::new(r)) Type::Pair(l.into(), r.into())
} }
rule name() -> Name rule name() -> Name
@ -274,10 +274,10 @@ mod test {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Lambda { function: Rc::new(Term::Lambda {
parameter_name: x.clone(), parameter_name: x.clone().into(),
body: Rc::new(Term::Var(x)), body: Rc::new(Term::Var(x.into())),
}), }),
argument: Rc::new(Term::Constant(Constant::Integer(0))) argument: Rc::new(Term::Constant(Constant::Integer(0).into()))
} }
} }
) )
@ -295,8 +295,8 @@ mod test {
Program::<Name> { Program::<Name> {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Lambda { term: Term::Lambda {
parameter_name: x.clone(), parameter_name: x.clone().into(),
body: Rc::new(Term::Var(x)), body: Rc::new(Term::Var(x.into())),
} }
} }
) )
@ -314,8 +314,8 @@ mod test {
Program::<Name> { Program::<Name> {
version: (1, 0, 0), version: (1, 0, 0),
term: Term::Lambda { term: Term::Lambda {
parameter_name: x.clone(), parameter_name: x.clone().into(),
body: Rc::new(Term::Delay(Rc::new(Term::Var(x)))), body: Rc::new(Term::Delay(Rc::new(Term::Var(x.into())))),
} }
} }
) )
@ -344,7 +344,7 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (11, 22, 33), version: (11, 22, 33),
term: Term::Constant(Constant::Integer(11)), term: Term::Constant(Constant::Integer(11).into()),
} }
); );
} }
@ -469,9 +469,13 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::AppendByteString)), function: Rc::new(Term::Builtin(DefaultFunction::AppendByteString)),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xFF]))), argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xFF]).into()
)),
}), }),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0xFF, 0x00]))) argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0xFF, 0x00]).into()
))
} }
} }
) )
@ -488,9 +492,9 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::ConsByteString)), function: Rc::new(Term::Builtin(DefaultFunction::ConsByteString)),
argument: Rc::new(Term::Constant(Constant::Integer(256))), argument: Rc::new(Term::Constant(Constant::Integer(256).into())),
}), }),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![]))) argument: Rc::new(Term::Constant(Constant::ByteString(vec![]).into()))
} }
} }
) )
@ -507,11 +511,13 @@ mod test {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::SliceByteString)), function: Rc::new(Term::Builtin(DefaultFunction::SliceByteString)),
argument: Rc::new(Term::Constant(Constant::Integer(1))), argument: Rc::new(Term::Constant(Constant::Integer(1).into())),
}), }),
argument: Rc::new(Term::Constant(Constant::Integer(2))), argument: Rc::new(Term::Constant(Constant::Integer(2).into())),
}), }),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xFF, 0xAA]))) argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xFF, 0xAA]).into()
))
} }
} }
) )
@ -526,7 +532,9 @@ mod test {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::LengthOfByteString)), function: Rc::new(Term::Builtin(DefaultFunction::LengthOfByteString)),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xFF, 0xAA]))) argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xFF, 0xAA]).into()
))
}, },
} }
) )
@ -542,9 +550,11 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::IndexByteString)), function: Rc::new(Term::Builtin(DefaultFunction::IndexByteString)),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00]))) argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00]).into()))
}), }),
argument: Rc::new(Term::Constant(Constant::Integer(9223372036854775808))), argument: Rc::new(Term::Constant(
Constant::Integer(9223372036854775808).into()
)),
} }
} }
) )
@ -560,11 +570,13 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::EqualsByteString)), function: Rc::new(Term::Builtin(DefaultFunction::EqualsByteString)),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![ argument: Rc::new(Term::Constant(
0x00, 0xff, 0xaa Constant::ByteString(vec![0x00, 0xff, 0xaa]).into()
]))) ))
}), }),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xff, 0xaa]))), argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xff, 0xaa]).into()
)),
} }
} }
) )
@ -580,9 +592,13 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::LessThanByteString)), function: Rc::new(Term::Builtin(DefaultFunction::LessThanByteString)),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xff]))) argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xff]).into()
))
}), }),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xff, 0xaa]))), argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xff, 0xaa]).into()
)),
} }
} }
) )
@ -598,9 +614,11 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(DefaultFunction::LessThanEqualsByteString)), function: Rc::new(Term::Builtin(DefaultFunction::LessThanEqualsByteString)),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00, 0xff]))) argument: Rc::new(Term::Constant(
Constant::ByteString(vec![0x00, 0xff]).into()
))
}), }),
argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00]))), argument: Rc::new(Term::Constant(Constant::ByteString(vec![0x00]).into())),
} }
} }
) )
@ -613,7 +631,7 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoList(Type::Unit, vec![])) term: Term::Constant(Constant::ProtoList(Type::Unit, vec![]).into())
} }
) )
} }
@ -625,7 +643,7 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoList(Type::Unit, vec![Constant::Unit])) term: Term::Constant(Constant::ProtoList(Type::Unit, vec![Constant::Unit]).into())
} }
) )
} }
@ -637,14 +655,17 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoList( term: Term::Constant(
Constant::ProtoList(
Type::Bool, Type::Bool,
vec![ vec![
Constant::Bool(true), Constant::Bool(true),
Constant::Bool(false), Constant::Bool(false),
Constant::Bool(true) Constant::Bool(true)
] ]
)) )
.into()
)
} }
) )
} }
@ -656,13 +677,16 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoList( term: Term::Constant(
Constant::ProtoList(
Type::ByteString, Type::ByteString,
vec![ vec![
Constant::ByteString(vec![0x00]), Constant::ByteString(vec![0x00]),
Constant::ByteString(vec![0x01]), Constant::ByteString(vec![0x01]),
] ]
)) )
.into()
)
} }
) )
} }
@ -674,8 +698,9 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoList( term: Term::Constant(
Type::List(Box::new(Type::Integer)), Constant::ProtoList(
Type::List(Type::Integer.into()),
vec![ vec![
Constant::ProtoList( Constant::ProtoList(
Type::Integer, Type::Integer,
@ -683,7 +708,9 @@ mod test {
), ),
Constant::ProtoList(Type::Integer, vec![Constant::Integer(1337)]) Constant::ProtoList(Type::Integer, vec![Constant::Integer(1337)])
] ]
)) )
.into()
)
} }
) )
} }
@ -703,10 +730,13 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoList( term: Term::Constant(
Constant::ProtoList(
Type::Integer, Type::Integer,
vec![Constant::Integer(14), Constant::Integer(42)], vec![Constant::Integer(14), Constant::Integer(42)],
)) )
.into()
)
} }
) )
} }
@ -718,12 +748,15 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoPair( term: Term::Constant(
Constant::ProtoPair(
Type::Unit, Type::Unit,
Type::Unit, Type::Unit,
Box::new(Constant::Unit), Constant::Unit.into(),
Box::new(Constant::Unit) Constant::Unit.into()
)) )
.into()
)
} }
) )
} }
@ -735,17 +768,21 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoPair( term: Term::Constant(
Constant::ProtoPair(
Type::Bool, Type::Bool,
Type::Pair(Box::new(Type::Integer), Box::new(Type::ByteString)), Type::Pair(Type::Integer.into(), Type::ByteString.into()),
Box::new(Constant::Bool(true)), Constant::Bool(true).into(),
Box::new(Constant::ProtoPair( Constant::ProtoPair(
Type::Integer, Type::Integer,
Type::ByteString, Type::ByteString,
Box::new(Constant::Integer(14)), Constant::Integer(14).into(),
Box::new(Constant::ByteString(vec![0x42])), Constant::ByteString(vec![0x42]).into(),
)) )
)) .into()
)
.into()
)
} }
) )
} }
@ -757,15 +794,19 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoPair( term: Term::Constant(
Constant::ProtoPair(
Type::String, Type::String,
Type::List(Box::new(Type::Integer)), Type::List(Type::Integer.into()),
Box::new(Constant::String(String::from("foo"))), Constant::String(String::from("foo")).into(),
Box::new(Constant::ProtoList( Constant::ProtoList(
Type::Integer, Type::Integer,
vec![Constant::Integer(14), Constant::Integer(42)], vec![Constant::Integer(14), Constant::Integer(42)],
)) )
)) .into()
)
.into()
)
} }
) )
} }
@ -783,12 +824,15 @@ mod test {
super::program(uplc).unwrap(), super::program(uplc).unwrap(),
Program::<Name> { Program::<Name> {
version: (0, 0, 0), version: (0, 0, 0),
term: Term::Constant(Constant::ProtoPair( term: Term::Constant(
Constant::ProtoPair(
Type::Integer, Type::Integer,
Type::Integer, Type::Integer,
Box::new(Constant::Integer(14)), Constant::Integer(14).into(),
Box::new(Constant::Integer(42)) Constant::Integer(42).into()
)) )
.into()
)
} }
) )
} }
@ -815,9 +859,9 @@ mod test {
term: Term::Apply { term: Term::Apply {
function: Rc::new(Term::Apply { function: Rc::new(Term::Apply {
function: Rc::new(Term::Builtin(default_function)), function: Rc::new(Term::Builtin(default_function)),
argument: Rc::new(Term::Constant(Constant::Integer(x))), argument: Rc::new(Term::Constant(Constant::Integer(x).into())),
}), }),
argument: Rc::new(Term::Constant(Constant::Integer(y))) argument: Rc::new(Term::Constant(Constant::Integer(y).into()))
} }
} }
) )

View File

@ -27,12 +27,16 @@ impl Interner {
pub fn term(&mut self, term: &mut Term<Name>) { pub fn term(&mut self, term: &mut Term<Name>) {
match term { match term {
Term::Var(name) => name.unique = self.intern(&name.text), Term::Var(name) => {
let name = Rc::make_mut(name);
name.unique = self.intern(&name.text)
}
Term::Delay(term) => self.term(Rc::make_mut(term)), Term::Delay(term) => self.term(Rc::make_mut(term)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => { } => {
let parameter_name = Rc::make_mut(parameter_name);
parameter_name.unique = self.intern(&parameter_name.text); parameter_name.unique = self.intern(&parameter_name.text);
self.term(Rc::make_mut(body)); self.term(Rc::make_mut(body));
} }

View File

@ -3,27 +3,27 @@ use crate::program_builder::WithTerm;
pub trait WithConstant: WithTerm { pub trait WithConstant: WithTerm {
fn with_int(self, int: i128) -> Self::Next { fn with_int(self, int: i128) -> Self::Next {
let term = Term::Constant(Constant::Integer(int)); let term = Term::Constant(Constant::Integer(int).into());
self.next(term) self.next(term)
} }
fn with_byte_string(self, bytes: Vec<u8>) -> Self::Next { fn with_byte_string(self, bytes: Vec<u8>) -> Self::Next {
let term = Term::Constant(Constant::ByteString(bytes)); let term = Term::Constant(Constant::ByteString(bytes).into());
self.next(term) self.next(term)
} }
fn with_string(self, string: String) -> Self::Next { fn with_string(self, string: String) -> Self::Next {
let term = Term::Constant(Constant::String(string)); let term = Term::Constant(Constant::String(string).into());
self.next(term) self.next(term)
} }
fn with_unit(self) -> Self::Next { fn with_unit(self) -> Self::Next {
let term = Term::Constant(Constant::Unit); let term = Term::Constant(Constant::Unit.into());
self.next(term) self.next(term)
} }
fn with_bool(self, bool: bool) -> Self::Next { fn with_bool(self, bool: bool) -> Self::Next {
let term = Term::Constant(Constant::Bool(bool)); let term = Term::Constant(Constant::Bool(bool).into());
self.next(term) self.next(term)
} }
} }

View File

@ -13,7 +13,7 @@ impl<T: WithTerm> WithTerm for LambdaBuilder<T> {
fn next(self, term: Term<Name>) -> Self::Next { fn next(self, term: Term<Name>) -> Self::Next {
let term = Term::Lambda { let term = Term::Lambda {
parameter_name: self.parameter_name, parameter_name: self.parameter_name.into(),
body: Rc::new(term), body: Rc::new(term),
}; };
self.outer.next(term) self.outer.next(term)

View File

@ -4,7 +4,7 @@ use crate::program_builder::WithTerm;
pub trait WithVar: WithTerm { pub trait WithVar: WithTerm {
fn with_var(self, name_str: &str) -> Self::Next { fn with_var(self, name_str: &str) -> Self::Next {
let name = self.get_name(name_str); let name = self.get_name(name_str);
let term = Term::Var(name); let term = Term::Var(name.into());
self.next(term) self.next(term)
} }
} }

View File

@ -84,6 +84,6 @@
i_0 i_0
] ]
) )
(con integer 15) (con integer 0)
] ]
) )