diff --git a/crates/aiken-lang/src/builder.rs b/crates/aiken-lang/src/builder.rs index 39c2385b..2cc2e81e 100644 --- a/crates/aiken-lang/src/builder.rs +++ b/crates/aiken-lang/src/builder.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, sync::Arc}; +use std::{cell::RefCell, rc::Rc, sync::Arc}; use indexmap::{IndexMap, IndexSet}; use itertools::Itertools; @@ -186,7 +186,8 @@ pub fn convert_type_to_data(term: Term, field_type: &Arc) -> Term, field_type: &Arc) -> Term, field_type: &Arc) -> Term, field_type: &Arc) -> Term, field_type: &Arc) -> Term, field_type: &Arc) -> Term) { }); } -pub fn convert_constants_to_data(constants: Vec) -> Vec { +pub fn convert_constants_to_data(constants: Vec>) -> Vec { let mut new_constants = vec![]; for constant in constants { - let constant = match constant { + let constant = match constant.as_ref() { 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::Data(PlutusData::BoundedBytes(b.try_into().unwrap())) + UplcConstant::Data(PlutusData::BoundedBytes(b.clone().try_into().unwrap())) } UplcConstant::String(s) => UplcConstant::Data(PlutusData::BoundedBytes( s.as_bytes().to_vec().try_into().unwrap(), )), UplcConstant::Bool(b) => UplcConstant::Data(PlutusData::Constr(Constr { - tag: convert_constr_to_tag(b.into()), + tag: convert_constr_to_tag((*b).into()), any_constructor: None, fields: vec![], })), UplcConstant::ProtoList(_, constants) => { - let inner_constants = convert_constants_to_data(constants) - .into_iter() - .map(|constant| match constant { - UplcConstant::Data(d) => d, - _ => todo!(), - }) - .collect_vec(); + let inner_constants = + convert_constants_to_data(constants.iter().cloned().map(Rc::new).collect()) + .into_iter() + .map(|constant| match constant { + UplcConstant::Data(d) => d, + _ => todo!(), + }) + .collect_vec(); UplcConstant::Data(PlutusData::Array(inner_constants)) } 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) .into_iter() .map(|constant| match constant { @@ -980,7 +1033,7 @@ pub fn convert_constants_to_data(constants: Vec) -> Vec d, + d @ UplcConstant::Data(_) => d.clone(), _ => unreachable!(), }; new_constants.push(constant); @@ -997,14 +1050,18 @@ pub fn wrap_validator_args(term: Term, arguments: &[TypedArg]) -> Term, arguments: &[TypedArg]) -> Term CodeGenerator<'a> { Air::Int { value, .. } => { let integer = value.parse().unwrap(); - let term = Term::Constant(UplcConstant::Integer(integer)); + let term = Term::Constant(UplcConstant::Integer(integer).into()); arg_stack.push(term); } Air::String { value, .. } => { - let term = Term::Constant(UplcConstant::String(value)); + let term = Term::Constant(UplcConstant::String(value).into()); arg_stack.push(term); } Air::ByteArray { bytes, .. } => { - let term = Term::Constant(UplcConstant::ByteString(bytes)); + let term = Term::Constant(UplcConstant::ByteString(bytes).into()); arg_stack.push(term); } Air::Bool { value, .. } => { - let term = Term::Constant(UplcConstant::Bool(value)); + let term = Term::Constant(UplcConstant::Bool(value).into()); arg_stack.push(term); } Air::Var { @@ -3516,12 +3516,13 @@ impl<'a> CodeGenerator<'a> { .. } => { match &constructor.variant { - ValueConstructorVariant::LocalVariable { .. } => { - arg_stack.push(Term::Var(Name { + ValueConstructorVariant::LocalVariable { .. } => arg_stack.push(Term::Var( + Name { text: name, unique: 0.into(), - })) - } + } + .into(), + )), ValueConstructorVariant::ModuleConstant { .. } => { unreachable!() } @@ -3539,19 +3540,23 @@ impl<'a> CodeGenerator<'a> { format!("{func_name}{variant_name}") }; - arg_stack.push(Term::Var(Name { - text: name, - unique: 0.into(), - })); + arg_stack.push(Term::Var( + Name { + text: name, + unique: 0.into(), + } + .into(), + )); } ValueConstructorVariant::Record { name: constr_name, .. } => { if constructor.tipo.is_bool() { - arg_stack - .push(Term::Constant(UplcConstant::Bool(constr_name == "True"))); + arg_stack.push(Term::Constant( + UplcConstant::Bool(constr_name == "True").into(), + )); } else if constructor.tipo.is_void() { - arg_stack.push(Term::Constant(UplcConstant::Unit)); + arg_stack.push(Term::Constant(UplcConstant::Unit.into())); } else { let data_type = lookup_data_type_by_tipo( self.data_types.clone(), @@ -3566,15 +3571,17 @@ impl<'a> CodeGenerator<'a> { .find(|(_, x)| x.name == *constr_name) .unwrap(); - let fields = - Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])); + let fields = Term::Constant( + UplcConstant::ProtoList(UplcType::Data, vec![]).into(), + ); let term = apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::ConstrData), - Term::Constant(UplcConstant::Integer( - constr_index.try_into().unwrap(), - )), + Term::Constant( + UplcConstant::Integer(constr_index.try_into().unwrap()) + .into(), + ), ), fields, ); @@ -3585,7 +3592,7 @@ impl<'a> CodeGenerator<'a> { }; } Air::Void { .. } => { - arg_stack.push(Term::Constant(UplcConstant::Unit)); + arg_stack.push(Term::Constant(UplcConstant::Unit.into())); } Air::List { count, tipo, tail, .. @@ -3610,37 +3617,44 @@ impl<'a> CodeGenerator<'a> { let mut convert_keys = vec![]; let mut convert_values = vec![]; for constant in constants { - match constant { + match constant.as_ref() { UplcConstant::ProtoPair(_, _, fst, snd) => { - convert_keys.push(*fst); - convert_values.push(*snd); + convert_keys.push(fst.clone()); + convert_values.push(snd.clone()); } _ => unreachable!(), } } - convert_keys = convert_constants_to_data(convert_keys); - convert_values = convert_constants_to_data(convert_values); - Term::Constant(UplcConstant::ProtoList( - UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()), - convert_keys - .into_iter() - .zip(convert_values.into_iter()) - .map(|(key, value)| { - UplcConstant::ProtoPair( - UplcType::Data, - UplcType::Data, - key.into(), - value.into(), - ) - }) - .collect_vec(), - )) + let convert_keys = convert_constants_to_data(convert_keys); + let convert_values = convert_constants_to_data(convert_values); + + Term::Constant( + UplcConstant::ProtoList( + UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()), + convert_keys + .into_iter() + .zip(convert_values.into_iter()) + .map(|(key, value)| { + UplcConstant::ProtoPair( + UplcType::Data, + UplcType::Data, + key.into(), + value.into(), + ) + }) + .collect_vec(), + ) + .into(), + ) } else { - Term::Constant(UplcConstant::ProtoList( - UplcType::Data, - convert_constants_to_data(constants), - )) + Term::Constant( + UplcConstant::ProtoList( + UplcType::Data, + convert_constants_to_data(constants), + ) + .into(), + ) }; arg_stack.push(list); @@ -3648,12 +3662,15 @@ impl<'a> CodeGenerator<'a> { let mut term = if tail { arg_stack.pop().unwrap() } else if tipo.is_map() { - Term::Constant(UplcConstant::ProtoList( - UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()), - vec![], - )) + Term::Constant( + UplcConstant::ProtoList( + UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()), + vec![], + ) + .into(), + ) } else { - Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])) + Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]).into()) }; for arg in args.into_iter().rev() { @@ -3697,19 +3714,25 @@ impl<'a> CodeGenerator<'a> { let head_list = if tipo.is_map() { apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: format!("__list_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__list_{}", list_id), + unique: 0.into(), + } + .into(), + ), ) } else { convert_data_to_type( apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: format!("__list_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__list_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), &tipo.get_inner_types()[0], ) @@ -3727,13 +3750,15 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: format!("__list_{}", list_id), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: first_name.clone(), unique: 0.into(), - }, + } + .into(), body: apply_wrap( list_access_to_uplc( names, @@ -3746,10 +3771,13 @@ impl<'a> CodeGenerator<'a> { ), apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: format!("__list_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__list_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), ) .into(), @@ -3777,15 +3805,19 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: tail_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: tail_var, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_var, + unique: 0.into(), + } + .into(), + ), ), ); } @@ -3794,19 +3826,25 @@ impl<'a> CodeGenerator<'a> { let head_list = if tipo.is_map() { apply_wrap( Term::Force(Term::Builtin(DefaultFunction::HeadList).into()), - Term::Var(Name { - text: tail_var, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_var, + unique: 0.into(), + } + .into(), + ), ) } else { convert_data_to_type( apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: tail_var, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_var, + unique: 0.into(), + } + .into(), + ), ), &tipo.get_inner_types()[0], ) @@ -3816,7 +3854,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: head_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, head_list, @@ -3833,7 +3872,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: param.clone(), unique: 0.into(), - }, + } + .into(), body: term.into(), }; } @@ -3856,7 +3896,9 @@ impl<'a> CodeGenerator<'a> { let zero_arg_functions = self.zero_arg_functions.clone(); let mut anon_func = true; - if let Term::Var(Name { text, .. }) = term.clone() { + if let Term::Var(name) = term.clone() { + let text = &name.text; + for ( FunctionAccessKey { module_name, @@ -3869,7 +3911,7 @@ impl<'a> CodeGenerator<'a> { let name_module = format!("{module_name}_{function_name}{variant_name}"); let name = format!("{function_name}{variant_name}"); - if text == name || text == name_module { + if text == &name || text == &name_module { let mut term = self.uplc_code_gen(&mut ir.clone()); term = builder::constr_get_field(term); term = builder::constr_fields_exposer(term); @@ -3909,10 +3951,13 @@ impl<'a> CodeGenerator<'a> { term = apply_wrap( term, - Term::Var(Name { - text: format!("__arg_{}", id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__arg_{}", id), + unique: 0.into(), + } + .into(), + ), ); let inner_type = if matches!(func, DefaultFunction::SndPair) { @@ -3926,7 +3971,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: format!("__arg_{}", id), unique: 0.into(), - }, + } + .into(), body: term.into(), }; @@ -3957,12 +4003,16 @@ impl<'a> CodeGenerator<'a> { }; let term = match name { - BinOp::And => { - delayed_if_else(left, right, Term::Constant(UplcConstant::Bool(false))) - } - BinOp::Or => { - delayed_if_else(left, Term::Constant(UplcConstant::Bool(true)), right) - } + BinOp::And => delayed_if_else( + left, + right, + Term::Constant(UplcConstant::Bool(false).into()), + ), + BinOp::Or => delayed_if_else( + left, + Term::Constant(UplcConstant::Bool(true).into()), + right, + ), BinOp::Eq => { if tipo.is_bool() { @@ -3971,8 +4021,8 @@ impl<'a> CodeGenerator<'a> { right.clone(), if_else( right, - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ), ); arg_stack.push(term); @@ -4001,13 +4051,16 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::MkCons).force_wrap(), left, ), - Term::Constant(UplcConstant::ProtoList( - UplcType::Pair( - UplcType::Data.into(), - UplcType::Data.into(), - ), - vec![], - )), + Term::Constant( + UplcConstant::ProtoList( + UplcType::Pair( + UplcType::Data.into(), + UplcType::Data.into(), + ), + vec![], + ) + .into(), + ), ), ), ), @@ -4018,13 +4071,16 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::MkCons).force_wrap(), right, ), - Term::Constant(UplcConstant::ProtoList( - UplcType::Pair( - UplcType::Data.into(), - UplcType::Data.into(), - ), - vec![], - )), + Term::Constant( + UplcConstant::ProtoList( + UplcType::Pair( + UplcType::Data.into(), + UplcType::Data.into(), + ), + vec![], + ) + .into(), + ), ), ), ); @@ -4043,7 +4099,7 @@ impl<'a> CodeGenerator<'a> { arg_stack.push(term); return; } else if tipo.is_void() { - arg_stack.push(Term::Constant(UplcConstant::Bool(true))); + arg_stack.push(Term::Constant(UplcConstant::Bool(true).into())); return; } @@ -4055,8 +4111,8 @@ impl<'a> CodeGenerator<'a> { left, if_else( right.clone(), - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ), right, ); @@ -4071,8 +4127,8 @@ impl<'a> CodeGenerator<'a> { ), apply_wrap(DefaultFunction::MapData.into(), right), ), - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ); arg_stack.push(term); @@ -4090,13 +4146,16 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::MkCons).force_wrap(), left, ), - Term::Constant(UplcConstant::ProtoList( - UplcType::Pair( - UplcType::Data.into(), - UplcType::Data.into(), - ), - vec![], - )), + Term::Constant( + UplcConstant::ProtoList( + UplcType::Pair( + UplcType::Data.into(), + UplcType::Data.into(), + ), + vec![], + ) + .into(), + ), ), ), ), @@ -4107,21 +4166,24 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::MkCons).force_wrap(), right, ), - Term::Constant(UplcConstant::ProtoList( - UplcType::Pair( - UplcType::Data.into(), - UplcType::Data.into(), - ), - vec![], - )), + Term::Constant( + UplcConstant::ProtoList( + UplcType::Pair( + UplcType::Data.into(), + UplcType::Data.into(), + ), + vec![], + ) + .into(), + ), ), ), ); term = if_else( term, - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ); arg_stack.push(term); return; @@ -4134,21 +4196,21 @@ impl<'a> CodeGenerator<'a> { ), apply_wrap(DefaultFunction::ListData.into(), right), ), - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ); arg_stack.push(term); return; } else if tipo.is_void() { - arg_stack.push(Term::Constant(UplcConstant::Bool(false))); + arg_stack.push(Term::Constant(UplcConstant::Bool(false).into())); return; } if_else( apply_wrap(apply_wrap(default_builtin.into(), left), right), - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ) } BinOp::LtInt => apply_wrap( @@ -4211,7 +4273,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: param.clone(), unique: 0.into(), - }, + } + .into(), body: func_body.into(), }; } @@ -4222,7 +4285,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: func_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, func_body, @@ -4234,7 +4298,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: func_name.clone(), unique: 0.into(), - }, + } + .into(), body: func_body.into(), }; @@ -4243,24 +4308,32 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: func_name.clone(), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: func_name.clone(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, apply_wrap( - Term::Var(Name { - text: func_name.clone(), - unique: 0.into(), - }), - Term::Var(Name { - text: func_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: func_name.clone(), + unique: 0.into(), + } + .into(), + ), + Term::Var( + Name { + text: func_name, + unique: 0.into(), + } + .into(), + ), ), ) .into(), @@ -4281,7 +4354,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, arg, @@ -4304,9 +4378,12 @@ impl<'a> CodeGenerator<'a> { let error_term = apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::Trace).force_wrap(), - Term::Constant(UplcConstant::String( - "Asserted on incorrect constructor variant.".to_string(), - )), + Term::Constant( + UplcConstant::String( + "Asserted on incorrect constructor variant.".to_string(), + ) + .into(), + ), ), Term::Delay(Term::Error.into()), ) @@ -4316,7 +4393,7 @@ impl<'a> CodeGenerator<'a> { apply_wrap( apply_wrap( DefaultFunction::EqualsInteger.into(), - Term::Constant(UplcConstant::Integer(constr_index as i128)), + Term::Constant(UplcConstant::Integer(constr_index as i128).into()), ), constr_index_exposer(constr), ), @@ -4345,7 +4422,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: subject_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, subject, @@ -4356,7 +4434,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: subject_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, constr_index_exposer(subject), @@ -4383,29 +4462,42 @@ impl<'a> CodeGenerator<'a> { if tipo.is_bool() { if complex_clause { let other_clauses = term; - if matches!(clause, Term::Constant(UplcConstant::Bool(true))) { + if matches!(clause, Term::Constant(boolean ) if matches!(boolean.as_ref(), UplcConstant::Bool(true))) + { term = if_else( - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), Term::Delay(body.into()), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), ) .force_wrap(); } else { term = if_else( - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), Term::Delay(body.into()), ) .force_wrap(); @@ -4416,26 +4508,34 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: "__other_clauses_delayed".to_string(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, Term::Delay(other_clauses.into()), ); - } else if matches!(clause, Term::Constant(UplcConstant::Bool(true))) { + } else if matches!(clause, Term::Constant(boolean) if matches!(boolean.as_ref(), UplcConstant::Bool(true))) + { term = delayed_if_else( - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), body, term, ); } else { term = delayed_if_else( - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), term, body, ); @@ -4444,36 +4544,48 @@ impl<'a> CodeGenerator<'a> { let checker = if tipo.is_int() { apply_wrap( DefaultFunction::EqualsInteger.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) } else if tipo.is_bytearray() { apply_wrap( DefaultFunction::EqualsByteString.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) } else if tipo.is_string() { apply_wrap( DefaultFunction::EqualsString.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) } else if tipo.is_list() || tipo.is_tuple() { unreachable!() } else { apply_wrap( DefaultFunction::EqualsInteger.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) }; @@ -4483,14 +4595,18 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: "__other_clauses_delayed".to_string(), unique: 0.into(), - }, + } + .into(), body: if_else( apply_wrap(checker, clause), Term::Delay(body.into()), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), ) .force_wrap() .into(), @@ -4522,15 +4638,19 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: next_tail_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: tail_name.clone(), - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name.clone(), + unique: 0.into(), + } + .into(), + ), ), ) } else { @@ -4539,15 +4659,21 @@ impl<'a> CodeGenerator<'a> { if complex_clause { term = choose_list( - Term::Var(Name { - text: tail_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name, + unique: 0.into(), + } + .into(), + ), Term::Delay(body.into()), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), ) .force_wrap(); @@ -4556,17 +4682,21 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: "__other_clauses_delayed".into(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, Term::Delay(arg.into()), ); } else { term = delayed_choose_list( - Term::Var(Name { - text: tail_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name, + unique: 0.into(), + } + .into(), + ), body, arg, ); @@ -4586,7 +4716,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: "__other_clauses_delayed".into(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, Term::Delay(arg.into()), @@ -4601,26 +4732,36 @@ impl<'a> CodeGenerator<'a> { let then = arg_stack.pop().unwrap(); if tipo.is_bool() { - let mut term = Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }); - if matches!(condition, Term::Constant(UplcConstant::Bool(true))) { + let mut term = Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ); + if matches!(condition, Term::Constant(boolean) if matches!(boolean.as_ref(), UplcConstant::Bool(true))) + { term = if_else( - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), Term::Delay(then.into()), term, ) .force_wrap(); } else { term = if_else( - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), term, Term::Delay(then.into()), ) @@ -4631,46 +4772,61 @@ impl<'a> CodeGenerator<'a> { let checker = if tipo.is_int() { apply_wrap( DefaultFunction::EqualsInteger.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) } else if tipo.is_bytearray() { apply_wrap( DefaultFunction::EqualsByteString.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) } else if tipo.is_string() { apply_wrap( DefaultFunction::EqualsString.into(), - Term::Var(Name { - text: subject_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + ), ) } else if tipo.is_list() || tipo.is_tuple() { unreachable!() } else { apply_wrap( DefaultFunction::EqualsInteger.into(), - constr_index_exposer(Term::Var(Name { - text: subject_name, - unique: 0.into(), - })), + constr_index_exposer(Term::Var( + Name { + text: subject_name, + unique: 0.into(), + } + .into(), + )), ) }; let term = if_else( apply_wrap(checker, condition), Term::Delay(then.into()), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), ) .force_wrap(); arg_stack.push(term); @@ -4695,15 +4851,19 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: next_tail_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: tail_name.clone(), - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name.clone(), + unique: 0.into(), + } + .into(), + ), ), ) } else { @@ -4712,27 +4872,39 @@ impl<'a> CodeGenerator<'a> { if !inverse { term = choose_list( - Term::Var(Name { - text: tail_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name, + unique: 0.into(), + } + .into(), + ), Term::Delay(term.into()), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), ) .force_wrap(); } else { term = choose_list( - Term::Var(Name { - text: tail_name, - unique: 0.into(), - }), - Term::Var(Name { - text: "__other_clauses_delayed".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name, + unique: 0.into(), + } + .into(), + ), + Term::Var( + Name { + text: "__other_clauses_delayed".to_string(), + unique: 0.into(), + } + .into(), + ), Term::Delay(term.into()), ) .force_wrap(); @@ -4763,7 +4935,8 @@ impl<'a> CodeGenerator<'a> { arg_vec.push(arg_stack.pop().unwrap()); } - let mut term = Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])); + let mut term = + Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]).into()); for (index, arg) in arg_vec.iter().enumerate().rev() { term = apply_wrap( @@ -4778,7 +4951,7 @@ impl<'a> CodeGenerator<'a> { term = apply_wrap( apply_wrap( DefaultFunction::ConstrData.into(), - Term::Constant(UplcConstant::Integer(constr_index as i128)), + Term::Constant(UplcConstant::Integer(constr_index as i128).into()), ), term, ); @@ -4809,19 +4982,25 @@ impl<'a> CodeGenerator<'a> { let mut term = apply_wrap( apply_wrap( - Term::Var(Name { - text: CONSTR_GET_FIELD.to_string(), - unique: 0.into(), - }), - apply_wrap( - Term::Var(Name { - text: CONSTR_FIELDS_EXPOSER.to_string(), + Term::Var( + Name { + text: CONSTR_GET_FIELD.to_string(), unique: 0.into(), - }), + } + .into(), + ), + apply_wrap( + Term::Var( + Name { + text: CONSTR_FIELDS_EXPOSER.to_string(), + unique: 0.into(), + } + .into(), + ), constr, ), ), - Term::Constant(UplcConstant::Integer(record_index.into())), + Term::Constant(UplcConstant::Integer(record_index.into()).into()), ); term = convert_data_to_type(term, &tipo); @@ -4849,10 +5028,13 @@ impl<'a> CodeGenerator<'a> { let head_list = convert_data_to_type( apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: format!("__constr_fields_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__constr_fields_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), &first_name.2, ); @@ -4873,10 +5055,13 @@ impl<'a> CodeGenerator<'a> { ), apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: format!("__constr_fields_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__constr_fields_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), ) } else { @@ -4888,13 +5073,15 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: format!("__constr_fields_{}", list_id), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: first_name.1.clone(), unique: 0.into(), - }, + } + .into(), body: tail_list.into(), }, head_list, @@ -4902,10 +5089,13 @@ impl<'a> CodeGenerator<'a> { .into(), }, apply_wrap( - Term::Var(Name { - text: CONSTR_FIELDS_EXPOSER.to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: CONSTR_FIELDS_EXPOSER.to_string(), + unique: 0.into(), + } + .into(), + ), value, ), ); @@ -4932,16 +5122,20 @@ impl<'a> CodeGenerator<'a> { let data_constants = convert_constants_to_data(constants); if count == 2 { - let term = Term::Constant(UplcConstant::ProtoPair( - UplcType::Data, - UplcType::Data, - data_constants[0].clone().into(), - data_constants[1].clone().into(), - )); + let term = Term::Constant( + UplcConstant::ProtoPair( + UplcType::Data, + UplcType::Data, + data_constants[0].clone().into(), + data_constants[1].clone().into(), + ) + .into(), + ); arg_stack.push(term); } else { - let term = - Term::Constant(UplcConstant::ProtoList(UplcType::Data, data_constants)); + let term = Term::Constant( + UplcConstant::ProtoList(UplcType::Data, data_constants).into(), + ); arg_stack.push(term); } } else if count == 2 { @@ -4954,7 +5148,8 @@ impl<'a> CodeGenerator<'a> { ); arg_stack.push(term); } else { - let mut term = Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])); + let mut term = + Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]).into()); for (arg, tipo) in args.into_iter().zip(tuple_sub_types.into_iter()).rev() { term = apply_wrap( apply_wrap( @@ -4971,9 +5166,12 @@ impl<'a> CodeGenerator<'a> { let term = apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::Trace).force_wrap(), - Term::Constant(UplcConstant::String( - label.unwrap_or_else(|| "aiken::todo".to_string()), - )), + Term::Constant( + UplcConstant::String( + label.unwrap_or_else(|| "aiken::todo".to_string()), + ) + .into(), + ), ), Term::Delay(Term::Error.into()), ) @@ -5011,10 +5209,13 @@ impl<'a> CodeGenerator<'a> { let mut term = apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: format!("{tail_name_prefix}_{highest_index}"), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("{tail_name_prefix}_{highest_index}"), + unique: 0.into(), + } + .into(), + ), ); for current_index in (0..(highest_index + 1)).rev() { @@ -5034,10 +5235,13 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::MkCons).force_wrap(), apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: tail_name, - unique: 0.into(), - }), + Term::Var( + Name { + text: tail_name, + unique: 0.into(), + } + .into(), + ), ), ), term, @@ -5048,7 +5252,7 @@ impl<'a> CodeGenerator<'a> { term = apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::ConstrData), - Term::Constant(UplcConstant::Integer(0)), + Term::Constant(UplcConstant::Integer(0).into()), ), term, ); @@ -5059,10 +5263,13 @@ impl<'a> CodeGenerator<'a> { let tail_name = format!("{tail_name_prefix}_{}", prev_index); let prev_tail_name = format!("{tail_name_prefix}_{index}"); - let mut tail_list = Term::Var(Name { - text: prev_tail_name, - unique: 0.into(), - }); + let mut tail_list = Term::Var( + Name { + text: prev_tail_name, + unique: 0.into(), + } + .into(), + ); if index < prev_index { for _ in index..prev_index { @@ -5077,7 +5284,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: tail_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, tail_list, @@ -5089,10 +5297,13 @@ impl<'a> CodeGenerator<'a> { let tail_name = format!("{tail_name_prefix}_{prev_index}"); let prev_tail_name = format!("{tail_name_prefix}_0"); - let mut tail_list = Term::Var(Name { - text: prev_tail_name.clone(), - unique: 0.into(), - }); + let mut tail_list = Term::Var( + Name { + text: prev_tail_name.clone(), + unique: 0.into(), + } + .into(), + ); for _ in 0..prev_index { tail_list = apply_wrap( @@ -5106,7 +5317,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: tail_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, tail_list, @@ -5119,14 +5331,18 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: prev_tail_name, unique: 0.into(), - }, + } + .into(), body: term.into(), }, apply_wrap( - Term::Var(Name { - text: CONSTR_FIELDS_EXPOSER.to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: CONSTR_FIELDS_EXPOSER.to_string(), + unique: 0.into(), + } + .into(), + ), record, ), ); @@ -5138,13 +5354,13 @@ impl<'a> CodeGenerator<'a> { let term = match op { UnOp::Not => if_else( value, - Term::Constant(UplcConstant::Bool(false)), - Term::Constant(UplcConstant::Bool(true)), + Term::Constant(UplcConstant::Bool(false).into()), + Term::Constant(UplcConstant::Bool(true).into()), ), UnOp::Negate => apply_wrap( apply_wrap( DefaultFunction::SubtractInteger.into(), - Term::Constant(UplcConstant::Integer(0)), + Term::Constant(UplcConstant::Integer(0).into()), ), value, ), @@ -5183,13 +5399,16 @@ impl<'a> CodeGenerator<'a> { self.needs_field_access = true; term = apply_wrap( apply_wrap( - Term::Var(Name { - text: CONSTR_GET_FIELD.to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: CONSTR_GET_FIELD.to_string(), + unique: 0.into(), + } + .into(), + ), term, ), - Term::Constant(UplcConstant::Integer(tuple_index as i128)), + Term::Constant(UplcConstant::Integer(tuple_index as i128).into()), ); } @@ -5212,19 +5431,22 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: format!("__tuple_{}", list_id), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: names[0].clone(), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: names[1].clone(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, convert_data_to_type( @@ -5232,10 +5454,13 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::SndPair) .force_wrap() .force_wrap(), - Term::Var(Name { - text: format!("__tuple_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__tuple_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), &inner_types[1], ), @@ -5247,10 +5472,13 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::FstPair) .force_wrap() .force_wrap(), - Term::Var(Name { - text: format!("__tuple_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__tuple_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), &inner_types[0], ), @@ -5272,10 +5500,13 @@ impl<'a> CodeGenerator<'a> { let head_list = convert_data_to_type( apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: format!("__tuple_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__tuple_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), &tipo.get_inner_types()[0], ); @@ -5285,13 +5516,15 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: format!("__tuple_{}", list_id), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: first_name.clone(), unique: 0.into(), - }, + } + .into(), body: apply_wrap( list_access_to_uplc( names, @@ -5304,10 +5537,13 @@ impl<'a> CodeGenerator<'a> { ), apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: format!("__tuple_{}", list_id), - unique: 0.into(), - }), + Term::Var( + Name { + text: format!("__tuple_{}", list_id), + unique: 0.into(), + } + .into(), + ), ), ) .into(), @@ -5328,9 +5564,12 @@ impl<'a> CodeGenerator<'a> { let term = apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::Trace).force_wrap(), - Term::Constant(UplcConstant::String( - text.unwrap_or_else(|| "aiken::trace".to_string()), - )), + Term::Constant( + UplcConstant::String( + text.unwrap_or_else(|| "aiken::trace".to_string()), + ) + .into(), + ), ), term, ); @@ -5342,7 +5581,7 @@ impl<'a> CodeGenerator<'a> { let term = apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::Trace).force_wrap(), - Term::Constant(UplcConstant::String(label)), + Term::Constant(UplcConstant::String(label).into()), ), Term::Delay(Term::Error.into()), ) @@ -5372,7 +5611,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: "__other_clauses_delayed".to_string(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, Term::Delay(next_clause.into()), @@ -5387,7 +5627,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: name.clone(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, convert_data_to_type( @@ -5395,10 +5636,13 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::FstPair) .force_wrap() .force_wrap(), - Term::Var(Name { - text: subject_name.clone(), - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name.clone(), + unique: 0.into(), + } + .into(), + ), ), &tuple_types[*index].clone(), ), @@ -5409,7 +5653,8 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: name.clone(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, convert_data_to_type( @@ -5417,10 +5662,13 @@ impl<'a> CodeGenerator<'a> { Term::Builtin(DefaultFunction::SndPair) .force_wrap() .force_wrap(), - Term::Var(Name { - text: subject_name.clone(), - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name.clone(), + unique: 0.into(), + } + .into(), + ), ), &tuple_types[*index].clone(), ), @@ -5434,17 +5682,21 @@ impl<'a> CodeGenerator<'a> { parameter_name: Name { text: name.clone(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, convert_data_to_type( apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), repeat_tail_list( - Term::Var(Name { - text: subject_name.clone(), - unique: 0.into(), - }), + Term::Var( + Name { + text: subject_name.clone(), + unique: 0.into(), + } + .into(), + ), *index, ), ), diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index 00ecc293..ae14e46f 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -655,7 +655,7 @@ where .map(|script| match script.program.eval(initial_budget) { (Ok(result), remaining_budget, logs) => EvalInfo { success: result != Term::Error - && result != Term::Constant(Constant::Bool(false)), + && result != Term::Constant(Constant::Bool(false).into()), script, spent_budget: initial_budget - remaining_budget, output: Some(result), diff --git a/crates/uplc/src/ast.rs b/crates/uplc/src/ast.rs index 867dd128..e3b1a95a 100644 --- a/crates/uplc/src/ast.rs +++ b/crates/uplc/src/ast.rs @@ -74,7 +74,7 @@ where pub fn apply_data(&self, plutus_data: PlutusData) -> Self { let applied_term = Term::Apply { 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 { @@ -239,7 +239,7 @@ pub enum Constant { // tag: 5 ProtoList(Type, Vec), // tag: 6 - ProtoPair(Type, Type, Box, Box), + ProtoPair(Type, Type, Rc, Rc), // tag: 7 // Apply(Box, Type), // tag: 8 @@ -253,8 +253,8 @@ pub enum Type { String, ByteString, Unit, - List(Box), - Pair(Box, Box), + List(Rc), + Pair(Rc, Rc), Data, } diff --git a/crates/uplc/src/ast/builder.rs b/crates/uplc/src/ast/builder.rs index 1b11d16f..ea8e9274 100644 --- a/crates/uplc/src/ast/builder.rs +++ b/crates/uplc/src/ast/builder.rs @@ -23,7 +23,7 @@ pub fn final_wrapper(term: Term) -> Term { argument: term.into(), } .into(), - argument: Term::Delay(Term::Constant(Constant::Unit).into()).into(), + argument: Term::Delay(Term::Constant(Constant::Unit.into()).into()).into(), } .into(), argument: Term::Delay(Term::Error.into()).into(), @@ -38,24 +38,32 @@ pub fn assert_on_list(term: Term) -> Term { parameter_name: Name { text: ASSERT_ON_LIST.to_string(), unique: 0.into(), - }, + } + .into(), body: apply_wrap( Term::Lambda { parameter_name: Name { text: ASSERT_ON_LIST.to_string(), unique: 0.into(), - }, + } + .into(), body: term.into(), }, apply_wrap( - Term::Var(Name { - text: ASSERT_ON_LIST.to_string(), - unique: 0.into(), - }), - Term::Var(Name { - text: ASSERT_ON_LIST.to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: ASSERT_ON_LIST.to_string(), + unique: 0.into(), + } + .into(), + ), + Term::Var( + Name { + text: ASSERT_ON_LIST.to_string(), + unique: 0.into(), + } + .into(), + ), ), ) .into(), @@ -64,64 +72,88 @@ pub fn assert_on_list(term: Term) -> Term { parameter_name: Name { text: ASSERT_ON_LIST.to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Lambda { parameter_name: Name { text: "list_to_check".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Lambda { parameter_name: Name { text: "check_with".to_string(), unique: 0.into(), - }, + } + .into(), body: delayed_choose_list( - Term::Var(Name { - text: "list_to_check".to_string(), - unique: 0.into(), - }), - Term::Constant(Constant::Unit), + Term::Var( + Name { + text: "list_to_check".to_string(), + unique: 0.into(), + } + .into(), + ), + Term::Constant(Constant::Unit.into()), apply_wrap( apply_wrap( Term::Builtin(DefaultFunction::ChooseUnit).force_wrap(), apply_wrap( - Term::Var(Name { - text: "check_with".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "check_with".to_string(), + unique: 0.into(), + } + .into(), + ), apply_wrap( Term::Builtin(DefaultFunction::HeadList).force_wrap(), - Term::Var(Name { - text: "list_to_check".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "list_to_check".to_string(), + unique: 0.into(), + } + .into(), + ), ), ), ), apply_wrap( apply_wrap( apply_wrap( - Term::Var(Name { - text: ASSERT_ON_LIST.to_string(), - unique: 0.into(), - }), - Term::Var(Name { - text: ASSERT_ON_LIST.to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: ASSERT_ON_LIST.to_string(), + unique: 0.into(), + } + .into(), + ), + Term::Var( + Name { + text: ASSERT_ON_LIST.to_string(), + unique: 0.into(), + } + .into(), + ), ), apply_wrap( Term::Builtin(DefaultFunction::TailList).force_wrap(), - Term::Var(Name { - text: "list_to_check".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "list_to_check".to_string(), + unique: 0.into(), + } + .into(), + ), ), ), - Term::Var(Name { - text: "check_with".to_string(), - unique: 0.into(), - }), + Term::Var( + Name { + text: "check_with".to_string(), + unique: 0.into(), + } + .into(), + ), ), ), ) @@ -140,7 +172,8 @@ pub fn constr_fields_exposer(term: Term) -> Term { parameter_name: Name { text: CONSTR_FIELDS_EXPOSER.to_string(), unique: 0.into(), - }, + } + .into(), body: term.into(), } .into(), @@ -148,7 +181,8 @@ pub fn constr_fields_exposer(term: Term) -> Term { parameter_name: Name { text: "__constr_var".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Apply { function: Term::Force( Term::Force(Term::Builtin(DefaultFunction::SndPair).into()).into(), @@ -156,10 +190,13 @@ pub fn constr_fields_exposer(term: Term) -> Term { .into(), argument: Term::Apply { function: Term::Builtin(DefaultFunction::UnConstrData).into(), - argument: Term::Var(Name { - text: "__constr_var".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__constr_var".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), @@ -188,7 +225,8 @@ pub fn constr_get_field(term: Term) -> Term { parameter_name: Name { text: CONSTR_GET_FIELD.to_string(), unique: 0.into(), - }, + } + .into(), body: term.into(), } .into(), @@ -196,42 +234,54 @@ pub fn constr_get_field(term: Term) -> Term { parameter_name: Name { text: "__constr_list".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Lambda { parameter_name: Name { text: "__arg_number".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Apply { function: Term::Lambda { parameter_name: Name { text: "__recurse".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Apply { function: Term::Apply { function: Term::Apply { - function: Term::Var(Name { - text: "__recurse".to_string(), - unique: 0.into(), - }) + function: Term::Var( + Name { + text: "__recurse".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), - argument: Term::Var(Name { - text: "__recurse".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__recurse".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), // 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(), - argument: Term::Var(Name { - text: "__constr_list".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__constr_list".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), @@ -242,17 +292,20 @@ pub fn constr_get_field(term: Term) -> Term { parameter_name: Name { text: "__self_recursor".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Lambda { parameter_name: Name { text: "__current_arg_number".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Lambda { parameter_name: Name { text: "__list_of_constr_args".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Apply { function: Term::Apply { function: Term::Apply { @@ -268,17 +321,24 @@ pub fn constr_get_field(term: Term) -> Term { DefaultFunction::EqualsInteger, ) .into(), - argument: Term::Var(Name { - text: "__arg_number".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__arg_number".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), - argument: Term::Var(Name { - text: "__current_arg_number".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__current_arg_number" + .to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), @@ -294,19 +354,26 @@ pub fn constr_get_field(term: Term) -> Term { parameter_name: Name { text: "__current_list_of_constr_args".to_string(), unique: 0.into(), - }, + } + .into(), body: Term::Apply { function: Term::Apply { function: Term::Apply { - function: Term::Var(Name { - text: "__self_recursor".to_string(), - unique: 0.into(), - }) + function: Term::Var( + Name { + text: "__self_recursor".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), - argument: Term::Var(Name { - text: "__self_recursor".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__self_recursor".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), @@ -317,16 +384,19 @@ pub fn constr_get_field(term: Term) -> Term { DefaultFunction::AddInteger, ) .into(), - argument: Term::Var(Name { - text: "__current_arg_number" - .to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__current_arg_number" + .to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), argument: Term::Constant( - Constant::Integer(1.into()), + Constant::Integer(1.into()).into(), ) .into(), } @@ -341,11 +411,14 @@ pub fn constr_get_field(term: Term) -> Term { ) .into(), - argument: Term::Var(Name { - text: "__current_list_of_constr_args" - .to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__current_list_of_constr_args" + .to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), @@ -355,10 +428,13 @@ pub fn constr_get_field(term: Term) -> Term { .into(), } .into(), - argument: Term::Var(Name { - text: "__list_of_constr_args".to_string(), - unique: 0.into(), - }) + argument: Term::Var( + Name { + text: "__list_of_constr_args".to_string(), + unique: 0.into(), + } + .into(), + ) .into(), } .into(), diff --git a/crates/uplc/src/debruijn.rs b/crates/uplc/src/debruijn.rs index 90b23346..4bd8ef18 100644 --- a/crates/uplc/src/debruijn.rs +++ b/crates/uplc/src/debruijn.rs @@ -37,10 +37,13 @@ impl Converter { term: &Term, ) -> Result, Error> { let converted_term = match term { - Term::Var(name) => Term::Var(NamedDeBruijn { - text: name.text.to_string(), - index: self.get_index(name)?, - }), + Term::Var(name) => Term::Var( + NamedDeBruijn { + text: name.text.to_string(), + index: self.get_index(name)?, + } + .into(), + ), Term::Delay(term) => Term::Delay(Rc::new(self.name_to_named_debruijn(term)?)), Term::Lambda { parameter_name, @@ -64,7 +67,7 @@ impl Converter { self.remove_unique(parameter_name.unique); Term::Lambda { - parameter_name: name, + parameter_name: name.into(), body: Rc::new(body), } } @@ -83,7 +86,7 @@ impl Converter { pub fn name_to_debruijn(&mut self, term: &Term) -> Result, Error> { 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::Lambda { parameter_name, @@ -102,7 +105,7 @@ impl Converter { self.remove_unique(parameter_name.unique); Term::Lambda { - parameter_name: name, + parameter_name: name.into(), body: Rc::new(body), } } @@ -124,10 +127,13 @@ impl Converter { term: &Term, ) -> Result, Error> { let converted_term = match term { - Term::Var(NamedDeBruijn { text, index }) => Term::Var(Name { - text: text.to_string(), - unique: self.get_unique(*index)?, - }), + Term::Var(var_name) => Term::Var( + Name { + 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::Lambda { parameter_name, @@ -135,7 +141,7 @@ impl Converter { } => { self.declare_binder(); - let unique = self.get_unique(parameter_name.index)?; + let unique = self.get_unique(¶meter_name.index)?; let name = Name { text: parameter_name.text.to_string(), @@ -149,7 +155,7 @@ impl Converter { self.end_scope(); Term::Lambda { - parameter_name: name, + parameter_name: name.into(), body: Rc::new(body), } } @@ -169,12 +175,15 @@ impl Converter { pub fn debruijn_to_name(&mut self, term: &Term) -> Result, Error> { let converted_term = match term { Term::Var(index) => { - let unique = self.get_unique(*index)?; + let unique = self.get_unique(index)?; - Term::Var(Name { - text: format!("i_{}", unique), - unique, - }) + Term::Var( + Name { + text: format!("i_{}", unique), + unique, + } + .into(), + ) } Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_name(term)?)), Term::Lambda { @@ -183,7 +192,7 @@ impl Converter { } => { self.declare_binder(); - let unique = self.get_unique(*parameter_name)?; + let unique = self.get_unique(parameter_name)?; let name = Name { text: format!("i_{}", unique), @@ -197,7 +206,7 @@ impl Converter { self.end_scope(); Term::Lambda { - parameter_name: name, + parameter_name: name.into(), body: Rc::new(body), } } @@ -217,13 +226,13 @@ impl Converter { #[allow(clippy::only_used_in_recursion)] pub fn named_debruijn_to_debruijn(&mut self, term: &Term) -> 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::Lambda { parameter_name, body, } => Term::Lambda { - parameter_name: parameter_name.clone().into(), + parameter_name: parameter_name.index.into(), body: Rc::new(self.named_debruijn_to_debruijn(body)), }, Term::Apply { function, argument } => Term::Apply { @@ -240,13 +249,19 @@ impl Converter { #[allow(clippy::only_used_in_recursion)] pub fn debruijn_to_named_debruijn(&mut self, term: &Term) -> 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::Lambda { parameter_name, body, } => 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)), }, Term::Apply { function, argument } => Term::Apply { @@ -266,7 +281,7 @@ impl Converter { term: &Term, ) -> 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(Rc::new(self.fake_named_debruijn_to_named_debruijn(term))) } @@ -274,7 +289,7 @@ impl Converter { parameter_name, body, } => 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)), }, Term::Apply { function, argument } => Term::Apply { @@ -296,7 +311,7 @@ impl Converter { term: &Term, ) -> 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(Rc::new(self.named_debruijn_to_fake_named_debruijn(term))) } @@ -304,7 +319,7 @@ impl Converter { parameter_name, body, } => 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)), }, Term::Apply { function, argument } => Term::Apply { @@ -332,7 +347,7 @@ impl Converter { Err(Error::FreeUnique(name.clone())) } - fn get_unique(&mut self, index: DeBruijn) -> Result { + fn get_unique(&mut self, index: &DeBruijn) -> Result { for scope in self.levels.iter().rev() { 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) { diff --git a/crates/uplc/src/flat.rs b/crates/uplc/src/flat.rs index e0d70941..271d2ab2 100644 --- a/crates/uplc/src/flat.rs +++ b/crates/uplc/src/flat.rs @@ -179,10 +179,10 @@ where { fn decode(d: &mut Decoder) -> Result { 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)?))), 2 => Ok(Term::Lambda { - parameter_name: T::binder_decode(d)?, + parameter_name: T::binder_decode(d)?.into(), body: Rc::new(Term::decode(d)?), }), 3 => Ok(Term::Apply { @@ -190,7 +190,7 @@ where argument: Rc::new(Term::decode(d)?), }), // 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)?))), 6 => Ok(Term::Error), 7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)), @@ -228,7 +228,7 @@ where match var_option { Ok(var) => { state_log.push(format!("{})", var.text())); - Ok(Term::Var(var)) + Ok(Term::Var(var.into())) } Err(error) => { state_log.push("parse error)".to_string()); @@ -263,7 +263,7 @@ where Ok(term) => { state_log.push(")".to_string()); Ok(Term::Lambda { - parameter_name: var, + parameter_name: var.into(), body: Rc::new(term), }) } @@ -315,7 +315,7 @@ where match con_option { Ok(constant) => { state_log.push(format!("{})", constant.to_pretty())); - Ok(Term::Constant(constant)) + Ok(Term::Constant(constant.into())) } Err(error) => { state_log.push("parse error)".to_string()); @@ -502,7 +502,7 @@ impl<'b> Decode<'b> for Constant { let typ = decode_type(&mut rest)?; let list: Vec = - 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)) } @@ -512,10 +512,10 @@ impl<'b> Decode<'b> for Constant { let type1 = decode_type(&mut rest)?; let type2 = decode_type(&mut rest)?; - let a = decode_constant_value(type1.clone(), d)?; - let b = decode_constant_value(type2.clone(), d)?; + let a = decode_constant_value(type1.clone().into(), 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] => { let cbor = Vec::::decode(d)?; @@ -533,8 +533,8 @@ impl<'b> Decode<'b> for Constant { } } -fn decode_constant_value(typ: Type, d: &mut Decoder) -> Result { - match typ { +fn decode_constant_value(typ: Rc, d: &mut Decoder) -> Result { + match typ.as_ref() { Type::Integer => Ok(Constant::Integer(i128::decode(d)?)), Type::ByteString => Ok(Constant::ByteString(Vec::::decode(d)?)), Type::String => Ok(Constant::String(String::decode(d)?)), @@ -542,19 +542,19 @@ fn decode_constant_value(typ: Type, d: &mut Decoder) -> Result Ok(Constant::Bool(bool::decode(d)?)), Type::List(sub_type) => { let list: Vec = - 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) => { - let a = decode_constant_value(*type1.clone(), d)?; - let b = decode_constant_value(*type2.clone(), d)?; + let a = decode_constant_value(type1.clone(), d)?; + let b = decode_constant_value(type2.clone(), d)?; Ok(Constant::ProtoPair( - *type1, - *type2, - Box::new(a), - Box::new(b), + type1.as_ref().clone(), + type2.as_ref().clone(), + a.into(), + b.into(), )) } Type::Data => { @@ -577,13 +577,13 @@ fn decode_type(types: &mut VecDeque) -> Result { Some(3) => Ok(Type::Unit), Some(8) => Ok(Type::Data), 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(6) => { let type1 = 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!( "Unknown constant type tag: {}", @@ -818,7 +818,7 @@ mod test { fn flat_encode_integer() { let program = Program:: { version: (11, 22, 33), - term: Term::Constant(Constant::Integer(11)), + term: Term::Constant(Constant::Integer(11).into()), }; let expected_bytes = vec![ @@ -834,13 +834,16 @@ mod test { fn flat_encode_list_list_integer() { let program = Program:: { version: (1, 0, 0), - term: Term::Constant(Constant::ProtoList( - Type::List(Box::new(Type::Integer)), - vec![ - Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]), - Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]), - ], - )), + term: Term::Constant( + Constant::ProtoList( + Type::List(Type::Integer.into()), + vec![ + Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]), + Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]), + ], + ) + .into(), + ), }; let expected_bytes = vec![ @@ -857,17 +860,21 @@ mod test { fn flat_encode_pair_pair_integer_bool_integer() { let program = Program:: { version: (1, 0, 0), - term: Term::Constant(Constant::ProtoPair( - Type::Pair(Box::new(Type::Integer), Box::new(Type::Bool)), - Type::Integer, - Box::new(Constant::ProtoPair( + term: Term::Constant( + Constant::ProtoPair( + Type::Pair(Type::Integer.into(), Type::Bool.into()), Type::Integer, - Type::Bool, - Box::new(Constant::Integer(11)), - Box::new(Constant::Bool(true)), - )), - Box::new(Constant::Integer(11)), - )), + Constant::ProtoPair( + Type::Integer, + Type::Bool, + Constant::Integer(11).into(), + Constant::Bool(true).into(), + ) + .into(), + Constant::Integer(11).into(), + ) + .into(), + ), }; let expected_bytes = vec![ @@ -889,13 +896,16 @@ mod test { let expected_program = Program:: { version: (1, 0, 0), - term: Term::Constant(Constant::ProtoList( - Type::List(Box::new(Type::Integer)), - vec![ - Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]), - Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]), - ], - )), + term: Term::Constant( + Constant::ProtoList( + Type::List(Type::Integer.into()), + vec![ + Constant::ProtoList(Type::Integer, vec![Constant::Integer(7)]), + Constant::ProtoList(Type::Integer, vec![Constant::Integer(5)]), + ], + ) + .into(), + ), }; let actual_program: Program = Program::unflat(&bytes).unwrap(); @@ -912,17 +922,21 @@ mod test { let expected_program = Program:: { version: (1, 0, 0), - term: Term::Constant(Constant::ProtoPair( - Type::Pair(Box::new(Type::Integer), Box::new(Type::Bool)), - Type::Integer, - Box::new(Constant::ProtoPair( + term: Term::Constant( + Constant::ProtoPair( + Type::Pair(Type::Integer.into(), Type::Bool.into()), Type::Integer, - Type::Bool, - Box::new(Constant::Integer(11)), - Box::new(Constant::Bool(true)), - )), - Box::new(Constant::Integer(11)), - )), + Constant::ProtoPair( + Type::Integer, + Type::Bool, + Constant::Integer(11).into(), + Constant::Bool(true).into(), + ) + .into(), + Constant::Integer(11).into(), + ) + .into(), + ), }; let actual_program: Program = Program::unflat(&bytes).unwrap(); @@ -938,7 +952,7 @@ mod test { let expected_program = Program { version: (11, 22, 33), - term: Term::Constant(Constant::Integer(11)), + term: Term::Constant(Constant::Integer(11).into()), }; let actual_program: Program = Program::unflat(&bytes).unwrap(); diff --git a/crates/uplc/src/machine.rs b/crates/uplc/src/machine.rs index 899c3ead..e7e59976 100644 --- a/crates/uplc/src/machine.rs +++ b/crates/uplc/src/machine.rs @@ -39,7 +39,7 @@ enum PartialTerm { // tag: 1 Delay, // tag: 2 - Lambda(NamedDeBruijn), + Lambda(Rc), // tag: 3 Apply, // tag: 4 @@ -330,7 +330,7 @@ impl Machine { fn lookup_var(&mut self, name: &NamedDeBruijn, env: Rc>) -> Result { env.get::(env.len() - usize::from(name.index)) .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> { @@ -398,10 +398,7 @@ fn discharge_value(value: Value) -> Rc> { 0, env, Term::Lambda { - parameter_name: NamedDeBruijn { - text: parameter_name.text, - index: 0.into(), - }, + parameter_name: parameter_name.clone(), body, } .into(), @@ -511,10 +508,10 @@ enum Context { #[derive(Clone, Debug)] pub enum Value { - Con(Constant), + Con(Rc), Delay(Rc>, Rc>), Lambda { - parameter_name: NamedDeBruijn, + parameter_name: Rc, body: Rc>, env: Rc>, }, @@ -527,17 +524,17 @@ pub enum Value { impl Value { 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 { - 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. pub fn to_ex_mem(&self) -> i64 { match self { - Value::Con(c) => match c { + Value::Con(c) => match c.as_ref() { Constant::Integer(i) => { if *i == 0 { 1 @@ -556,10 +553,10 @@ impl Value { Constant::Unit => 1, Constant::Bool(_) => 1, 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) => { - 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), }, @@ -603,14 +600,14 @@ impl Value { PlutusData::BigInt(i) => { if let BigInt::Int(g) = i { 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 { unreachable!() }; } PlutusData::BoundedBytes(b) => { let byte_string: Vec = 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) => { // create new stack with of items from the list of data @@ -679,7 +676,7 @@ impl TryFrom for Constant { fn try_from(value: Value) -> Result { match value { - Value::Con(constant) => Ok(constant), + Value::Con(constant) => Ok(constant.as_ref().clone()), rest => Err(Error::NotAConstant(rest)), } } @@ -693,9 +690,9 @@ impl From<&Constant> for Type { Constant::String(_) => Type::String, Constant::Unit => Type::Unit, 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, _, _) => { - Type::Pair(Box::new(t1.clone()), Box::new(t2.clone())) + Type::Pair(Rc::new(t1.clone()), Rc::new(t2.clone())) } Constant::Data(_) => Type::Data, } diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index b2eb90c2..943efcae 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -1,4 +1,4 @@ -use std::ops::Deref; +use std::{ops::Deref, rc::Rc}; use pallas_primitives::babbage::{BigInt, Constr, PlutusData}; @@ -281,7 +281,7 @@ impl DefaultFunction { } else { 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(), @@ -298,14 +298,14 @@ impl DefaultFunction { if args.is_empty() { arg.expect_type(Type::Integer) } 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( - Box::new(Type::Data), - Box::new(Type::Data), + DefaultFunction::MapData => arg.expect_type(Type::List(Rc::new(Type::Pair( + Rc::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::BData => arg.expect_type(Type::ByteString), DefaultFunction::UnConstrData => arg.expect_type(Type::Data), @@ -327,543 +327,762 @@ impl DefaultFunction { pub fn call(&self, args: &[Value], logs: &mut Vec) -> Result { match self { DefaultFunction::AddInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - match arg1.checked_add(*arg2) { - Some(res) => Ok(Value::Con(Constant::Integer(res))), - None => Err(Error::OverflowError), + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + match arg1.checked_add(*arg2) { + Some(res) => Ok(Value::Con(Constant::Integer(res).into())), + None => Err(Error::OverflowError), + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::SubtractInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - match arg1.checked_sub(*arg2) { - Some(res) => Ok(Value::Con(Constant::Integer(res))), - None => Err(Error::OverflowError), + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + match arg1.checked_sub(*arg2) { + Some(res) => Ok(Value::Con(Constant::Integer(res).into())), + None => Err(Error::OverflowError), + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::MultiplyInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - match arg1.checked_mul(*arg2) { - Some(res) => Ok(Value::Con(Constant::Integer(res))), - None => Err(Error::OverflowError), + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + match arg1.checked_mul(*arg2) { + Some(res) => Ok(Value::Con(Constant::Integer(res).into())), + None => Err(Error::OverflowError), + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::DivideInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - if *arg2 != 0 { - let ret = (*arg1 as f64) / (*arg2 as f64); + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + if *arg2 != 0 { + let ret = (*arg1 as f64) / (*arg2 as f64); - Ok(Value::Con(Constant::Integer(ret.floor() as i128))) - } else { - Err(Error::DivideByZero(*arg1, *arg2)) + Ok(Value::Con(Constant::Integer(ret.floor() as i128).into())) + } else { + Err(Error::DivideByZero(*arg1, *arg2)) + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::QuotientInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - if *arg2 != 0 { - let ret = (*arg1 as f64) / (*arg2 as f64); + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + if *arg2 != 0 { + 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))) - } else { - Err(Error::DivideByZero(*arg1, *arg2)) + Ok(Value::Con(Constant::Integer(ret as i128).into())) + } else { + Err(Error::DivideByZero(*arg1, *arg2)) + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::RemainderInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - if *arg2 != 0 { - let ret = arg1 % arg2; + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + if *arg2 != 0 { + let ret = arg1 % arg2; - Ok(Value::Con(Constant::Integer(ret))) - } else { - Err(Error::DivideByZero(*arg1, *arg2)) + Ok(Value::Con(Constant::Integer(ret).into())) + } else { + Err(Error::DivideByZero(*arg1, *arg2)) + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::ModInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - if *arg2 != 0 { - let ret = arg1 % arg2; + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + if *arg2 != 0 { + let ret = arg1 % arg2; - Ok(Value::Con(Constant::Integer(ret.abs()))) - } else { - Err(Error::DivideByZero(*arg1, *arg2)) + Ok(Value::Con(Constant::Integer(ret.abs()).into())) + } else { + Err(Error::DivideByZero(*arg1, *arg2)) + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::EqualsInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - Ok(Value::Con(Constant::Bool(arg1 == arg2))) + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 == arg2).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::LessThanInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - Ok(Value::Con(Constant::Bool(arg1 < arg2))) + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 < arg2).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::LessThanEqualsInteger => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => { - Ok(Value::Con(Constant::Bool(arg1 <= arg2))) + (Value::Con(integer1), Value::Con(integer2)) => { + match (integer1.as_ref(), integer2.as_ref()) { + (Constant::Integer(arg1), Constant::Integer(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 <= arg2).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::AppendByteString => match (&args[0], &args[1]) { - ( - Value::Con(Constant::ByteString(arg1)), - Value::Con(Constant::ByteString(arg2)), - ) => Ok(Value::Con(Constant::ByteString( - arg1.iter().copied().chain(arg2.iter().copied()).collect(), - ))), + (Value::Con(byte_string1), Value::Con(byte_string2)) => { + match (byte_string1.as_ref(), byte_string2.as_ref()) { + (Constant::ByteString(arg1), Constant::ByteString(arg2)) => Ok(Value::Con( + Constant::ByteString( + arg1.iter().copied().chain(arg2.iter().copied()).collect(), + ) + .into(), + )), + _ => unreachable!(), + } + } _ => unreachable!(), }, DefaultFunction::ConsByteString => match (&args[0], &args[1]) { - (Value::Con(Constant::Integer(arg1)), Value::Con(Constant::ByteString(arg2))) => { - let mut ret = vec![(arg1 % 256) as u8]; - ret.extend(arg2.clone()); + (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]; + ret.extend(arg2.clone()); - Ok(Value::Con(Constant::ByteString(ret))) + Ok(Value::Con(Constant::ByteString(ret).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::SliceByteString => match (&args[0], &args[1], &args[2]) { - ( - Value::Con(Constant::Integer(arg1)), - Value::Con(Constant::Integer(arg2)), - Value::Con(Constant::ByteString(arg3)), - ) => { - let skip = if 0 > *arg1 { 0 } else { *arg1 as usize }; - let take = if 0 > *arg2 { 0 } else { *arg2 as usize }; + (Value::Con(integer1), Value::Con(integer2), Value::Con(byte_string)) => { + match (integer1.as_ref(), integer2.as_ref(), byte_string.as_ref()) { + ( + Constant::Integer(arg1), + Constant::Integer(arg2), + Constant::ByteString(arg3), + ) => { + let skip = if 0 > *arg1 { 0 } else { *arg1 as usize }; + let take = if 0 > *arg2 { 0 } else { *arg2 as usize }; - let ret: Vec = arg3.iter().skip(skip).take(take).cloned().collect(); + let ret: Vec = arg3.iter().skip(skip).take(take).cloned().collect(); - Ok(Value::Con(Constant::ByteString(ret))) + Ok(Value::Con(Constant::ByteString(ret).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::LengthOfByteString => match &args[0] { - Value::Con(Constant::ByteString(arg1)) => { - Ok(Value::Con(Constant::Integer(arg1.len() as i128))) - } + Value::Con(byte_string) => match byte_string.as_ref() { + Constant::ByteString(arg1) => { + Ok(Value::Con(Constant::Integer(arg1.len() as i128).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::IndexByteString => match (&args[0], &args[1]) { - (Value::Con(Constant::ByteString(arg1)), Value::Con(Constant::Integer(arg2))) => { - let index = *arg2 as usize; + (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; - if 0 <= *arg2 && index < arg1.len() { - let ret = arg1[index] as i128; + if 0 <= *arg2 && index < arg1.len() { + let ret = arg1[index] as i128; - Ok(Value::Con(Constant::Integer(ret))) - } else { - Err(Error::ByteStringOutOfBounds(*arg2, arg1.to_vec())) + Ok(Value::Con(Constant::Integer(ret).into())) + } else { + Err(Error::ByteStringOutOfBounds(*arg2, arg1.to_vec())) + } + } + _ => unreachable!(), } } _ => unreachable!(), }, DefaultFunction::EqualsByteString => match (&args[0], &args[1]) { - ( - Value::Con(Constant::ByteString(arg1)), - Value::Con(Constant::ByteString(arg2)), - ) => Ok(Value::Con(Constant::Bool(arg1 == arg2))), + (Value::Con(byte_string1), Value::Con(byte_string2)) => { + match (byte_string1.as_ref(), byte_string2.as_ref()) { + (Constant::ByteString(arg1), Constant::ByteString(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 == arg2).into())) + } + _ => unreachable!(), + } + } _ => unreachable!(), }, DefaultFunction::LessThanByteString => match (&args[0], &args[1]) { - ( - Value::Con(Constant::ByteString(arg1)), - Value::Con(Constant::ByteString(arg2)), - ) => Ok(Value::Con(Constant::Bool(arg1 < arg2))), + (Value::Con(byte_string1), Value::Con(byte_string2)) => { + match (byte_string1.as_ref(), byte_string2.as_ref()) { + (Constant::ByteString(arg1), Constant::ByteString(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 < arg2).into())) + } + _ => unreachable!(), + } + } _ => unreachable!(), }, DefaultFunction::LessThanEqualsByteString => match (&args[0], &args[1]) { - ( - Value::Con(Constant::ByteString(arg1)), - Value::Con(Constant::ByteString(arg2)), - ) => Ok(Value::Con(Constant::Bool(arg1 <= arg2))), + (Value::Con(byte_string1), Value::Con(byte_string2)) => { + match (byte_string1.as_ref(), byte_string2.as_ref()) { + (Constant::ByteString(arg1), Constant::ByteString(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 <= arg2).into())) + } + _ => unreachable!(), + } + } _ => unreachable!(), }, DefaultFunction::Sha2_256 => match &args[0] { - Value::Con(Constant::ByteString(arg1)) => { - use cryptoxide::{digest::Digest, sha2::Sha256}; + Value::Con(byte_string) => match byte_string.as_ref() { + Constant::ByteString(arg1) => { + use cryptoxide::{digest::Digest, sha2::Sha256}; - let mut hasher = Sha256::new(); + let mut hasher = Sha256::new(); - hasher.input(arg1); + hasher.input(arg1); - let mut bytes = vec![0; hasher.output_bytes()]; + let mut bytes = vec![0; hasher.output_bytes()]; - hasher.result(&mut bytes); + hasher.result(&mut bytes); - Ok(Value::Con(Constant::ByteString(bytes))) - } + Ok(Value::Con(Constant::ByteString(bytes).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::Sha3_256 => match &args[0] { - Value::Con(Constant::ByteString(arg1)) => { - use cryptoxide::{digest::Digest, sha3::Sha3_256}; + Value::Con(byte_string) => match byte_string.as_ref() { + Constant::ByteString(arg1) => { + use cryptoxide::{digest::Digest, sha3::Sha3_256}; - let mut hasher = Sha3_256::new(); + let mut hasher = Sha3_256::new(); - hasher.input(arg1); + hasher.input(arg1); - let mut bytes = vec![0; hasher.output_bytes()]; + let mut bytes = vec![0; hasher.output_bytes()]; - hasher.result(&mut bytes); + hasher.result(&mut bytes); - Ok(Value::Con(Constant::ByteString(bytes))) - } + Ok(Value::Con(Constant::ByteString(bytes).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::Blake2b_256 => match &args[0] { - Value::Con(Constant::ByteString(arg1)) => { - use cryptoxide::{blake2b::Blake2b, digest::Digest}; + Value::Con(byte_string) => match byte_string.as_ref() { + Constant::ByteString(arg1) => { + use cryptoxide::{blake2b::Blake2b, digest::Digest}; - let mut digest = [0u8; 32]; - let mut context = Blake2b::new(32); + let mut digest = [0u8; 32]; + let mut context = Blake2b::new(32); - context.input(arg1); - context.result(&mut digest); + context.input(arg1); + context.result(&mut digest); - Ok(Value::Con(Constant::ByteString(digest.to_vec()))) - } + Ok(Value::Con(Constant::ByteString(digest.to_vec()).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::VerifyEd25519Signature => match (&args[0], &args[1], &args[2]) { - ( - Value::Con(Constant::ByteString(public_key)), - Value::Con(Constant::ByteString(message)), - Value::Con(Constant::ByteString(signature)), - ) => { - use cryptoxide::ed25519; + (Value::Con(public_key), Value::Con(message), Value::Con(signature)) => { + match (public_key.as_ref(), message.as_ref(), signature.as_ref()) { + ( + Constant::ByteString(public_key), + Constant::ByteString(message), + Constant::ByteString(signature), + ) => { + use cryptoxide::ed25519; - let public_key: [u8; 32] = public_key - .clone() - .try_into() - .map_err(|e: Vec| Error::UnexpectedEd25519PublicKeyLength(e.len()))?; + let public_key: [u8; 32] = + public_key.clone().try_into().map_err(|e: Vec| { + Error::UnexpectedEd25519PublicKeyLength(e.len()) + })?; - let signature: [u8; 64] = signature - .clone() - .try_into() - .map_err(|e: Vec| Error::UnexpectedEd25519SignatureLength(e.len()))?; + let signature: [u8; 64] = + signature.clone().try_into().map_err(|e: Vec| { + 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!(), }, DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(), DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(), DefaultFunction::AppendString => match (&args[0], &args[1]) { - (Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => { - Ok(Value::Con(Constant::String(format!("{}{}", arg1, arg2)))) + (Value::Con(string1), Value::Con(string2)) => { + match (string1.as_ref(), string2.as_ref()) { + (Constant::String(arg1), Constant::String(arg2)) => Ok(Value::Con( + Constant::String(format!("{}{}", arg1, arg2)).into(), + )), + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::EqualsString => match (&args[0], &args[1]) { - (Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => { - Ok(Value::Con(Constant::Bool(arg1 == arg2))) + (Value::Con(string1), Value::Con(string2)) => { + match (string1.as_ref(), string2.as_ref()) { + (Constant::String(arg1), Constant::String(arg2)) => { + Ok(Value::Con(Constant::Bool(arg1 == arg2).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::EncodeUtf8 => match &args[0] { - Value::Con(Constant::String(arg1)) => { - let bytes = arg1.as_bytes().to_vec(); + Value::Con(string) => match string.as_ref() { + Constant::String(arg1) => { + let bytes = arg1.as_bytes().to_vec(); - Ok(Value::Con(Constant::ByteString(bytes))) - } + Ok(Value::Con(Constant::ByteString(bytes).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::DecodeUtf8 => match &args[0] { - Value::Con(Constant::ByteString(arg1)) => { - let string = String::from_utf8(arg1.clone())?; + Value::Con(byte_string) => match byte_string.as_ref() { + Constant::ByteString(arg1) => { + 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] { - Value::Con(Constant::Bool(condition)) => { - if condition { - Ok(args[1].clone()) - } else { - Ok(args[2].clone()) + DefaultFunction::IfThenElse => match &args[0] { + Value::Con(boolean) => match boolean.as_ref() { + Constant::Bool(condition) => { + if *condition { + Ok(args[1].clone()) + } else { + Ok(args[2].clone()) + } } - } + _ => unreachable!(), + }, _ => unreachable!(), }, 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!(), }, DefaultFunction::Trace => match &args[0] { - Value::Con(Constant::String(arg1)) => { - logs.push(arg1.clone()); + Value::Con(string) => match string.as_ref() { + Constant::String(arg1) => { + logs.push(arg1.clone()); - Ok(args[1].clone()) - } + Ok(args[1].clone()) + } + _ => unreachable!(), + }, _ => unreachable!(), }, 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!(), }, 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!(), }, DefaultFunction::ChooseList => match &args[0] { - Value::Con(Constant::ProtoList(_, list)) => { - if list.is_empty() { - Ok(args[1].clone()) - } else { - Ok(args[2].clone()) + Value::Con(list) => match list.as_ref() { + Constant::ProtoList(_, list) => { + if list.is_empty() { + Ok(args[1].clone()) + } else { + Ok(args[2].clone()) + } } - } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::MkCons => match (&args[0], &args[1]) { - (Value::Con(item), Value::Con(Constant::ProtoList(r#type, list))) => { - let mut ret = vec![item.clone()]; - ret.extend(list.clone()); + (Value::Con(item), Value::Con(list)) => match list.as_ref() { + Constant::ProtoList(r#type, list) => { + let mut ret = vec![item.as_ref().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!(), }, DefaultFunction::HeadList => match &args[0] { - c @ Value::Con(Constant::ProtoList(_, list)) => { - if list.is_empty() { - Err(Error::EmptyList(c.clone())) - } else { - Ok(Value::Con(list[0].clone())) + c @ Value::Con(list) => match list.as_ref() { + Constant::ProtoList(_, list) => { + if list.is_empty() { + Err(Error::EmptyList(c.clone())) + } else { + Ok(Value::Con(list[0].clone().into())) + } } - } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::TailList => match &args[0] { - c @ Value::Con(Constant::ProtoList(r#type, list)) => { - if list.is_empty() { - Err(Error::EmptyList(c.clone())) - } else { - Ok(Value::Con(Constant::ProtoList( - r#type.clone(), - list[1..].to_vec(), - ))) + c @ Value::Con(list) => match list.as_ref() { + Constant::ProtoList(r#type, list) => { + if list.is_empty() { + Err(Error::EmptyList(c.clone())) + } else { + Ok(Value::Con( + Constant::ProtoList(r#type.clone(), list[1..].to_vec()).into(), + )) + } } - } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::NullList => match &args[0] { - Value::Con(Constant::ProtoList(_, list)) => { - Ok(Value::Con(Constant::Bool(list.is_empty()))) - } + Value::Con(list) => match list.as_ref() { + Constant::ProtoList(_, list) => { + Ok(Value::Con(Constant::Bool(list.is_empty()).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::ChooseData => match &args[0] { - Value::Con(Constant::Data(PlutusData::Constr(_))) => Ok(args[1].clone()), - Value::Con(Constant::Data(PlutusData::Map(_))) => Ok(args[2].clone()), - Value::Con(Constant::Data(PlutusData::Array(_))) => Ok(args[3].clone()), - Value::Con(Constant::Data(PlutusData::BigInt(_))) => Ok(args[4].clone()), - Value::Con(Constant::Data(PlutusData::BoundedBytes(_))) => Ok(args[5].clone()), + Value::Con(con) => match con.as_ref() { + Constant::Data(PlutusData::Constr(_)) => Ok(args[1].clone()), + Constant::Data(PlutusData::Map(_)) => Ok(args[2].clone()), + Constant::Data(PlutusData::Array(_)) => Ok(args[3].clone()), + Constant::Data(PlutusData::BigInt(_)) => Ok(args[4].clone()), + Constant::Data(PlutusData::BoundedBytes(_)) => Ok(args[5].clone()), + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::ConstrData => match (&args[0], &args[1]) { - ( - Value::Con(Constant::Integer(i)), - Value::Con(Constant::ProtoList(Type::Data, l)), - ) => { - let data_list: Vec = l - .iter() - .map(|item| match item { - Constant::Data(d) => d.clone(), - _ => unreachable!(), - }) - .collect(); + (Value::Con(integer), Value::Con(list)) => { + match (integer.as_ref(), list.as_ref()) { + (Constant::Integer(i), Constant::ProtoList(Type::Data, l)) => { + let data_list: Vec = l + .iter() + .map(|item| match item { + Constant::Data(d) => d.clone(), + _ => unreachable!(), + }) + .collect(); - let constr_data = PlutusData::Constr(Constr { - // TODO: handle other types of constructor tags - tag: convert_constr_to_tag(*i as u64), - any_constructor: None, - fields: data_list, - }); - Ok(Value::Con(Constant::Data(constr_data))) + let constr_data = PlutusData::Constr(Constr { + // TODO: handle other types of constructor tags + tag: convert_constr_to_tag(*i as u64), + any_constructor: None, + fields: data_list, + }); + + Ok(Value::Con(Constant::Data(constr_data).into())) + } + _ => unreachable!(), + } } _ => unreachable!(), }, DefaultFunction::MapData => match &args[0] { - Value::Con(Constant::ProtoList(_, list)) => { - let mut map = Vec::new(); + Value::Con(list) => match list.as_ref() { + Constant::ProtoList(_, list) => { + let mut map = Vec::new(); - for item in list { - match item { - Constant::ProtoPair(Type::Data, Type::Data, left, right) => { - match (*left.clone(), *right.clone()) { - (Constant::Data(key), Constant::Data(value)) => { - map.push((key, value)); + for item in list { + match item { + Constant::ProtoPair(Type::Data, Type::Data, left, right) => { + match (left.as_ref(), right.as_ref()) { + (Constant::Data(key), Constant::Data(value)) => { + map.push((key.clone(), value.clone())); + } + _ => unreachable!(), } - _ => unreachable!(), } + _ => unreachable!(), } - _ => unreachable!(), } - } - Ok(Value::Con(Constant::Data(PlutusData::Map(map.into())))) - } + Ok(Value::Con( + Constant::Data(PlutusData::Map(map.into())).into(), + )) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::ListData => match &args[0] { - Value::Con(Constant::ProtoList(_, list)) => { - let data_list: Vec = list - .iter() - .map(|item| match item { - Constant::Data(d) => d.clone(), - _ => unreachable!(), - }) - .collect(); + Value::Con(list) => match list.as_ref() { + Constant::ProtoList(_, list) => { + let data_list: Vec = list + .iter() + .map(|item| match item { + Constant::Data(d) => d.clone(), + _ => unreachable!(), + }) + .collect(); - Ok(Value::Con(Constant::Data(PlutusData::Array(data_list)))) - } + Ok(Value::Con( + Constant::Data(PlutusData::Array(data_list)).into(), + )) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::IData => match &args[0] { - Value::Con(Constant::Integer(i)) => Ok(Value::Con(Constant::Data( - PlutusData::BigInt(BigInt::Int((*i).try_into().unwrap())), - ))), + Value::Con(integer) => match integer.as_ref() { + Constant::Integer(i) => Ok(Value::Con( + Constant::Data(PlutusData::BigInt(BigInt::Int((*i).try_into().unwrap()))) + .into(), + )), + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::BData => match &args[0] { - Value::Con(Constant::ByteString(b)) => Ok(Value::Con(Constant::Data( - PlutusData::BoundedBytes(b.clone().try_into().unwrap()), - ))), + Value::Con(byte_string) => match byte_string.as_ref() { + Constant::ByteString(b) => Ok(Value::Con( + Constant::Data(PlutusData::BoundedBytes(b.clone().try_into().unwrap())) + .into(), + )), + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::UnConstrData => match &args[0] { - Value::Con(Constant::Data(PlutusData::Constr(c))) => { - Ok(Value::Con(Constant::ProtoPair( - Type::Integer, - Type::List(Box::new(Type::Data)), - // TODO: handle other types of constructor tags - Box::new(Constant::Integer(convert_tag_to_constr(c.tag as i128))), - Box::new(Constant::ProtoList( - Type::Data, - c.fields - .deref() - .iter() - .map(|d| Constant::Data(d.clone())) - .collect(), - )), - ))) - } + Value::Con(con) => match con.as_ref() { + Constant::Data(PlutusData::Constr(c)) => { + Ok(Value::Con( + Constant::ProtoPair( + Type::Integer, + Type::List(Rc::new(Type::Data)), + // TODO: handle other types of constructor tags + Rc::new(Constant::Integer(convert_tag_to_constr(c.tag as i128))), + Rc::new(Constant::ProtoList( + Type::Data, + c.fields + .deref() + .iter() + .map(|d| Constant::Data(d.clone())) + .collect(), + )), + ) + .into(), + )) + } + v => Err(Error::DeserialisationError( + "UnConstrData".to_string(), + Value::Con(v.clone().into()), + )), + }, v => Err(Error::DeserialisationError( "UnConstrData".to_string(), v.clone(), )), }, DefaultFunction::UnMapData => match &args[0] { - Value::Con(Constant::Data(PlutusData::Map(m))) => { - Ok(Value::Con(Constant::ProtoList( - Type::Pair(Box::new(Type::Data), Box::new(Type::Data)), - m.deref() - .iter() - .map(|p| -> Constant { - Constant::ProtoPair( - Type::Data, - Type::Data, - Box::new(Constant::Data(p.0.clone())), - Box::new(Constant::Data(p.1.clone())), - ) - }) - .collect(), - ))) - } + Value::Con(data) => match data.as_ref() { + Constant::Data(PlutusData::Map(m)) => Ok(Value::Con( + Constant::ProtoList( + Type::Pair(Rc::new(Type::Data), Rc::new(Type::Data)), + m.deref() + .iter() + .map(|p| -> Constant { + Constant::ProtoPair( + Type::Data, + Type::Data, + Rc::new(Constant::Data(p.0.clone())), + Rc::new(Constant::Data(p.1.clone())), + ) + }) + .collect(), + ) + .into(), + )), + v => Err(Error::DeserialisationError( + "UnMapData".to_string(), + Value::Con(v.clone().into()), + )), + }, v => Err(Error::DeserialisationError( "UnMapData".to_string(), v.clone(), )), }, DefaultFunction::UnListData => match &args[0] { - Value::Con(Constant::Data(PlutusData::Array(l))) => { - Ok(Value::Con(Constant::ProtoList( - Type::Data, - l.deref() - .iter() - .map(|d| Constant::Data(d.clone())) - .collect(), - ))) - } + Value::Con(data) => match data.as_ref() { + Constant::Data(PlutusData::Array(l)) => Ok(Value::Con( + Constant::ProtoList( + Type::Data, + l.deref() + .iter() + .map(|d| Constant::Data(d.clone())) + .collect(), + ) + .into(), + )), + v => Err(Error::DeserialisationError( + "UnMapData".to_string(), + Value::Con(v.clone().into()), + )), + }, v => Err(Error::DeserialisationError( "UnListData".to_string(), v.clone(), )), }, DefaultFunction::UnIData => match &args[0] { - Value::Con(Constant::Data(PlutusData::BigInt(b))) => { - if let BigInt::Int(i) = b { - let x: i128 = (*i).try_into().unwrap(); + Value::Con(data) => match data.as_ref() { + Constant::Data(PlutusData::BigInt(b)) => { + if let BigInt::Int(i) = b { + let x: i128 = (*i).try_into().unwrap(); - Ok(Value::Con(Constant::Integer(x))) - } else { - unreachable!() + Ok(Value::Con(Constant::Integer(x).into())) + } else { + unreachable!() + } } - } + v => Err(Error::DeserialisationError( + "UnMapData".to_string(), + Value::Con(v.clone().into()), + )), + }, v => Err(Error::DeserialisationError( "UnIData".to_string(), v.clone(), )), }, DefaultFunction::UnBData => match &args[0] { - Value::Con(Constant::Data(PlutusData::BoundedBytes(b))) => { - Ok(Value::Con(Constant::ByteString(b.to_vec()))) - } + Value::Con(data) => match data.as_ref() { + 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( "UnBData".to_string(), v.clone(), )), }, DefaultFunction::EqualsData => match (&args[0], &args[1]) { - (Value::Con(Constant::Data(d1)), Value::Con(Constant::Data(d2))) => { - Ok(Value::Con(Constant::Bool(d1.eq(d2)))) - } + (Value::Con(data1), Value::Con(data2)) => match (data1.as_ref(), data2.as_ref()) { + (Constant::Data(d1), Constant::Data(d2)) => { + Ok(Value::Con(Constant::Bool(d1.eq(d2)).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::SerialiseData => match &args[0] { - Value::Con(Constant::Data(d)) => { - let serialized_data = plutus_data_to_bytes(d).unwrap(); - Ok(Value::Con(Constant::ByteString(serialized_data))) - } + Value::Con(data) => match data.as_ref() { + Constant::Data(d) => { + let serialized_data = plutus_data_to_bytes(d).unwrap(); + Ok(Value::Con(Constant::ByteString(serialized_data).into())) + } + _ => unreachable!(), + }, _ => unreachable!(), }, DefaultFunction::MkPairData => match (&args[0], &args[1]) { - (Value::Con(Constant::Data(d1)), Value::Con(Constant::Data(d2))) => { - Ok(Value::Con(Constant::ProtoPair( - Type::Data, - Type::Data, - Box::new(Constant::Data(d1.clone())), - Box::new(Constant::Data(d2.clone())), - ))) - } + (Value::Con(data1), Value::Con(data2)) => match (data1.as_ref(), data2.as_ref()) { + (Constant::Data(d1), Constant::Data(d2)) => Ok(Value::Con( + Constant::ProtoPair( + Type::Data, + Type::Data, + Rc::new(Constant::Data(d1.clone())), + Rc::new(Constant::Data(d2.clone())), + ) + .into(), + )), + _ => unreachable!(), + }, _ => unreachable!(), }, - DefaultFunction::MkNilData => Ok(Value::Con(Constant::ProtoList(Type::Data, vec![]))), - DefaultFunction::MkNilPairData => Ok(Value::Con(Constant::ProtoList( - Type::Pair(Box::new(Type::Data), Box::new(Type::Data)), - vec![], - ))), + DefaultFunction::MkNilData => { + 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(), + )), } } } diff --git a/crates/uplc/src/parser.rs b/crates/uplc/src/parser.rs index 5e1c5dae..19b6815b 100644 --- a/crates/uplc/src/parser.rs +++ b/crates/uplc/src/parser.rs @@ -87,7 +87,7 @@ peg::parser! { / constant_list() / constant_pair() ) _* ")" { - Term::Constant(con) + Term::Constant(con.into()) } rule builtin() -> Term @@ -96,11 +96,11 @@ peg::parser! { } rule var() -> Term - = n:name() { Term::Var(n) } + = n:name() { Term::Var(n.into()) } rule lambda() -> 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] @@ -148,7 +148,7 @@ peg::parser! { rule constant_pair() -> Constant = "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) @@ -218,13 +218,13 @@ peg::parser! { } / ls:list(list_sub_type(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") } } / p:pair(pair_sub_type(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") } } @@ -237,10 +237,10 @@ peg::parser! { / _* "string" { Type::String } / _* "data" { Type::Data } / _* "list" _* "<" _* t:type_info() _* ">" { - Type::List(Box::new(t)) + Type::List(t.into()) } / _* "pair" _* "<" l:type_info() "," r:type_info() ">" { - Type::Pair(Box::new(l), Box::new(r)) + Type::Pair(l.into(), r.into()) } rule name() -> Name @@ -274,10 +274,10 @@ mod test { version: (1, 0, 0), term: Term::Apply { function: Rc::new(Term::Lambda { - parameter_name: x.clone(), - body: Rc::new(Term::Var(x)), + parameter_name: x.clone().into(), + 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:: { version: (1, 0, 0), term: Term::Lambda { - parameter_name: x.clone(), - body: Rc::new(Term::Var(x)), + parameter_name: x.clone().into(), + body: Rc::new(Term::Var(x.into())), } } ) @@ -314,8 +314,8 @@ mod test { Program:: { version: (1, 0, 0), term: Term::Lambda { - parameter_name: x.clone(), - body: Rc::new(Term::Delay(Rc::new(Term::Var(x)))), + parameter_name: x.clone().into(), + body: Rc::new(Term::Delay(Rc::new(Term::Var(x.into())))), } } ) @@ -344,7 +344,7 @@ mod test { super::program(uplc).unwrap(), Program:: { 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 { function: Rc::new(Term::Apply { 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 { function: Rc::new(Term::Apply { 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::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), term: Term::Apply { 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 { function: Rc::new(Term::Apply { 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 { function: Rc::new(Term::Apply { function: Rc::new(Term::Builtin(DefaultFunction::EqualsByteString)), - argument: Rc::new(Term::Constant(Constant::ByteString(vec![ - 0x00, 0xff, 0xaa - ]))) + argument: Rc::new(Term::Constant( + 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 { function: Rc::new(Term::Apply { 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 { function: Rc::new(Term::Apply { 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(), Program:: { 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(), Program:: { 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(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoList( - Type::Bool, - vec![ - Constant::Bool(true), - Constant::Bool(false), - Constant::Bool(true) - ] - )) + term: Term::Constant( + Constant::ProtoList( + Type::Bool, + vec![ + Constant::Bool(true), + Constant::Bool(false), + Constant::Bool(true) + ] + ) + .into() + ) } ) } @@ -656,13 +677,16 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoList( - Type::ByteString, - vec![ - Constant::ByteString(vec![0x00]), - Constant::ByteString(vec![0x01]), - ] - )) + term: Term::Constant( + Constant::ProtoList( + Type::ByteString, + vec![ + Constant::ByteString(vec![0x00]), + Constant::ByteString(vec![0x01]), + ] + ) + .into() + ) } ) } @@ -674,16 +698,19 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoList( - Type::List(Box::new(Type::Integer)), - vec![ - Constant::ProtoList( - Type::Integer, - vec![Constant::Integer(14), Constant::Integer(42)] - ), - Constant::ProtoList(Type::Integer, vec![Constant::Integer(1337)]) - ] - )) + term: Term::Constant( + Constant::ProtoList( + Type::List(Type::Integer.into()), + vec![ + Constant::ProtoList( + Type::Integer, + vec![Constant::Integer(14), Constant::Integer(42)] + ), + Constant::ProtoList(Type::Integer, vec![Constant::Integer(1337)]) + ] + ) + .into() + ) } ) } @@ -703,10 +730,13 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoList( - Type::Integer, - vec![Constant::Integer(14), Constant::Integer(42)], - )) + term: Term::Constant( + Constant::ProtoList( + Type::Integer, + vec![Constant::Integer(14), Constant::Integer(42)], + ) + .into() + ) } ) } @@ -718,12 +748,15 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoPair( - Type::Unit, - Type::Unit, - Box::new(Constant::Unit), - Box::new(Constant::Unit) - )) + term: Term::Constant( + Constant::ProtoPair( + Type::Unit, + Type::Unit, + Constant::Unit.into(), + Constant::Unit.into() + ) + .into() + ) } ) } @@ -735,17 +768,21 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoPair( - Type::Bool, - Type::Pair(Box::new(Type::Integer), Box::new(Type::ByteString)), - Box::new(Constant::Bool(true)), - Box::new(Constant::ProtoPair( - Type::Integer, - Type::ByteString, - Box::new(Constant::Integer(14)), - Box::new(Constant::ByteString(vec![0x42])), - )) - )) + term: Term::Constant( + Constant::ProtoPair( + Type::Bool, + Type::Pair(Type::Integer.into(), Type::ByteString.into()), + Constant::Bool(true).into(), + Constant::ProtoPair( + Type::Integer, + Type::ByteString, + Constant::Integer(14).into(), + Constant::ByteString(vec![0x42]).into(), + ) + .into() + ) + .into() + ) } ) } @@ -757,15 +794,19 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoPair( - Type::String, - Type::List(Box::new(Type::Integer)), - Box::new(Constant::String(String::from("foo"))), - Box::new(Constant::ProtoList( - Type::Integer, - vec![Constant::Integer(14), Constant::Integer(42)], - )) - )) + term: Term::Constant( + Constant::ProtoPair( + Type::String, + Type::List(Type::Integer.into()), + Constant::String(String::from("foo")).into(), + Constant::ProtoList( + Type::Integer, + vec![Constant::Integer(14), Constant::Integer(42)], + ) + .into() + ) + .into() + ) } ) } @@ -783,12 +824,15 @@ mod test { super::program(uplc).unwrap(), Program:: { version: (0, 0, 0), - term: Term::Constant(Constant::ProtoPair( - Type::Integer, - Type::Integer, - Box::new(Constant::Integer(14)), - Box::new(Constant::Integer(42)) - )) + term: Term::Constant( + Constant::ProtoPair( + Type::Integer, + Type::Integer, + Constant::Integer(14).into(), + Constant::Integer(42).into() + ) + .into() + ) } ) } @@ -815,9 +859,9 @@ mod test { term: Term::Apply { function: Rc::new(Term::Apply { 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())) } } ) diff --git a/crates/uplc/src/parser/interner.rs b/crates/uplc/src/parser/interner.rs index 6fc6be87..b6c67cbe 100644 --- a/crates/uplc/src/parser/interner.rs +++ b/crates/uplc/src/parser/interner.rs @@ -27,12 +27,16 @@ impl Interner { pub fn term(&mut self, term: &mut 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::Lambda { parameter_name, body, } => { + let parameter_name = Rc::make_mut(parameter_name); parameter_name.unique = self.intern(¶meter_name.text); self.term(Rc::make_mut(body)); } diff --git a/crates/uplc/src/program_builder/constant.rs b/crates/uplc/src/program_builder/constant.rs index 532298d4..0e998b85 100644 --- a/crates/uplc/src/program_builder/constant.rs +++ b/crates/uplc/src/program_builder/constant.rs @@ -3,27 +3,27 @@ use crate::program_builder::WithTerm; pub trait WithConstant: WithTerm { 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) } fn with_byte_string(self, bytes: Vec) -> Self::Next { - let term = Term::Constant(Constant::ByteString(bytes)); + let term = Term::Constant(Constant::ByteString(bytes).into()); self.next(term) } 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) } fn with_unit(self) -> Self::Next { - let term = Term::Constant(Constant::Unit); + let term = Term::Constant(Constant::Unit.into()); self.next(term) } 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) } } diff --git a/crates/uplc/src/program_builder/lambda.rs b/crates/uplc/src/program_builder/lambda.rs index b301f28b..5b92b64b 100644 --- a/crates/uplc/src/program_builder/lambda.rs +++ b/crates/uplc/src/program_builder/lambda.rs @@ -13,7 +13,7 @@ impl WithTerm for LambdaBuilder { fn next(self, term: Term) -> Self::Next { let term = Term::Lambda { - parameter_name: self.parameter_name, + parameter_name: self.parameter_name.into(), body: Rc::new(term), }; self.outer.next(term) diff --git a/crates/uplc/src/program_builder/var.rs b/crates/uplc/src/program_builder/var.rs index 44e88930..60e4ab84 100644 --- a/crates/uplc/src/program_builder/var.rs +++ b/crates/uplc/src/program_builder/var.rs @@ -4,7 +4,7 @@ use crate::program_builder::WithTerm; pub trait WithVar: WithTerm { fn with_var(self, name_str: &str) -> Self::Next { let name = self.get_name(name_str); - let term = Term::Var(name); + let term = Term::Var(name.into()); self.next(term) } } diff --git a/crates/uplc/test_data/fibonacci/fibonacci.uplc b/crates/uplc/test_data/fibonacci/fibonacci.uplc index 8ae3fa0f..2e1f1174 100644 --- a/crates/uplc/test_data/fibonacci/fibonacci.uplc +++ b/crates/uplc/test_data/fibonacci/fibonacci.uplc @@ -84,6 +84,6 @@ i_0 ] ) - (con integer 15) + (con integer 0) ] ) \ No newline at end of file