summaryrefslogtreecommitdiff
path: root/src/chomp/error.rs
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-01-14 11:42:55 +0000
committerGreg Brown <gmb60@cam.ac.uk>2021-01-14 11:42:55 +0000
commitaac3549a72663c523a456b2f5d7c3b77f509cdd6 (patch)
tree562824f3cfa5feca791715c733f7749197bb7e7a /src/chomp/error.rs
parent0d01692c97ea8ca6fc4b229e5b9678cb252bceda (diff)
Add labelled expressions.
Restructure project (again). Convert `Cat` and `Alt` from binary to n+2-ary.
Diffstat (limited to 'src/chomp/error.rs')
-rw-r--r--src/chomp/error.rs402
1 files changed, 0 insertions, 402 deletions
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<VariableError> 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<CatError> 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<AltError> 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<TypeError>);
-
-impl From<FixError> 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<CatError> for TypeError {
- fn from(other: CatError) -> Self {
- Self::Cat(other)
- }
-}
-
-impl From<AltError> for TypeError {
- fn from(other: AltError) -> Self {
- Self::Alt(other)
- }
-}
-
-impl From<VariableError> for TypeError {
- fn from(other: VariableError) -> Self {
- Self::Variable(other)
- }
-}
-
-impl From<TypeError> 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<SubstituteError> 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 {}