diff --git a/crates/uplc/src/parser.rs b/crates/uplc/src/parser.rs index bfc9c482..1bb17e22 100644 --- a/crates/uplc/src/parser.rs +++ b/crates/uplc/src/parser.rs @@ -158,17 +158,17 @@ peg::parser! { = "data" _+ d:data() { Constant::Data(d) } rule constant_list() -> Constant - = "list" _* "<" _* t:type_info() _* ">" _+ ls:list(Some(&t)) { + = "(" _* "list" _* t:type_info() _* ")" _+ ls:list(Some(&t)) { Constant::ProtoList(t, ls) } rule constant_pair() -> Constant - = "pair" _* "<" _* l:type_info() _* "," r:type_info() _* ">" _+ p:pair(Some((&l, &r))) { + = "(" _* "pair" _+ l:type_info() _+ r:type_info() _* ")" _+ p:pair(Some((&l, &r))) { Constant::ProtoPair(l, r, p.0.into(), p.1.into()) } rule pair(type_info: Option<(&Type, &Type)>) -> (Constant, Constant) - = "[" _* x:typed_constant(type_info.map(|t| t.0)) _* "," _* y:typed_constant(type_info.map(|t| t.1)) _* "]" { (x, y) } + = "(" _* x:typed_constant(type_info.map(|t| t.0)) _* "," _* y:typed_constant(type_info.map(|t| t.1)) _* ")" { (x, y) } rule number() -> isize = n:$("-"* ['0'..='9']+) {? n.parse().or(Err("isize")) } @@ -262,10 +262,10 @@ peg::parser! { / _* "bytestring" { Type::ByteString } / _* "string" { Type::String } / _* "data" { Type::Data } - / _* "list" _* "<" _* t:type_info() _* ">" { + / _* "(" _* "list" _+ t:type_info() _* ")" _* { Type::List(t.into()) } - / _* "pair" _* "<" l:type_info() "," r:type_info() ">" { + / _* "(" _* "pair" _+ l:type_info() _+ r:type_info() _* ")" _* { Type::Pair(l.into(), r.into()) } diff --git a/crates/uplc/tests/pretty_tests.rs b/crates/uplc/tests/pretty_tests.rs index 3a53d386..0996c94d 100644 --- a/crates/uplc/tests/pretty_tests.rs +++ b/crates/uplc/tests/pretty_tests.rs @@ -1,58 +1,64 @@ use num_bigint::ToBigInt; use uplc::{ - ast::{Constant, DeBruijn, Term, Type}, - Constr, PlutusData, + ast::{Constant, Term, Type, Name}, + Constr, PlutusData, parser::term, }; // Examples sourced from https://github.com/input-output-hk/plutus/issues/4751#issuecomment-1538377273 +fn round_trip(old_term: Term::, pp: &str) { + //assert_eq!(old_term.to_pretty(), pp); + let new_term = term(pp).expect("failed to parse"); + assert_eq!(new_term, old_term); +} + #[test] fn constant_list_integer() { - let term = Term::::Constant( - Constant::ProtoList( - Type::Integer.into(), - vec![ - Constant::Integer(0.to_bigint().unwrap()), - Constant::Integer(1.to_bigint().unwrap()), - Constant::Integer(2.to_bigint().unwrap()), - ], - ) - .into(), + round_trip( + Term::::Constant( + Constant::ProtoList( + Type::Integer.into(), + vec![ + Constant::Integer(0.to_bigint().unwrap()), + Constant::Integer(1.to_bigint().unwrap()), + Constant::Integer(2.to_bigint().unwrap()), + ], + ) + .into(), + ), + "(con (list integer) [0, 1, 2])", ); - assert_eq!(term.to_pretty(), "(con (list integer) [0, 1, 2])"); } #[test] fn constant_pair_bool_bytestring() { - let term = Term::::Constant( - Constant::ProtoPair( - Type::Bool.into(), - Type::ByteString.into(), - Constant::Bool(true).into(), - Constant::ByteString(vec![0x01, 0x23, 0x45]).into(), - ) - .into(), - ); - assert_eq!( - term.to_pretty(), - "(con (pair bool bytestring) (True, #012345))" + round_trip( + Term::::Constant( + Constant::ProtoPair( + Type::Bool.into(), + Type::ByteString.into(), + Constant::Bool(true).into(), + Constant::ByteString(vec![0x01, 0x23, 0x45]).into(), + ) + .into(), + ), + "(con (pair bool bytestring) (True, #012345))", ); } #[test] fn constant_pair_unit_string() { - let term = Term::::Constant( - Constant::ProtoPair( - Type::Unit.into(), - Type::String.into(), - Constant::Unit.into(), - Constant::String("hello universe".into()).into(), - ) - .into(), - ); - assert_eq!( - term.to_pretty(), - "(con (pair unit string) ((), \"hello universe\"))" + round_trip( + Term::::Constant( + Constant::ProtoPair( + Type::Unit.into(), + Type::String.into(), + Constant::Unit.into(), + Constant::String("hello universe".into()).into(), + ) + .into(), + ), + "(con (pair unit string) ((), \"hello universe\"))", ) } @@ -61,100 +67,104 @@ fn constant_deeply_nested_list() { let t0 = Type::Integer; let t1 = Type::List(t0.clone().into()); let t2 = Type::List(t1.clone().into()); - let term = Term::::Constant( - Constant::ProtoList( - t2, - vec![ - Constant::ProtoList( - t1.clone(), - vec![ - Constant::ProtoList( - t0.clone(), - vec![Constant::Integer(-1.to_bigint().unwrap())], - ), - Constant::ProtoList(t0.clone(), vec![]), - ], - ), - Constant::ProtoList( - t1.clone(), - vec![ - Constant::ProtoList(t0.clone(), vec![]), - Constant::ProtoList( - t0.clone(), - vec![ - Constant::Integer(2.to_bigint().unwrap()), - Constant::Integer(3.to_bigint().unwrap()), - ], - ), - ], - ), - ], - ) - .into(), - ); - assert_eq!( - term.to_pretty(), - "(con (list (list (list integer))) [[[-1], []], [[], [2, 3]]])" + round_trip( + Term::::Constant( + Constant::ProtoList( + t2, + vec![ + Constant::ProtoList( + t1.clone(), + vec![ + Constant::ProtoList( + t0.clone(), + vec![Constant::Integer(-1.to_bigint().unwrap())], + ), + Constant::ProtoList(t0.clone(), vec![]), + ], + ), + Constant::ProtoList( + t1.clone(), + vec![ + Constant::ProtoList(t0.clone(), vec![]), + Constant::ProtoList( + t0.clone(), + vec![ + Constant::Integer(2.to_bigint().unwrap()), + Constant::Integer(3.to_bigint().unwrap()), + ], + ), + ], + ), + ], + ) + .into(), + ), + "(con (list (list (list integer))) [[[-1], []], [[], [2, 3]]])", ); } #[test] fn constant_data_constr() { - let term = Term::::Constant( - Constant::Data(PlutusData::Constr(Constr:: { - tag: 1, - any_constructor: None, - fields: vec![PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int( - 2.into(), - ))], - })) - .into(), + round_trip( + Term::::Constant( + Constant::Data(PlutusData::Constr(Constr:: { + tag: 1, + any_constructor: None, + fields: vec![PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int( + 2.into(), + ))], + })) + .into(), + ), + "(con data (Constr 1 [I 2]))", ); - assert_eq!(term.to_pretty(), "(con data (Constr 1 [I 2]))"); } #[test] fn constant_data_map() { - let term = Term::::Constant( - Constant::Data(PlutusData::Map(uplc::KeyValuePairs::Def(vec![ - ( - PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(0.into())), - PlutusData::BoundedBytes(vec![0x00].into()), - ), - ( - PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())), - PlutusData::BoundedBytes(vec![0x0f].into()), - ), - ]))) - .into(), - ); - assert_eq!( - term.to_pretty(), - "(con data (Map [(I 0, B #00), (I 1, B #0f)]))" + round_trip( + Term::::Constant( + Constant::Data(PlutusData::Map(uplc::KeyValuePairs::Def(vec![ + ( + PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(0.into())), + PlutusData::BoundedBytes(vec![0x00].into()), + ), + ( + PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())), + PlutusData::BoundedBytes(vec![0x0f].into()), + ), + ]))) + .into(), + ), + "(con data (Map [(I 0, B #00), (I 1, B #0f)]))", ); } #[test] fn constant_data_list() { - let term = Term::::Constant( - Constant::Data(PlutusData::Array(vec![ - PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(0.into())), - PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())), - ])) - .into(), + round_trip( + Term::::Constant( + Constant::Data(PlutusData::Array(vec![ + PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(0.into())), + PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())), + ])) + .into(), + ), + "(con data (List [I 0, I 1]))", ); - assert_eq!(term.to_pretty(), "(con data (List [I 0, I 1]))"); } #[test] fn constant_data_int() { - let term = Term::::Constant( - Constant::Data(PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int( - 2.into(), - ))) - .into(), + round_trip( + Term::::Constant( + Constant::Data(PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int( + 2.into(), + ))) + .into(), + ), + "(con data (I 2))", ); - assert_eq!(term.to_pretty(), "(con data (I 2))"); // TODO: large integers currently encode as bytestrings, which isn't great /* @@ -171,8 +181,10 @@ fn constant_data_int() { #[test] fn constant_data_bytes() { - let term = Term::::Constant( - Constant::Data(PlutusData::BoundedBytes(vec![0x00, 0x1A].into())).into(), + round_trip( + Term::::Constant( + Constant::Data(PlutusData::BoundedBytes(vec![0x00, 0x1A].into())).into(), + ), + "(con data (B #001a))", ); - assert_eq!(term.to_pretty(), "(con data (B #001a))"); }