Actually just three programming languages in a trenchcoat
at string-repr-callable 88 lines 2.5 kB view raw
1use crate::Spanned; 2use source_span::Span; 3use std::fmt::{self, Display}; 4 5#[derive(Clone, Debug)] 6pub enum ErrorKind { 7 Unknown(String), 8 KwNotInExpression, 9 RuleRightArrow, 10 MatchStatementExpressionCase, 11 TripleDot { dot: Span }, 12 IfStatementRestriction, 13 IfExpressionRestriction, 14 MatchExpressionRestriction, 15} 16 17impl ErrorKind { 18 pub(crate) fn at(self, span: Span) -> SyntaxError { 19 SyntaxError { span, kind: self } 20 } 21} 22 23#[derive(Clone, Debug)] 24pub struct SyntaxError { 25 span: Span, 26 kind: ErrorKind, 27} 28 29impl Spanned for SyntaxError { 30 fn span(&self) -> Span { 31 self.span 32 } 33} 34 35impl SyntaxError { 36 pub(crate) fn new(span: Span, message: impl std::fmt::Display) -> Self { 37 Self { 38 span, 39 kind: ErrorKind::Unknown(message.to_string()), 40 } 41 } 42 43 pub(crate) fn new_spanless(message: impl std::fmt::Display) -> Self { 44 Self { 45 span: Span::default(), 46 kind: ErrorKind::Unknown(message.to_string()), 47 } 48 } 49 50 pub fn kind(&self) -> &ErrorKind { 51 &self.kind 52 } 53} 54 55impl std::error::Error for SyntaxError {} 56 57impl Display for SyntaxError { 58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 59 write!(f, "syntax error ({}): ", self.span)?; 60 match &self.kind { 61 ErrorKind::Unknown(message) => write!(f, "{message}")?, 62 ErrorKind::KwNotInExpression => { 63 write!(f, "keyword `not` cannot be used in an expression")? 64 } 65 ErrorKind::RuleRightArrow => { 66 write!(f, "right arrow following rule should be a left arrow")? 67 } 68 ErrorKind::MatchStatementExpressionCase => { 69 write!(f, "case in match statement should be a block")? 70 } 71 ErrorKind::TripleDot { .. } => write!(f, "triple `...` should be `..`")?, 72 ErrorKind::IfStatementRestriction => write!( 73 f, 74 "an `if` statement must be in strict statement form, or be a valid `if` expression" 75 )?, 76 ErrorKind::IfExpressionRestriction => { 77 write!(f, "an `if` expression must have an `else` clause")? 78 } 79 ErrorKind::MatchExpressionRestriction => { 80 write!(f, "a `match` expression must have an `else` case")? 81 } 82 } 83 84 Ok(()) 85 } 86} 87 88pub type SyntaxResult<T> = Result<T, SyntaxError>;