diff options
| author | Tolmachev Igor <me@igorek.dev> | 2026-05-09 19:04:27 +0300 |
|---|---|---|
| committer | Tolmachev Igor <me@igorek.dev> | 2026-05-09 19:04:46 +0300 |
| commit | 6be28381d6081dfb3a1dc9d1ec15062b67ba1ef9 (patch) | |
| tree | 1bf89581879ce76f27d69881a6afa4e72e30bf61 | |
| parent | 6c5c627dd441b0e7ac52cfd05e1923584dd213ae (diff) | |
| download | crisp-6be28381d6081dfb3a1dc9d1ec15062b67ba1ef9.tar.gz crisp-6be28381d6081dfb3a1dc9d1ec15062b67ba1ef9.zip | |
Implement fmt::Display for Error
Replaces the todo!() stub. InvalidFloatLiteral and InvalidIntegerLiteral now also take the original
string.
| -rw-r--r-- | compiler/src/ast/error.rs | 33 | ||||
| -rw-r--r-- | compiler/src/ast/parser.rs | 16 | ||||
| -rw-r--r-- | compiler/src/ast/tests.rs | 8 |
3 files changed, 31 insertions, 26 deletions
diff --git a/compiler/src/ast/error.rs b/compiler/src/ast/error.rs index c3283f4..8117513 100644 --- a/compiler/src/ast/error.rs +++ b/compiler/src/ast/error.rs | |||
| @@ -7,8 +7,8 @@ use std::{ | |||
| 7 | #[derive(Clone, Debug, PartialEq, Eq)] | 7 | #[derive(Clone, Debug, PartialEq, Eq)] |
| 8 | pub enum Error { | 8 | pub enum Error { |
| 9 | // Number | 9 | // Number |
| 10 | InvalidFloatLiteral(ParseFloatError), | 10 | InvalidFloatLiteral(Rc<str>, ParseFloatError), |
| 11 | InvalidIntegerLiteral(ParseIntError), | 11 | InvalidIntegerLiteral(Rc<str>, ParseIntError), |
| 12 | 12 | ||
| 13 | // String | 13 | // String |
| 14 | UnclosedString(Rc<str>), | 14 | UnclosedString(Rc<str>), |
| @@ -23,21 +23,22 @@ pub enum Error { | |||
| 23 | RecursionLimit, | 23 | RecursionLimit, |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | impl From<ParseFloatError> for Error { | ||
| 27 | fn from(value: ParseFloatError) -> Self { | ||
| 28 | Self::InvalidFloatLiteral(value) | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | impl From<ParseIntError> for Error { | ||
| 33 | fn from(value: ParseIntError) -> Self { | ||
| 34 | Self::InvalidIntegerLiteral(value) | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | impl fmt::Display for Error { | 26 | impl fmt::Display for Error { |
| 39 | fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { | 27 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 40 | todo!() | 28 | match self { |
| 29 | Error::InvalidFloatLiteral(number, err) => { | ||
| 30 | write!(f, "invalid float literal {number}: {err}") | ||
| 31 | } | ||
| 32 | Error::InvalidIntegerLiteral(number, err) => { | ||
| 33 | write!(f, "invalid integer literal {number}: {err}") | ||
| 34 | } | ||
| 35 | Error::UnclosedString(string) => write!(f, "unclosed string {string:?}"), | ||
| 36 | Error::UnexpectedEscapeChar(ch) => write!(f, "unexpected escape char {ch:?}"), | ||
| 37 | Error::UnexpectedRightPar => write!(f, "unexpected right par"), | ||
| 38 | Error::UnclosedLeftPar => write!(f, "unclosed left par"), | ||
| 39 | Error::UnexpectedEof => write!(f, "unexpected eof"), | ||
| 40 | Error::RecursionLimit => write!(f, "recursion limit"), | ||
| 41 | } | ||
| 41 | } | 42 | } |
| 42 | } | 43 | } |
| 43 | 44 | ||
diff --git a/compiler/src/ast/parser.rs b/compiler/src/ast/parser.rs index 83e48b8..263e5b7 100644 --- a/compiler/src/ast/parser.rs +++ b/compiler/src/ast/parser.rs | |||
| @@ -12,13 +12,17 @@ fn parse_number(number: &str) -> Result<Atom, Error> { | |||
| 12 | let is_float = number.bytes().any(|b| matches!(b, b'.' | b'e' | b'E')) | 12 | let is_float = number.bytes().any(|b| matches!(b, b'.' | b'e' | b'E')) |
| 13 | || matches!(number, "inf" | "+inf" | "-inf" | "nan"); | 13 | || matches!(number, "inf" | "+inf" | "-inf" | "nan"); |
| 14 | 14 | ||
| 15 | let atom = if is_float { | 15 | if is_float { |
| 16 | Atom::Float(number.parse()?) | 16 | match number.parse() { |
| 17 | Ok(ok) => Ok(Atom::Float(ok)), | ||
| 18 | Err(err) => Err(Error::InvalidFloatLiteral(number.into(), err)), | ||
| 19 | } | ||
| 17 | } else { | 20 | } else { |
| 18 | Atom::Integer(number.parse()?) | 21 | match number.parse() { |
| 19 | }; | 22 | Ok(ok) => Ok(Atom::Integer(ok)), |
| 20 | 23 | Err(err) => Err(Error::InvalidIntegerLiteral(number.into(), err)), | |
| 21 | Ok(atom) | 24 | } |
| 25 | } | ||
| 22 | } | 26 | } |
| 23 | 27 | ||
| 24 | fn parse_string(string: &str) -> Result<Atom, Error> { | 28 | fn parse_string(string: &str) -> Result<Atom, Error> { |
diff --git a/compiler/src/ast/tests.rs b/compiler/src/ast/tests.rs index 708e788..c6d8c38 100644 --- a/compiler/src/ast/tests.rs +++ b/compiler/src/ast/tests.rs | |||
| @@ -415,7 +415,7 @@ fn test_invalid_integer() { | |||
| 415 | let error = number.parse::<i64>().unwrap_err(); | 415 | let error = number.parse::<i64>().unwrap_err(); |
| 416 | assert_eq!( | 416 | assert_eq!( |
| 417 | parse_err(tokens.clone()), | 417 | parse_err(tokens.clone()), |
| 418 | Error::InvalidIntegerLiteral(error), | 418 | Error::InvalidIntegerLiteral(number.into(), error), |
| 419 | "input: {tokens:?}", | 419 | "input: {tokens:?}", |
| 420 | ); | 420 | ); |
| 421 | } | 421 | } |
| @@ -445,7 +445,7 @@ fn test_invalid_float() { | |||
| 445 | let error = number.parse::<f64>().unwrap_err(); | 445 | let error = number.parse::<f64>().unwrap_err(); |
| 446 | assert_eq!( | 446 | assert_eq!( |
| 447 | parse_err(tokens.clone()), | 447 | parse_err(tokens.clone()), |
| 448 | Error::InvalidFloatLiteral(error), | 448 | Error::InvalidFloatLiteral(number.into(), error), |
| 449 | "input: {tokens:?}", | 449 | "input: {tokens:?}", |
| 450 | ); | 450 | ); |
| 451 | } | 451 | } |
| @@ -639,7 +639,7 @@ fn test_error_span_invalid_float() { | |||
| 639 | let err = parse_sp_err(tokens.clone()); | 639 | let err = parse_sp_err(tokens.clone()); |
| 640 | 640 | ||
| 641 | assert!( | 641 | assert!( |
| 642 | matches!(err.inner, Error::InvalidFloatLiteral(_)), | 642 | matches!(err.inner, Error::InvalidFloatLiteral(..)), |
| 643 | "input: {tokens:?}, got: {:?}", | 643 | "input: {tokens:?}, got: {:?}", |
| 644 | err.inner, | 644 | err.inner, |
| 645 | ); | 645 | ); |
| @@ -725,7 +725,7 @@ fn test_error_span_deep_nested() { | |||
| 725 | let err = parse_sp_err(tokens.clone()); | 725 | let err = parse_sp_err(tokens.clone()); |
| 726 | 726 | ||
| 727 | assert!( | 727 | assert!( |
| 728 | matches!(err.inner, Error::InvalidIntegerLiteral(_)), | 728 | matches!(err.inner, Error::InvalidIntegerLiteral(..)), |
| 729 | "input: {tokens:?}, got: {:?}", | 729 | "input: {tokens:?}, got: {:?}", |
| 730 | err.inner, | 730 | err.inner, |
| 731 | ); | 731 | ); |
