feat: better errors for debruijn converter

This commit is contained in:
rvcas 2022-06-04 12:16:56 -04:00
parent 2f51b23e7e
commit 377c5c206c
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
6 changed files with 66 additions and 39 deletions

21
Cargo.lock generated
View File

@ -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]]

View File

@ -25,7 +25,7 @@ fn main() -> anyhow::Result<()> {
println!();
let program_nd: Program<NamedDeBruijn> = program.try_into().unwrap();
let program_nd: Program<NamedDeBruijn> = program.try_into()?;
println!("\nNamed De Bruijn:");
println!("{:#?}", program_nd);

View File

@ -12,3 +12,4 @@ flat = { path = "../flat" }
hex = "0.4.3"
strum = "0.24.0"
strum_macros = "0.24.0"
thiserror = "1.0.31"

View File

@ -1,3 +1,3 @@
(program 11.22.33
(lam x (lam x x))
(lam x (lam x y))
)

View File

@ -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<T> {
@ -79,6 +84,12 @@ impl From<Unique> 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<DeBruijn> for NamedDeBruijn {
}
impl TryFrom<Program<Name>> for Program<NamedDeBruijn> {
type Error = String;
type Error = debruijn::Error;
fn try_from(value: Program<Name>) -> Result<Self, Self::Error> {
Ok(Program::<NamedDeBruijn> {
@ -133,23 +144,19 @@ impl TryFrom<Program<Name>> for Program<NamedDeBruijn> {
}
impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
type Error = String;
type Error = debruijn::Error;
fn try_from(
value: Term<Name>,
) -> Result<Self, <Term<NamedDeBruijn> as TryFrom<Term<Name>>>::Error> {
fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> {
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<Program<Name>> for Program<DeBruijn> {
type Error = String;
type Error = debruijn::Error;
fn try_from(value: Program<Name>) -> Result<Self, Self::Error> {
Ok(Program::<DeBruijn> {
@ -160,21 +167,19 @@ impl TryFrom<Program<Name>> for Program<DeBruijn> {
}
impl TryFrom<Term<Name>> for Term<DeBruijn> {
type Error = String;
type Error = debruijn::Error;
fn try_from(value: Term<Name>) -> Result<Self, <Term<DeBruijn> as TryFrom<Term<Name>>>::Error> {
fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> {
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<Program<NamedDeBruijn>> for Program<Name> {
type Error = String;
type Error = debruijn::Error;
fn try_from(value: Program<NamedDeBruijn>) -> Result<Self, Self::Error> {
Ok(Program::<Name> {
@ -185,16 +190,12 @@ impl TryFrom<Program<NamedDeBruijn>> for Program<Name> {
}
impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
type Error = String;
type Error = debruijn::Error;
fn try_from(
value: Term<NamedDeBruijn>,
) -> Result<Self, <Term<Name> as TryFrom<Term<NamedDeBruijn>>>::Error> {
fn try_from(value: Term<NamedDeBruijn>) -> Result<Self, debruijn::Error> {
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<Term<NamedDeBruijn>> for Term<DeBruijn> {
}
impl TryFrom<Program<DeBruijn>> for Program<Name> {
type Error = String;
type Error = debruijn::Error;
fn try_from(value: Program<DeBruijn>) -> Result<Self, Self::Error> {
Ok(Program::<Name> {
@ -229,16 +230,12 @@ impl TryFrom<Program<DeBruijn>> for Program<Name> {
}
impl TryFrom<Term<DeBruijn>> for Term<Name> {
type Error = String;
type Error = debruijn::Error;
fn try_from(
value: Term<DeBruijn>,
) -> Result<Self, <Term<Name> as TryFrom<Term<DeBruijn>>>::Error> {
fn try_from(value: Term<DeBruijn>) -> Result<Self, debruijn::Error> {
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)
}

View File

@ -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<HashMap<Unique, Level>>,
@ -21,7 +29,7 @@ impl Converter {
pub fn name_to_named_debruijn(
&mut self,
term: Term<Name>,
) -> anyhow::Result<Term<NamedDeBruijn>> {
) -> Result<Term<NamedDeBruijn>, 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<Name>) -> anyhow::Result<Term<DeBruijn>> {
pub fn name_to_debruijn(&mut self, term: Term<Name>) -> Result<Term<DeBruijn>, 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<NamedDeBruijn>,
) -> anyhow::Result<Term<Name>> {
) -> Result<Term<Name>, Error> {
todo!()
}
@ -130,7 +138,7 @@ impl Converter {
}
}
pub fn debruijn_to_name(&mut self, _term: Term<DeBruijn>) -> anyhow::Result<Term<Name>> {
pub fn debruijn_to_name(&mut self, _term: Term<DeBruijn>) -> Result<Term<Name>, Error> {
todo!()
}
@ -156,7 +164,7 @@ impl Converter {
}
}
fn get_index(&mut self, unique: Unique) -> anyhow::Result<DeBruijn> {
fn get_index(&mut self, unique: Unique) -> Result<DeBruijn, Error> {
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) {