Skip to content

Commit

Permalink
Merge pull request #49 from hiratara/support-anyhow
Browse files Browse the repository at this point in the history
Support anyhow crate
  • Loading branch information
ljedrz authored Aug 5, 2023
2 parents ebd9d68 + a58a546 commit 5791e67
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use self::Token::*;
pub use crate::term::Notation::*;
use crate::term::Term::*;
use crate::term::{abs, app, Notation, Term};
use std::error::Error;
use std::fmt;

/// An error returned by `parse()` when a parsing issue is encountered.
#[derive(Debug, PartialEq, Eq)]
Expand All @@ -19,6 +21,24 @@ pub enum ParseError {
EmptyExpression,
}

impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ParseError::InvalidCharacter((idx, char)) => {
write!(f, "lexical error; invalid character '{}' at {}", char, idx)
}
ParseError::InvalidExpression => write!(f, "syntax error; the expression is invalid"),
ParseError::EmptyExpression => write!(f, "syntax error; the expression is empty"),
}
}
}

impl Error for ParseError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}

#[derive(Debug, PartialEq, Eq)]
#[doc(hidden)]
pub enum Token {
Expand Down
17 changes: 17 additions & 0 deletions src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub use self::Term::*;
use self::TermError::*;
use std::borrow::Cow;
use std::char::from_u32;
use std::error::Error;
use std::fmt;

/// The character used to display lambda abstractions (a backslash).
Expand Down Expand Up @@ -61,6 +62,22 @@ pub enum TermError {
NotApp,
}

impl fmt::Display for TermError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TermError::NotVar => write!(f, "the term is not a variable",),
TermError::NotAbs => write!(f, "the term is not an abstraction"),
TermError::NotApp => write!(f, "the term is not an application"),
}
}
}

impl Error for TermError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}

impl Term {
/// Returns a variable's De Bruijn index, consuming it in the process.
///
Expand Down
17 changes: 17 additions & 0 deletions tests/parse_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extern crate lambda_calculus as lambda;

use lambda::{parser::parse, term::Notation::Classic};
use std::error::Error;

#[test]
fn parse_error_question_mark_operator() {
match using_question_mark_operator() {
Result::Ok(_) => panic!("Should not be Ok"),
Result::Err(e) => assert_eq!(e.to_string(), "syntax error; the expression is empty"),
}
}

fn using_question_mark_operator() -> Result<(), Box<dyn Error>> {
parse("λλλ", Classic)?;
Ok(())
}
17 changes: 17 additions & 0 deletions tests/term_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extern crate lambda_calculus as lambda;

use lambda::term::Term;
use std::error::Error;

#[test]
fn term_error_question_mark_operator() {
match using_question_mark_operator() {
Result::Ok(_) => panic!("Should not be Ok"),
Result::Err(e) => assert_eq!(e.to_string(), "the term is not an abstraction"),
}
}

fn using_question_mark_operator() -> Result<(), Box<dyn Error>> {
Term::Var(0).unabs()?;
Ok(())
}

0 comments on commit 5791e67

Please sign in to comment.