Add command line option to shrink uplc

This commit is contained in:
Niels Mündler 2023-12-13 23:12:18 +01:00 committed by Kasey
parent b6acdde552
commit 4c60be368e
3 changed files with 101 additions and 1 deletions

View File

@ -57,7 +57,7 @@ pub fn exec(
} }
} }
fn encode<'a, T>(program: Program<T>, cbor: bool, hex: bool) -> miette::Result<()> pub(crate) fn encode<'a, T>(program: Program<T>, cbor: bool, hex: bool) -> miette::Result<()>
where where
T: Binder<'a> + std::fmt::Debug, T: Binder<'a> + std::fmt::Debug,
{ {

View File

@ -2,6 +2,7 @@ mod decode;
mod encode; mod encode;
mod eval; mod eval;
mod fmt; mod fmt;
mod shrink;
use clap::{Subcommand, ValueEnum}; use clap::{Subcommand, ValueEnum};
@ -21,6 +22,8 @@ pub enum Cmd {
Encode(encode::Args), Encode(encode::Args),
#[clap(alias = "unflat")] #[clap(alias = "unflat")]
Decode(decode::Args), Decode(decode::Args),
#[clap(alias = "optimize")]
Shrink(shrink::Args)
} }
pub fn exec(cmd: Cmd) -> miette::Result<()> { pub fn exec(cmd: Cmd) -> miette::Result<()> {
@ -29,5 +32,6 @@ pub fn exec(cmd: Cmd) -> miette::Result<()> {
Cmd::Eval(args) => eval::exec(args), Cmd::Eval(args) => eval::exec(args),
Cmd::Encode(args) => encode::exec(args), Cmd::Encode(args) => encode::exec(args),
Cmd::Decode(args) => decode::exec(args), Cmd::Decode(args) => decode::exec(args),
Cmd::Shrink(args) => shrink::exec(args),
} }
} }

View File

@ -0,0 +1,96 @@
use miette::IntoDiagnostic;
use std::{path::PathBuf};
use uplc::ast::{DeBruijn, Name, NamedDeBruijn, Program};
use uplc::optimize::aiken_optimize_and_intern;
use super::{encode, Format};
#[derive(clap::Args)]
/// Shrink / Optimize UPLC code using a variety of optimization steps
pub struct Args {
/// Flat encoded Untyped Plutus Core file
input: PathBuf,
// Format to convert from
#[clap(long, default_value = "debruijn")]
from: Format,
// Format to convert into
#[clap(long, default_value = "debruijn")]
to: Format,
/// Input file contains cbor encoded flat bytes
#[clap(short, long)]
cbor: bool,
/// Input file contents will be hex decoded
#[clap(long)]
hex: bool,
}
pub fn exec(
Args {
input,
from,
to,
cbor,
hex,
}: Args,
) -> miette::Result<()> {
let bytes = if hex {
let hex_bytes = std::fs::read_to_string(&input).into_diagnostic()?;
hex::decode(hex_bytes.trim()).into_diagnostic()?
} else {
std::fs::read(&input).into_diagnostic()?
};
let program: Program<Name> = match from {
Format::Name => {
if cbor {
let mut flat_buffer = Vec::new();
Program::from_cbor(&bytes, &mut flat_buffer).into_diagnostic()?
} else {
Program::from_flat(&bytes).into_diagnostic()?
}
}
Format::NamedDebruijn => {
let program: Program<NamedDeBruijn> = if cbor {
let mut flat_buffer = Vec::new();
Program::from_cbor(&bytes, &mut flat_buffer).into_diagnostic()?
} else {
Program::from_flat(&bytes).into_diagnostic()?
};
program.try_into().unwrap()
}
Format::Debruijn => {
let program: Program<DeBruijn> = if cbor {
let mut flat_buffer = Vec::new();
Program::from_cbor(&bytes, &mut flat_buffer).into_diagnostic()?
} else {
Program::from_flat(&bytes).into_diagnostic()?
};
program.try_into().unwrap()
}
};
let optimized_program = aiken_optimize_and_intern(program);
match to {
Format::Name => encode::encode(optimized_program, cbor, hex),
Format::NamedDebruijn => {
let program: Program<NamedDeBruijn> = optimized_program.try_into().into_diagnostic()?;
encode::encode(program, cbor, hex)
}
Format::Debruijn => {
let program: Program<DeBruijn> = optimized_program.try_into().into_diagnostic()?;
encode::encode(program, cbor, hex)
}
}
}