From 377c5c206cae287730f3c9a8683b0f8e7245d78f Mon Sep 17 00:00:00 2001 From: rvcas Date: Sat, 4 Jun 2022 12:16:56 -0400 Subject: [PATCH] feat: better errors for debruijn converter --- Cargo.lock | 21 ++++++++++++ crates/cli/src/main.rs | 2 +- crates/uplc/Cargo.toml | 1 + crates/uplc/example/integer.uplc | 2 +- crates/uplc/src/ast.rs | 59 +++++++++++++++----------------- crates/uplc/src/debruijn.rs | 20 +++++++---- 6 files changed, 66 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7869aa86..b12c063e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,6 +259,26 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.0" @@ -275,6 +295,7 @@ dependencies = [ "hex", "strum", "strum_macros", + "thiserror", ] [[package]] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 47bdd860..ed0a9cc0 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -25,7 +25,7 @@ fn main() -> anyhow::Result<()> { println!(); - let program_nd: Program = program.try_into().unwrap(); + let program_nd: Program = program.try_into()?; println!("\nNamed De Bruijn:"); println!("{:#?}", program_nd); diff --git a/crates/uplc/Cargo.toml b/crates/uplc/Cargo.toml index 6df70bf4..eccca392 100644 --- a/crates/uplc/Cargo.toml +++ b/crates/uplc/Cargo.toml @@ -12,3 +12,4 @@ flat = { path = "../flat" } hex = "0.4.3" strum = "0.24.0" strum_macros = "0.24.0" +thiserror = "1.0.31" diff --git a/crates/uplc/example/integer.uplc b/crates/uplc/example/integer.uplc index 6ac9f3c9..86df1598 100644 --- a/crates/uplc/example/integer.uplc +++ b/crates/uplc/example/integer.uplc @@ -1,3 +1,3 @@ (program 11.22.33 - (lam x (lam x x)) + (lam x (lam x y)) ) \ No newline at end of file diff --git a/crates/uplc/src/ast.rs b/crates/uplc/src/ast.rs index ea766a6f..2aaf408f 100644 --- a/crates/uplc/src/ast.rs +++ b/crates/uplc/src/ast.rs @@ -1,4 +1,9 @@ -use crate::{builtins::DefaultFunction, debruijn::Converter}; +use std::fmt::Display; + +use crate::{ + builtins::DefaultFunction, + debruijn::{self, Converter}, +}; #[derive(Debug, Clone, PartialEq)] pub struct Program { @@ -79,6 +84,12 @@ impl From for isize { } } +impl Display for Unique { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + #[derive(Debug, Clone, PartialEq)] pub struct NamedDeBruijn { pub text: String, @@ -122,7 +133,7 @@ impl From for NamedDeBruijn { } impl TryFrom> for Program { - type Error = String; + type Error = debruijn::Error; fn try_from(value: Program) -> Result { Ok(Program:: { @@ -133,23 +144,19 @@ impl TryFrom> for Program { } impl TryFrom> for Term { - type Error = String; + type Error = debruijn::Error; - fn try_from( - value: Term, - ) -> Result as TryFrom>>::Error> { + fn try_from(value: Term) -> Result { let mut converter = Converter::new(); - let term = converter - .name_to_named_debruijn(value) - .map_err(|err| err.to_string())?; + let term = converter.name_to_named_debruijn(value)?; Ok(term) } } impl TryFrom> for Program { - type Error = String; + type Error = debruijn::Error; fn try_from(value: Program) -> Result { Ok(Program:: { @@ -160,21 +167,19 @@ impl TryFrom> for Program { } impl TryFrom> for Term { - type Error = String; + type Error = debruijn::Error; - fn try_from(value: Term) -> Result as TryFrom>>::Error> { + fn try_from(value: Term) -> Result { let mut converter = Converter::new(); - let term = converter - .name_to_debruijn(value) - .map_err(|err| err.to_string())?; + let term = converter.name_to_debruijn(value)?; Ok(term) } } impl TryFrom> for Program { - type Error = String; + type Error = debruijn::Error; fn try_from(value: Program) -> Result { Ok(Program:: { @@ -185,16 +190,12 @@ impl TryFrom> for Program { } impl TryFrom> for Term { - type Error = String; + type Error = debruijn::Error; - fn try_from( - value: Term, - ) -> Result as TryFrom>>::Error> { + fn try_from(value: Term) -> Result { let mut converter = Converter::new(); - let term = converter - .named_debruijn_to_name(value) - .map_err(|err| err.to_string())?; + let term = converter.named_debruijn_to_name(value)?; Ok(term) } @@ -218,7 +219,7 @@ impl From> for Term { } impl TryFrom> for Program { - type Error = String; + type Error = debruijn::Error; fn try_from(value: Program) -> Result { Ok(Program:: { @@ -229,16 +230,12 @@ impl TryFrom> for Program { } impl TryFrom> for Term { - type Error = String; + type Error = debruijn::Error; - fn try_from( - value: Term, - ) -> Result as TryFrom>>::Error> { + fn try_from(value: Term) -> Result { let mut converter = Converter::new(); - let term = converter - .debruijn_to_name(value) - .map_err(|err| err.to_string())?; + let term = converter.debruijn_to_name(value)?; Ok(term) } diff --git a/crates/uplc/src/debruijn.rs b/crates/uplc/src/debruijn.rs index 047e4608..294b184a 100644 --- a/crates/uplc/src/debruijn.rs +++ b/crates/uplc/src/debruijn.rs @@ -1,10 +1,18 @@ use std::collections::HashMap; +use thiserror::Error; + use crate::ast::{DeBruijn, Name, NamedDeBruijn, Term, Unique}; #[derive(Debug, Copy, Clone)] struct Level(usize); +#[derive(Error, Debug)] +pub enum Error { + #[error("Free Unique: `{0}`")] + FreeUnique(Unique), +} + pub struct Converter { current_level: Level, levels: Vec>, @@ -21,7 +29,7 @@ impl Converter { pub fn name_to_named_debruijn( &mut self, term: Term, - ) -> anyhow::Result> { + ) -> Result, Error> { let converted_term = match term { Term::Var(Name { text, unique }) => Term::Var(NamedDeBruijn { text, @@ -65,7 +73,7 @@ impl Converter { Ok(converted_term) } - pub fn name_to_debruijn(&mut self, term: Term) -> anyhow::Result> { + pub fn name_to_debruijn(&mut self, term: Term) -> Result, Error> { let converted_term = match term { Term::Var(Name { unique, .. }) => Term::Var(self.get_index(unique)?), Term::Delay(term) => Term::Delay(Box::new(self.name_to_debruijn(*term)?)), @@ -104,7 +112,7 @@ impl Converter { pub fn named_debruijn_to_name( &mut self, _term: Term, - ) -> anyhow::Result> { + ) -> Result, Error> { todo!() } @@ -130,7 +138,7 @@ impl Converter { } } - pub fn debruijn_to_name(&mut self, _term: Term) -> anyhow::Result> { + pub fn debruijn_to_name(&mut self, _term: Term) -> Result, Error> { todo!() } @@ -156,7 +164,7 @@ impl Converter { } } - fn get_index(&mut self, unique: Unique) -> anyhow::Result { + fn get_index(&mut self, unique: Unique) -> Result { for scope in self.levels.iter().rev() { if let Some(found_level) = scope.get(&unique) { let index = self.current_level.0 - found_level.0; @@ -165,7 +173,7 @@ impl Converter { } } - anyhow::bail!("Free unique: {}", isize::from(unique)) + Err(Error::FreeUnique(unique)) } fn declare_unique(&mut self, unique: Unique) {