feat: start pretty printing

This commit is contained in:
rvcas
2022-06-17 17:40:59 -04:00
committed by Lucas
parent b95c04a9dd
commit 5a6ba40557
7 changed files with 315 additions and 44 deletions

View File

@@ -16,6 +16,5 @@ exclude = ["test_data/*"]
flat-rs = { path = "../flat", version = "0.0.2" }
hex = "0.4.3"
peg = "0.8.0"
strum = "0.24.0"
strum_macros = "0.24.0"
pretty = "0.11.3"
thiserror = "1.0.31"

View File

@@ -1,11 +1,11 @@
use std::{fmt::Display, str::FromStr};
use flat_rs::de;
use strum_macros::EnumString;
/// All the possible builtin functions in Untyped Plutus Core.
#[repr(u8)]
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, EnumString, PartialEq, Copy)]
#[strum(serialize_all = "camelCase")]
#[derive(Debug, Clone, PartialEq, Copy)]
pub enum DefaultFunction {
// Integer functions
AddInteger = 0,
@@ -28,7 +28,6 @@ pub enum DefaultFunction {
LessThanByteString = 16,
LessThanEqualsByteString = 17,
// Cryptography and hash functions
#[strum(serialize = "sha2_256")]
Sha2_256 = 18,
Sha3_256 = 19,
Blake2b_256 = 20,
@@ -195,3 +194,132 @@ impl TryFrom<u8> for DefaultFunction {
}
}
}
impl FromStr for DefaultFunction {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
use DefaultFunction::*;
match s {
"addInteger" => Ok(AddInteger),
"subtractInteger" => Ok(SubtractInteger),
"multiplyInteger" => Ok(MultiplyInteger),
"divideInteger" => Ok(DivideInteger),
"quotientInteger" => Ok(QuotientInteger),
"remainderInteger" => Ok(RemainderInteger),
"modInteger" => Ok(ModInteger),
"equalsInteger" => Ok(EqualsInteger),
"lessThanInteger" => Ok(LessThanInteger),
"lessThanEqualsInteger" => Ok(LessThanEqualsInteger),
"appendByteString" => Ok(AppendByteString),
"consByteString" => Ok(ConsByteString),
"sliceByteString" => Ok(SliceByteString),
"lengthOfByteString" => Ok(LengthOfByteString),
"indexByteString" => Ok(IndexByteString),
"equalsByteString" => Ok(EqualsByteString),
"lessThanByteString" => Ok(LessThanByteString),
"lessThanEqualsByteString" => Ok(LessThanEqualsByteString),
"sha2_256" => Ok(Sha2_256),
"sha3_256" => Ok(Sha3_256),
"blake2b_256" => Ok(Blake2b_256),
"verifySignature" => Ok(VerifySignature),
"verifyEcdsaSecp256k1Signature" => Ok(VerifyEcdsaSecp256k1Signature),
"verifySchnorrSecp256k1Signature" => Ok(VerifySchnorrSecp256k1Signature),
"appendString" => Ok(AppendString),
"equalsString" => Ok(EqualsString),
"encodeUtf8" => Ok(EncodeUtf8),
"decodeUtf8" => Ok(DecodeUtf8),
"ifThenElse" => Ok(IfThenElse),
"chooseUnit" => Ok(ChooseUnit),
"trace" => Ok(Trace),
"fstPair" => Ok(FstPair),
"sndPair" => Ok(SndPair),
"chooseList" => Ok(ChooseList),
"mkCons" => Ok(MkCons),
"headList" => Ok(HeadList),
"tailList" => Ok(TailList),
"nullList" => Ok(NullList),
"chooseData" => Ok(ChooseData),
"constrData" => Ok(ConstrData),
"mapData" => Ok(MapData),
"listData" => Ok(ListData),
"iData" => Ok(IData),
"bData" => Ok(BData),
"unConstrData" => Ok(UnConstrData),
"unMapData" => Ok(UnMapData),
"unListData" => Ok(UnListData),
"unIData" => Ok(UnIData),
"unBData" => Ok(UnBData),
"equalsData" => Ok(EqualsData),
"serialiseData" => Ok(SerialiseData),
"mkPairData" => Ok(MkPairData),
"mkNilData" => Ok(MkNilData),
"mkNilPairData" => Ok(MkNilPairData),
rest => Err(format!("Default Function not found - {}", rest)),
}
}
}
impl Display for DefaultFunction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use DefaultFunction::*;
match self {
AddInteger => write!(f, "addInteger"),
SubtractInteger => write!(f, "subtractInteger"),
MultiplyInteger => write!(f, "multiplyInteger"),
DivideInteger => write!(f, "divideInteger"),
QuotientInteger => write!(f, "quotientInteger"),
RemainderInteger => write!(f, "remainderInteger"),
ModInteger => write!(f, "modInteger"),
EqualsInteger => write!(f, "equalsInteger"),
LessThanInteger => write!(f, "lessThanInteger"),
LessThanEqualsInteger => write!(f, "lessThanEqualsInteger"),
AppendByteString => write!(f, "appendByteString"),
ConsByteString => write!(f, "consByteString"),
SliceByteString => write!(f, "sliceByteString"),
LengthOfByteString => write!(f, "lengthOfByteString"),
IndexByteString => write!(f, "indexByteString"),
EqualsByteString => write!(f, "equalsByteString"),
LessThanByteString => write!(f, "lessThanByteString"),
LessThanEqualsByteString => write!(f, "lessThanEqualsByteString"),
Sha2_256 => write!(f, "sha2_256"),
Sha3_256 => write!(f, "sha3_256"),
Blake2b_256 => write!(f, "blake2b_256"),
VerifySignature => write!(f, "verifySignature"),
VerifyEcdsaSecp256k1Signature => write!(f, "verifyEcdsaSecp256k1Signature"),
VerifySchnorrSecp256k1Signature => write!(f, "verifySchnorrSecp256k1Signature"),
AppendString => write!(f, "appendString"),
EqualsString => write!(f, "equalsString"),
EncodeUtf8 => write!(f, "encodeUtf8"),
DecodeUtf8 => write!(f, "decodeUtf8"),
IfThenElse => write!(f, "ifThenElse"),
ChooseUnit => write!(f, "chooseUnit"),
Trace => write!(f, "trace"),
FstPair => write!(f, "fstPair"),
SndPair => write!(f, "sndPair"),
ChooseList => write!(f, "chooseList"),
MkCons => write!(f, "mkCons"),
HeadList => write!(f, "headList"),
TailList => write!(f, "tailList"),
NullList => write!(f, "nullList"),
ChooseData => write!(f, "chooseData"),
ConstrData => write!(f, "constrData"),
MapData => write!(f, "mapData"),
ListData => write!(f, "listData"),
IData => write!(f, "iData"),
BData => write!(f, "bData"),
UnConstrData => write!(f, "unConstrData"),
UnMapData => write!(f, "unMapData"),
UnListData => write!(f, "unListData"),
UnIData => write!(f, "unIData"),
UnBData => write!(f, "unBData"),
EqualsData => write!(f, "equalsData"),
SerialiseData => write!(f, "serialiseData"),
MkPairData => write!(f, "mkPairData"),
MkNilData => write!(f, "mkNilData"),
MkNilPairData => write!(f, "mkNilPairData"),
}
}
}

View File

@@ -3,6 +3,7 @@ pub mod builtins;
mod debruijn;
mod flat;
pub mod parser;
mod pretty;
#[cfg(test)]
mod test;

108
crates/uplc/src/pretty.rs Normal file
View File

@@ -0,0 +1,108 @@
use pretty::RcDoc;
use crate::ast::{Constant, Name, Program, Term};
impl Program<Name> {
pub fn to_pretty(&self) -> String {
let mut w = Vec::new();
self.to_doc().render(20, &mut w).unwrap();
String::from_utf8(w).unwrap()
}
fn to_doc(&self) -> RcDoc<()> {
let version = format!("{}.{}.{}", self.version.0, self.version.1, self.version.2);
RcDoc::text("(")
.append(RcDoc::text("program"))
.append(RcDoc::line())
.append(RcDoc::text(version))
.append(RcDoc::line())
.append(self.term.to_doc())
.append(RcDoc::line_())
.append(RcDoc::text(")"))
}
}
impl Term<Name> {
fn to_doc(&self) -> RcDoc<()> {
match self {
Term::Var(name) => RcDoc::text(format!("{}_{}", name.text, name.unique)),
Term::Delay(term) => RcDoc::text("(")
.append(RcDoc::line_())
.append(RcDoc::text("delay"))
.append(RcDoc::line())
.append(term.to_doc())
.append(RcDoc::line_())
.append(RcDoc::text(")")),
Term::Lambda {
parameter_name,
body,
} => RcDoc::text("(")
.append(RcDoc::line_())
.append(RcDoc::text(format!(
"{}_{}",
parameter_name.text, parameter_name.unique
)))
.append(RcDoc::line())
.append(body.to_doc())
.append(RcDoc::line_())
.append(RcDoc::text(")")),
Term::Apply { function, argument } => RcDoc::text("[")
.append(RcDoc::line_())
.append(function.to_doc())
.append(RcDoc::line())
.append(argument.to_doc())
.append(RcDoc::line_())
.append(RcDoc::text("]")),
Term::Constant(constant) => RcDoc::text("(")
.append(RcDoc::text("con"))
.append(RcDoc::text(" "))
.append(constant.to_doc())
.append(RcDoc::text(")")),
Term::Force(term) => RcDoc::text("(")
.append(RcDoc::line_())
.append(RcDoc::text("force"))
.append(RcDoc::line())
.append(term.to_doc())
.append(RcDoc::line_())
.append(RcDoc::text(")")),
Term::Error => RcDoc::text("(")
.append(RcDoc::line_())
.append(RcDoc::text("error"))
.append(RcDoc::line_())
.append(RcDoc::text(")")),
Term::Builtin(builtin) => RcDoc::text("(")
.append(RcDoc::line_())
.append(RcDoc::text("builtin"))
.append(RcDoc::line())
.append(RcDoc::text(builtin.to_string()))
.append(RcDoc::line_())
.append(RcDoc::text(")")),
}
}
}
impl Constant {
fn to_doc(&self) -> RcDoc<()> {
match self {
Constant::Integer(i) => RcDoc::text("integer")
.append(RcDoc::space())
.append(RcDoc::as_string(i)),
Constant::ByteString(bs) => RcDoc::text("bytestring")
.append(RcDoc::space())
.append(RcDoc::text(hex::encode(bs))),
Constant::String(s) => RcDoc::text("string")
.append(RcDoc::space())
.append(RcDoc::text(s)),
Constant::Char(c) => unimplemented!("char: {}", c),
Constant::Unit => RcDoc::text("unit")
.append(RcDoc::space())
.append(RcDoc::text("()")),
Constant::Bool(b) => RcDoc::text("bool")
.append(RcDoc::space())
.append(RcDoc::text(if *b { "true" } else { "false" })),
}
}
}