feat: better errors for debruijn converter

This commit is contained in:
rvcas
2022-06-04 12:16:56 -04:00
parent 2f51b23e7e
commit 377c5c206c
6 changed files with 66 additions and 39 deletions

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) {