feat: start pretty printing
This commit is contained in:
parent
b95c04a9dd
commit
5a6ba40557
|
@ -17,6 +17,12 @@ version = "1.0.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
|
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -40,6 +46,12 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.1.18"
|
version = "3.1.18"
|
||||||
|
@ -136,6 +148,15 @@ version = "0.2.126"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "6.0.1"
|
version = "6.0.1"
|
||||||
|
@ -169,6 +190,18 @@ version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9b0efd3ba03c3a409d44d60425f279ec442bcf0b9e63ff4e410da31c8b0f69f"
|
checksum = "f9b0efd3ba03c3a409d44d60425f279ec442bcf0b9e63ff4e410da31c8b0f69f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83f3aa1e3ca87d3b124db7461265ac176b40c277f37e503eaa29c9c75c037846"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"log",
|
||||||
|
"typed-arena",
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -211,37 +244,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustversion"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strum"
|
|
||||||
version = "0.24.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strum_macros"
|
|
||||||
version = "0.24.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef"
|
|
||||||
dependencies = [
|
|
||||||
"heck",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"rustversion",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.95"
|
version = "1.0.95"
|
||||||
|
@ -288,12 +296,24 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typed-arena"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uplc"
|
name = "uplc"
|
||||||
version = "0.0.2"
|
version = "0.0.2"
|
||||||
|
@ -301,8 +321,7 @@ dependencies = [
|
||||||
"flat-rs",
|
"flat-rs",
|
||||||
"hex",
|
"hex",
|
||||||
"peg",
|
"peg",
|
||||||
"strum",
|
"pretty",
|
||||||
"strum_macros",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use clap::{Parser, Subcommand};
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
#[clap(propagate_version = true)]
|
#[clap(propagate_version = true)]
|
||||||
pub enum Cli {
|
pub enum Args {
|
||||||
/// A subcommand for working with Untyped Plutus Core
|
/// A subcommand for working with Untyped Plutus Core
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
Uplc(UplcCommand),
|
Uplc(UplcCommand),
|
||||||
|
@ -28,10 +28,12 @@ pub enum UplcCommand {
|
||||||
input: PathBuf,
|
input: PathBuf,
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
print: bool,
|
print: bool,
|
||||||
|
#[clap(short, long)]
|
||||||
|
out: Option<String>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Cli {
|
impl Default for Args {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::parse()
|
Self::parse()
|
||||||
}
|
}
|
|
@ -5,13 +5,15 @@ use uplc::{
|
||||||
parser,
|
parser,
|
||||||
};
|
};
|
||||||
|
|
||||||
use aiken::{Cli, UplcCommand};
|
mod args;
|
||||||
|
|
||||||
|
use args::{Args, UplcCommand};
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let args = Cli::default();
|
let args = Args::default();
|
||||||
|
|
||||||
match args {
|
match args {
|
||||||
Cli::Uplc(uplc) => match uplc {
|
Args::Uplc(uplc) => match uplc {
|
||||||
UplcCommand::Flat { input, print, out } => {
|
UplcCommand::Flat { input, print, out } => {
|
||||||
let code = std::fs::read_to_string(&input)?;
|
let code = std::fs::read_to_string(&input)?;
|
||||||
|
|
||||||
|
@ -22,17 +24,19 @@ fn main() -> anyhow::Result<()> {
|
||||||
let bytes = program.to_flat()?;
|
let bytes = program.to_flat()?;
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
|
let mut output = String::new();
|
||||||
|
|
||||||
for (i, byte) in bytes.iter().enumerate() {
|
for (i, byte) in bytes.iter().enumerate() {
|
||||||
print!("{:08b}", byte);
|
output.push_str(&format!("{:08b}", byte));
|
||||||
|
|
||||||
if (i + 1) % 4 == 0 {
|
if (i + 1) % 4 == 0 {
|
||||||
println!();
|
output.push('\n');
|
||||||
} else {
|
} else {
|
||||||
print!(" ");
|
output.push(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!();
|
println!("{}", output);
|
||||||
} else {
|
} else {
|
||||||
let out_name = if let Some(out) = out {
|
let out_name = if let Some(out) = out {
|
||||||
out
|
out
|
||||||
|
@ -43,15 +47,25 @@ fn main() -> anyhow::Result<()> {
|
||||||
fs::write(&out_name, &bytes)?;
|
fs::write(&out_name, &bytes)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UplcCommand::Unflat { input, print } => {
|
UplcCommand::Unflat { input, print, out } => {
|
||||||
let bytes = std::fs::read(&input)?;
|
let bytes = std::fs::read(&input)?;
|
||||||
|
|
||||||
let program = Program::<DeBruijn>::from_flat(&bytes)?;
|
let program = Program::<DeBruijn>::from_flat(&bytes)?;
|
||||||
|
|
||||||
let program: Program<Name> = program.try_into()?;
|
let program: Program<Name> = program.try_into()?;
|
||||||
|
|
||||||
|
let pretty = program.to_pretty();
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
println!("{:#?}", program);
|
println!("{}", pretty);
|
||||||
|
} else {
|
||||||
|
let out_name = if let Some(out) = out {
|
||||||
|
out
|
||||||
|
} else {
|
||||||
|
format!("{}.uplc", input.file_stem().unwrap().to_str().unwrap())
|
||||||
|
};
|
||||||
|
|
||||||
|
fs::write(&out_name, pretty)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,6 +16,5 @@ exclude = ["test_data/*"]
|
||||||
flat-rs = { path = "../flat", version = "0.0.2" }
|
flat-rs = { path = "../flat", version = "0.0.2" }
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
peg = "0.8.0"
|
peg = "0.8.0"
|
||||||
strum = "0.24.0"
|
pretty = "0.11.3"
|
||||||
strum_macros = "0.24.0"
|
|
||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
use flat_rs::de;
|
use flat_rs::de;
|
||||||
use strum_macros::EnumString;
|
|
||||||
|
|
||||||
/// All the possible builtin functions in Untyped Plutus Core.
|
/// All the possible builtin functions in Untyped Plutus Core.
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Debug, Clone, EnumString, PartialEq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||||
#[strum(serialize_all = "camelCase")]
|
|
||||||
pub enum DefaultFunction {
|
pub enum DefaultFunction {
|
||||||
// Integer functions
|
// Integer functions
|
||||||
AddInteger = 0,
|
AddInteger = 0,
|
||||||
|
@ -28,7 +28,6 @@ pub enum DefaultFunction {
|
||||||
LessThanByteString = 16,
|
LessThanByteString = 16,
|
||||||
LessThanEqualsByteString = 17,
|
LessThanEqualsByteString = 17,
|
||||||
// Cryptography and hash functions
|
// Cryptography and hash functions
|
||||||
#[strum(serialize = "sha2_256")]
|
|
||||||
Sha2_256 = 18,
|
Sha2_256 = 18,
|
||||||
Sha3_256 = 19,
|
Sha3_256 = 19,
|
||||||
Blake2b_256 = 20,
|
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 debruijn;
|
||||||
mod flat;
|
mod flat;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
mod pretty;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
|
@ -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" })),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue