feat: better errors for debruijn converter
This commit is contained in:
parent
2f51b23e7e
commit
377c5c206c
|
@ -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]]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -12,3 +12,4 @@ flat = { path = "../flat" }
|
|||
hex = "0.4.3"
|
||||
strum = "0.24.0"
|
||||
strum_macros = "0.24.0"
|
||||
thiserror = "1.0.31"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
(program 11.22.33
|
||||
(lam x (lam x x))
|
||||
(lam x (lam x y))
|
||||
)
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue