feat: new fmt command and pretty printing works

This commit is contained in:
rvcas 2022-06-18 22:53:02 -04:00 committed by Lucas
parent 6a39d4349a
commit 6aae184848
6 changed files with 45 additions and 13 deletions

View File

@ -31,6 +31,9 @@ pub enum UplcCommand {
#[clap(short, long)] #[clap(short, long)]
out: Option<String>, out: Option<String>,
}, },
Fmt {
input: PathBuf,
},
} }
impl Default for Args { impl Default for Args {

View File

@ -47,6 +47,15 @@ fn main() -> anyhow::Result<()> {
fs::write(&out_name, &bytes)?; fs::write(&out_name, &bytes)?;
} }
} }
UplcCommand::Fmt { input } => {
let code = std::fs::read_to_string(&input)?;
let program = parser::program(&code)?;
let pretty = program.to_pretty();
fs::write(&input, pretty)?;
}
UplcCommand::Unflat { input, print, out } => { UplcCommand::Unflat { input, print, out } => {
let bytes = std::fs::read(&input)?; let bytes = std::fs::read(&input)?;

View File

@ -162,10 +162,14 @@ impl Converter {
pub fn debruijn_to_name(&mut self, term: Term<DeBruijn>) -> Result<Term<Name>, Error> { pub fn debruijn_to_name(&mut self, term: Term<DeBruijn>) -> Result<Term<Name>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(index) => Term::Var(Name { Term::Var(index) => {
text: String::from("i"), let unique = self.get_unique(index)?;
unique: self.get_unique(index)?,
}), Term::Var(Name {
text: format!("i_{}", unique),
unique,
})
}
Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_name(*term)?)), Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_name(*term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
@ -176,7 +180,7 @@ impl Converter {
let unique = self.get_unique(parameter_name)?; let unique = self.get_unique(parameter_name)?;
let name = Name { let name = Name {
text: String::from("i"), text: format!("i_{}", unique),
unique, unique,
}; };

View File

@ -8,7 +8,21 @@ impl Program<Name> {
self.to_doc().render(80, &mut w).unwrap(); self.to_doc().render(80, &mut w).unwrap();
String::from_utf8(w).unwrap() String::from_utf8(w)
.unwrap()
.lines()
// This is a hack to deal with blank newlines
// that end up with a bunch of useless whitespace
// because of the nesting
.map(|l| {
if l.chars().all(|c| c.is_whitespace()) {
"".to_string()
} else {
l.to_string()
}
})
.collect::<Vec<_>>()
.join("\n")
} }
fn to_doc(&self) -> RcDoc<()> { fn to_doc(&self) -> RcDoc<()> {
@ -29,7 +43,7 @@ impl Program<Name> {
impl Term<Name> { impl Term<Name> {
fn to_doc(&self) -> RcDoc<()> { fn to_doc(&self) -> RcDoc<()> {
match self { match self {
Term::Var(name) => RcDoc::text(format!("{}_{}", name.text, name.unique)), Term::Var(name) => RcDoc::text(&name.text),
Term::Delay(term) => RcDoc::text("(") Term::Delay(term) => RcDoc::text("(")
.append( .append(
RcDoc::text("delay") RcDoc::text("delay")
@ -46,10 +60,7 @@ impl Term<Name> {
.append( .append(
RcDoc::text("lam") RcDoc::text("lam")
.append(RcDoc::line()) .append(RcDoc::line())
.append(RcDoc::text(format!( .append(RcDoc::text(&parameter_name.text))
"{}_{}",
parameter_name.text, parameter_name.unique
)))
.append(RcDoc::line()) .append(RcDoc::line())
.append(body.to_doc()) .append(body.to_doc())
.nest(2), .nest(2),

View File

@ -24,6 +24,10 @@ fn integer() {
let name_program: Program<Name> = decoded_program.try_into().unwrap(); let name_program: Program<Name> = decoded_program.try_into().unwrap();
assert_eq!(parsed_program, name_program); assert_eq!(parsed_program, name_program);
let pretty = name_program.to_pretty();
assert_eq!(pretty, code);
} }
#[test] #[test]

View File

@ -1,3 +1,4 @@
(program 11.22.33 (program
(con integer 11) 11.22.33
(con integer 11)
) )