feat: start pretty printing
This commit is contained in:
@@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
108
crates/uplc/src/pretty.rs
Normal 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" })),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user