Add all but data parsing
Updates the parsing to the standard, *except* for Data, since that'll be more involved
This commit is contained in:
parent
a48c45b737
commit
6d9a95ef2d
|
@ -158,17 +158,17 @@ peg::parser! {
|
||||||
= "data" _+ d:data() { Constant::Data(d) }
|
= "data" _+ d:data() { Constant::Data(d) }
|
||||||
|
|
||||||
rule constant_list() -> Constant
|
rule constant_list() -> Constant
|
||||||
= "list" _* "<" _* t:type_info() _* ">" _+ ls:list(Some(&t)) {
|
= "(" _* "list" _* t:type_info() _* ")" _+ ls:list(Some(&t)) {
|
||||||
Constant::ProtoList(t, ls)
|
Constant::ProtoList(t, ls)
|
||||||
}
|
}
|
||||||
|
|
||||||
rule constant_pair() -> Constant
|
rule constant_pair() -> Constant
|
||||||
= "pair" _* "<" _* l:type_info() _* "," r:type_info() _* ">" _+ p:pair(Some((&l, &r))) {
|
= "(" _* "pair" _+ l:type_info() _+ r:type_info() _* ")" _+ p:pair(Some((&l, &r))) {
|
||||||
Constant::ProtoPair(l, r, p.0.into(), p.1.into())
|
Constant::ProtoPair(l, r, p.0.into(), p.1.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
rule pair(type_info: Option<(&Type, &Type)>) -> (Constant, Constant)
|
rule pair(type_info: Option<(&Type, &Type)>) -> (Constant, Constant)
|
||||||
= "[" _* 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
|
rule number() -> isize
|
||||||
= n:$("-"* ['0'..='9']+) {? n.parse().or(Err("isize")) }
|
= n:$("-"* ['0'..='9']+) {? n.parse().or(Err("isize")) }
|
||||||
|
@ -262,10 +262,10 @@ peg::parser! {
|
||||||
/ _* "bytestring" { Type::ByteString }
|
/ _* "bytestring" { Type::ByteString }
|
||||||
/ _* "string" { Type::String }
|
/ _* "string" { Type::String }
|
||||||
/ _* "data" { Type::Data }
|
/ _* "data" { Type::Data }
|
||||||
/ _* "list" _* "<" _* t:type_info() _* ">" {
|
/ _* "(" _* "list" _+ t:type_info() _* ")" _* {
|
||||||
Type::List(t.into())
|
Type::List(t.into())
|
||||||
}
|
}
|
||||||
/ _* "pair" _* "<" l:type_info() "," r:type_info() ">" {
|
/ _* "(" _* "pair" _+ l:type_info() _+ r:type_info() _* ")" _* {
|
||||||
Type::Pair(l.into(), r.into())
|
Type::Pair(l.into(), r.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,64 @@
|
||||||
use num_bigint::ToBigInt;
|
use num_bigint::ToBigInt;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{Constant, DeBruijn, Term, Type},
|
ast::{Constant, Term, Type, Name},
|
||||||
Constr, PlutusData,
|
Constr, PlutusData, parser::term,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Examples sourced from https://github.com/input-output-hk/plutus/issues/4751#issuecomment-1538377273
|
// Examples sourced from https://github.com/input-output-hk/plutus/issues/4751#issuecomment-1538377273
|
||||||
|
|
||||||
|
fn round_trip(old_term: Term::<Name>, 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]
|
#[test]
|
||||||
fn constant_list_integer() {
|
fn constant_list_integer() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::ProtoList(
|
Term::<Name>::Constant(
|
||||||
Type::Integer.into(),
|
Constant::ProtoList(
|
||||||
vec![
|
Type::Integer.into(),
|
||||||
Constant::Integer(0.to_bigint().unwrap()),
|
vec![
|
||||||
Constant::Integer(1.to_bigint().unwrap()),
|
Constant::Integer(0.to_bigint().unwrap()),
|
||||||
Constant::Integer(2.to_bigint().unwrap()),
|
Constant::Integer(1.to_bigint().unwrap()),
|
||||||
],
|
Constant::Integer(2.to_bigint().unwrap()),
|
||||||
)
|
],
|
||||||
.into(),
|
)
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
"(con (list integer) [0, 1, 2])",
|
||||||
);
|
);
|
||||||
assert_eq!(term.to_pretty(), "(con (list integer) [0, 1, 2])");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_pair_bool_bytestring() {
|
fn constant_pair_bool_bytestring() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::ProtoPair(
|
Term::<Name>::Constant(
|
||||||
Type::Bool.into(),
|
Constant::ProtoPair(
|
||||||
Type::ByteString.into(),
|
Type::Bool.into(),
|
||||||
Constant::Bool(true).into(),
|
Type::ByteString.into(),
|
||||||
Constant::ByteString(vec![0x01, 0x23, 0x45]).into(),
|
Constant::Bool(true).into(),
|
||||||
)
|
Constant::ByteString(vec![0x01, 0x23, 0x45]).into(),
|
||||||
.into(),
|
)
|
||||||
);
|
.into(),
|
||||||
assert_eq!(
|
),
|
||||||
term.to_pretty(),
|
"(con (pair bool bytestring) (True, #012345))",
|
||||||
"(con (pair bool bytestring) (True, #012345))"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_pair_unit_string() {
|
fn constant_pair_unit_string() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::ProtoPair(
|
Term::<Name>::Constant(
|
||||||
Type::Unit.into(),
|
Constant::ProtoPair(
|
||||||
Type::String.into(),
|
Type::Unit.into(),
|
||||||
Constant::Unit.into(),
|
Type::String.into(),
|
||||||
Constant::String("hello universe".into()).into(),
|
Constant::Unit.into(),
|
||||||
)
|
Constant::String("hello universe".into()).into(),
|
||||||
.into(),
|
)
|
||||||
);
|
.into(),
|
||||||
assert_eq!(
|
),
|
||||||
term.to_pretty(),
|
"(con (pair unit string) ((), \"hello universe\"))",
|
||||||
"(con (pair unit string) ((), \"hello universe\"))"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,100 +67,104 @@ fn constant_deeply_nested_list() {
|
||||||
let t0 = Type::Integer;
|
let t0 = Type::Integer;
|
||||||
let t1 = Type::List(t0.clone().into());
|
let t1 = Type::List(t0.clone().into());
|
||||||
let t2 = Type::List(t1.clone().into());
|
let t2 = Type::List(t1.clone().into());
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::ProtoList(
|
Term::<Name>::Constant(
|
||||||
t2,
|
Constant::ProtoList(
|
||||||
vec![
|
t2,
|
||||||
Constant::ProtoList(
|
vec![
|
||||||
t1.clone(),
|
Constant::ProtoList(
|
||||||
vec![
|
t1.clone(),
|
||||||
Constant::ProtoList(
|
vec![
|
||||||
t0.clone(),
|
Constant::ProtoList(
|
||||||
vec![Constant::Integer(-1.to_bigint().unwrap())],
|
t0.clone(),
|
||||||
),
|
vec![Constant::Integer(-1.to_bigint().unwrap())],
|
||||||
Constant::ProtoList(t0.clone(), vec![]),
|
),
|
||||||
],
|
Constant::ProtoList(t0.clone(), vec![]),
|
||||||
),
|
],
|
||||||
Constant::ProtoList(
|
),
|
||||||
t1.clone(),
|
Constant::ProtoList(
|
||||||
vec![
|
t1.clone(),
|
||||||
Constant::ProtoList(t0.clone(), vec![]),
|
vec![
|
||||||
Constant::ProtoList(
|
Constant::ProtoList(t0.clone(), vec![]),
|
||||||
t0.clone(),
|
Constant::ProtoList(
|
||||||
vec![
|
t0.clone(),
|
||||||
Constant::Integer(2.to_bigint().unwrap()),
|
vec![
|
||||||
Constant::Integer(3.to_bigint().unwrap()),
|
Constant::Integer(2.to_bigint().unwrap()),
|
||||||
],
|
Constant::Integer(3.to_bigint().unwrap()),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
)
|
],
|
||||||
.into(),
|
)
|
||||||
);
|
.into(),
|
||||||
assert_eq!(
|
),
|
||||||
term.to_pretty(),
|
"(con (list (list (list integer))) [[[-1], []], [[], [2, 3]]])",
|
||||||
"(con (list (list (list integer))) [[[-1], []], [[], [2, 3]]])"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_data_constr() {
|
fn constant_data_constr() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::Data(PlutusData::Constr(Constr::<PlutusData> {
|
Term::<Name>::Constant(
|
||||||
tag: 1,
|
Constant::Data(PlutusData::Constr(Constr::<PlutusData> {
|
||||||
any_constructor: None,
|
tag: 1,
|
||||||
fields: vec![PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(
|
any_constructor: None,
|
||||||
2.into(),
|
fields: vec![PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(
|
||||||
))],
|
2.into(),
|
||||||
}))
|
))],
|
||||||
.into(),
|
}))
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
"(con data (Constr 1 [I 2]))",
|
||||||
);
|
);
|
||||||
assert_eq!(term.to_pretty(), "(con data (Constr 1 [I 2]))");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_data_map() {
|
fn constant_data_map() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::Data(PlutusData::Map(uplc::KeyValuePairs::Def(vec![
|
Term::<Name>::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(0.into())),
|
||||||
),
|
PlutusData::BoundedBytes(vec![0x00].into()),
|
||||||
(
|
),
|
||||||
PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())),
|
(
|
||||||
PlutusData::BoundedBytes(vec![0x0f].into()),
|
PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())),
|
||||||
),
|
PlutusData::BoundedBytes(vec![0x0f].into()),
|
||||||
])))
|
),
|
||||||
.into(),
|
])))
|
||||||
);
|
.into(),
|
||||||
assert_eq!(
|
),
|
||||||
term.to_pretty(),
|
"(con data (Map [(I 0, B #00), (I 1, B #0f)]))",
|
||||||
"(con data (Map [(I 0, B #00), (I 1, B #0f)]))"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_data_list() {
|
fn constant_data_list() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::Data(PlutusData::Array(vec![
|
Term::<Name>::Constant(
|
||||||
PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(0.into())),
|
Constant::Data(PlutusData::Array(vec![
|
||||||
PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())),
|
PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(0.into())),
|
||||||
]))
|
PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(1.into())),
|
||||||
.into(),
|
]))
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
"(con data (List [I 0, I 1]))",
|
||||||
);
|
);
|
||||||
assert_eq!(term.to_pretty(), "(con data (List [I 0, I 1]))");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_data_int() {
|
fn constant_data_int() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::Data(PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(
|
Term::<Name>::Constant(
|
||||||
2.into(),
|
Constant::Data(PlutusData::BigInt(pallas_primitives::alonzo::BigInt::Int(
|
||||||
)))
|
2.into(),
|
||||||
.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
|
// TODO: large integers currently encode as bytestrings, which isn't great
|
||||||
/*
|
/*
|
||||||
|
@ -171,8 +181,10 @@ fn constant_data_int() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_data_bytes() {
|
fn constant_data_bytes() {
|
||||||
let term = Term::<DeBruijn>::Constant(
|
round_trip(
|
||||||
Constant::Data(PlutusData::BoundedBytes(vec![0x00, 0x1A].into())).into(),
|
Term::<Name>::Constant(
|
||||||
|
Constant::Data(PlutusData::BoundedBytes(vec![0x00, 0x1A].into())).into(),
|
||||||
|
),
|
||||||
|
"(con data (B #001a))",
|
||||||
);
|
);
|
||||||
assert_eq!(term.to_pretty(), "(con data (B #001a))");
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue