From aac3549a72663c523a456b2f5d7c3b77f509cdd6 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Thu, 14 Jan 2021 11:42:55 +0000 Subject: Add labelled expressions. Restructure project (again). Convert `Cat` and `Alt` from binary to n+2-ary. --- src/chomp/error.rs | 402 ----------------------------------------------------- 1 file changed, 402 deletions(-) delete mode 100644 src/chomp/error.rs (limited to 'src/chomp/error.rs') diff --git a/src/chomp/error.rs b/src/chomp/error.rs deleted file mode 100644 index e7e4660..0000000 --- a/src/chomp/error.rs +++ /dev/null @@ -1,402 +0,0 @@ -use std::{ - error::Error, - fmt::{self, Display}, -}; - -use proc_macro2::Span; - -use super::{ - ast::{Alt, Call, Cat, Fix, Parameter, Variable}, - check::Spanning, - typed::Type, - visit::Visitable, -}; - -/// A type error when using a fix point variable. -#[derive(Debug, Eq, PartialEq)] -pub enum VariableError { - /// Usage of a free variable. - FreeVariable(Variable), - /// Usage of a guarded variable. - GuardedVariable(Variable), -} - -impl From for syn::Error { - fn from(other: VariableError) -> Self { - match other { - VariableError::FreeVariable(_) => todo!(), - VariableError::GuardedVariable(_) => todo!(), - } - } -} - -impl Display for VariableError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::FreeVariable(var) => { - let start = var.name().span().unwrap_or_else(Span::call_site).start(); - write!( - f, - "{}:{}: unbound variable '{}'", - start.line, - start.column, - var.name() - ) - } - Self::GuardedVariable(var) => { - let start = var.name().span().unwrap_or_else(Span::call_site).start(); - write!( - f, - "{}:{}: variable '{}' is guarded", - start.line, - start.column, - var.name() - ) - } - } - } -} - -impl Error for VariableError {} - -/// A type error when concatenating two terms. -#[derive(Debug, Eq, PartialEq)] -pub enum CatError { - /// The first term was unexpectedly nullable. - FirstNullable(Cat), - /// The flast set of the first term intersects the first set of the second. - FirstFlastOverlap(Cat), -} - -impl From for syn::Error { - fn from(other: CatError) -> Self { - match other { - CatError::FirstNullable(cat) => { - let mut err = Self::new( - cat.punct().map_or_else(Span::call_site, |p| p.span), - "first item in sequence cannot accept the empty string", - ); - err.combine(Self::new( - cat.first() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "this can accept empty string", - )); - err - } - CatError::FirstFlastOverlap(cat) => { - let mut err = Self::new( - cat.punct().map_or_else(Span::call_site, |p| p.span), - "cannot decide whether to repeat first or start accepting second", - ); - err.combine(Self::new( - cat.first() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "a repetition of this", - )); - err.combine(Self::new( - cat.second() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "collides with the start of this", - )); - err - } - } - } -} - -impl Display for CatError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::FirstNullable(cat) => { - let start = cat.punct().map_or_else(Span::call_site, |p| p.span).start(); - let fst_start = cat - .first() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - write!( - f, - "{}:{}: term `{}' ({}:{}) accepts the empty string", - start.line, - start.column, - cat.first(), - fst_start.line, - fst_start.column - ) - } - Self::FirstFlastOverlap(cat) => { - let start = cat.punct().map_or_else(Span::call_site, |p| p.span).start(); - let fst_start = cat - .first() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - let snd_start = cat - .second() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - write!( - f, - "{}:{}: cannot decide whether to repeat `{}' ({}:{}) or start accepting `{}' ({}:{}).", - start.line, - start.column, - cat.first(), - fst_start.line, - fst_start.column, - cat.second(), - snd_start.line, - snd_start.column - ) - } - } - } -} - -impl Error for CatError {} - -/// A type error when alternating two terms. -#[derive(Debug, Eq, PartialEq)] -pub enum AltError { - /// Both terms are nullable. - BothNullable(Alt), - /// The first sets of the two terms intersect. - FirstOverlap(Alt), -} - -impl From for syn::Error { - fn from(other: AltError) -> Self { - match other { - AltError::BothNullable(alt) => { - let mut err = Self::new( - alt.punct().map_or_else(Span::call_site, |p| p.span), - "both branches accept the empty string", - ); - err.combine(Self::new( - alt.left() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "left branch accepts the empty string", - )); - err.combine(Self::new( - alt.right() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "right branch accepts the empty string", - )); - err - } - AltError::FirstOverlap(alt) => { - let mut err = Self::new( - alt.punct().map_or_else(Span::call_site, |p| p.span), - "cannot decide whether to accept the left or right branch", - ); - err.combine(Self::new( - alt.left() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "left branch starts with a character", - )); - err.combine(Self::new( - alt.right() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site), - "right branch starts with the same character", - )); - err - } - } - } -} - -impl Display for AltError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::BothNullable(alt) => { - let start = alt.punct().map_or_else(Span::call_site, |p| p.span).start(); - let left_start = alt - .left() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - let right_start = alt - .right() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - write!( - f, - "{}:{}: both `{}' ({}:{}) and `{}' ({}:{}) accept the empty string.", - start.line, - start.column, - alt.left(), - left_start.line, - left_start.column, - alt.right(), - right_start.line, - right_start.column, - ) - } - Self::FirstOverlap(alt) => { - let start = alt.punct().map_or_else(Span::call_site, |p| p.span).start(); - let left_start = alt - .left() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - let right_start = alt - .right() - .visit(&mut Spanning) - .unwrap_or_else(Span::call_site) - .start(); - write!( - f, - "{}:{}: cannot decide whether to accept `{}' ({}:{}) or `{}' ({}:{}).", - start.line, - start.column, - alt.left(), - left_start.line, - left_start.column, - alt.right(), - right_start.line, - right_start.column, - ) - } - } - } -} - -impl Error for AltError {} - -#[derive(Debug, Eq, PartialEq)] -pub struct FixError(pub Fix, pub Type, pub Box); - -impl From for syn::Error { - fn from(e: FixError) -> Self { - let mut error = Self::from(*e.2); - error.combine(Self::new( - e.0.span().unwrap_or_else(Span::call_site), - format!("assuming `{}' has type {:?}.", e.0.arg(), e.1), - )); - error - } -} - -impl Display for FixError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.2.fmt(f)?; - let start = self.0.span().unwrap_or_else(Span::call_site).start(); - write!( - f, - "\n{}:{}: assuming `{}' has type {:?}.", - start.line, - start.column, - self.0.arg(), - self.1 - ) - } -} - -impl Error for FixError {} - -#[derive(Debug, Eq, PartialEq)] -pub enum TypeError { - Cat(CatError), - Alt(AltError), - Variable(VariableError), - Fix(FixError), -} - -impl From for TypeError { - fn from(other: CatError) -> Self { - Self::Cat(other) - } -} - -impl From for TypeError { - fn from(other: AltError) -> Self { - Self::Alt(other) - } -} - -impl From for TypeError { - fn from(other: VariableError) -> Self { - Self::Variable(other) - } -} - -impl From for syn::Error { - fn from(other: TypeError) -> Self { - match other { - TypeError::Cat(e) => e.into(), - TypeError::Alt(e) => e.into(), - TypeError::Variable(e) => e.into(), - TypeError::Fix(e) => e.into(), - } - } -} - -impl Display for TypeError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Cat(e) => e.fmt(f), - Self::Alt(e) => e.fmt(f), - Self::Variable(e) => e.fmt(f), - Self::Fix(e) => e.fmt(f), - } - } -} - -impl Error for TypeError {} - -#[derive(Debug, Eq, PartialEq)] -pub enum SubstituteError { - FreeParameter(Parameter), - WrongArgCount { call: Call, expected: usize }, -} - -impl From for syn::Error { - fn from(e: SubstituteError) -> Self { - match e { - SubstituteError::FreeParameter(param) => { - Self::new(param.name().span().unwrap_or_else(Span::call_site), format!("undeclared variable `{}'", param.name())) - } - SubstituteError::WrongArgCount { call, expected } => { - Self::new(call.span().unwrap_or_else(Span::call_site), format!("wrong number of arguments. Expected {}, got {}", expected, call.args().len())) - } - } - } -} - -impl Display for SubstituteError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::FreeParameter(param) => { - let start = param.name().span().unwrap_or_else(Span::call_site).start(); - write!( - f, - "{}:{}: undeclared variable `{}'", - start.line, - start.column, - param.name() - ) - } - SubstituteError::WrongArgCount { call, expected } => { - let start = call.span().unwrap_or_else(Span::call_site).start(); - write!( - f, - "{}:{}: wrong number of arguments. Expected {}, got {}", - start.line, - start.column, - expected, - call.args().len() - ) - } - } - } -} - -impl Error for SubstituteError {} -- cgit v1.2.3