1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::loc::Loc;
use crate::token::TokenType;
use core::fmt;
use core::fmt::Debug;
use core::fmt::Formatter;
use std::error::Error;
use std::fmt::Display;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum SyntaxErrorType {
  ExpectedNotFound,
  ExpectedSyntax(&'static str),
  ForLoopHeaderHasInvalidLhs,
  ForLoopHeaderHasMultipleDeclarators,
  ForLoopHeaderHasNoLhs,
  InvalidAssigmentTarget,
  InvalidCharacterEscape,
  JsxClosingTagMismatch,
  LineTerminatorAfterArrowFunctionParameters,
  LineTerminatorAfterThrow,
  LineTerminatorAfterYield,
  LineTerminatorInRegex,
  LineTerminatorInString,
  MalformedLiteralBigInt,
  MalformedLiteralNumber,
  RequiredTokenNotFound(TokenType),
  TryStatementHasNoCatchOrFinally,
  UnexpectedEnd,
}

#[derive(Clone)]
pub struct SyntaxError {
  pub typ: SyntaxErrorType,
  pub loc: Loc,
  pub actual_token: Option<TokenType>,
}

impl SyntaxError {
  pub fn new(typ: SyntaxErrorType, loc: Loc, actual_token: Option<TokenType>) -> SyntaxError {
    SyntaxError {
      typ,
      loc,
      actual_token,
    }
  }
}

impl Debug for SyntaxError {
  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    write!(f, "{} around loc [{}:{}]", self, self.loc.0, self.loc.1)
  }
}

impl Display for SyntaxError {
  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    write!(f, "{:?} [token={:?}]", self.typ, self.actual_token)
  }
}

impl Error for SyntaxError {}

impl PartialEq for SyntaxError {
  fn eq(&self, other: &Self) -> bool {
    self.typ == other.typ
  }
}

impl Eq for SyntaxError {}

pub type SyntaxResult<T> = Result<T, SyntaxError>;