1use crate::common::*;
2
3#[derive(Default, Diagnostic, Clone, Debug, thiserror::Error)]
4pub enum ExprError {
5 #[error("invalid token")]
6 #[diagnostic()]
7 InvalidToken {
8 #[label("occurs here")]
9 span: SourceSpan,
10 },
11 #[error("unrecognized token")]
12 #[diagnostic(help("expected one of: {}", expected.as_slice().join(", ")))]
13 UnrecognizedToken {
14 #[label("lexed a {token} here")]
15 span: SourceSpan,
16 token: String,
17 expected: Vec<String>,
18 },
19 #[error("unexpected trailing tokens")]
20 #[diagnostic()]
21 ExtraToken {
22 #[label("{token} was found here, but was not expected")]
23 span: SourceSpan,
24 token: String,
25 },
26 #[error("unexpected end of file")]
27 #[diagnostic(help("expected one of: {}", expected.as_slice().join(", ")))]
28 UnrecognizedEof {
29 #[label("reached end of file here")]
30 span: SourceSpan,
31 expected: Vec<String>,
32 },
33 #[error(transparent)]
34 #[diagnostic(transparent)]
35 InvalidCall(#[from] InvalidCallExprError),
36 #[error("invalid numeric expression")]
37 #[diagnostic(help("make sure the value is parseable as a 64-bit signed integer"))]
38 Number {
39 #[label("{error}")]
40 span: SourceSpan,
41 #[source]
42 error: core::num::ParseIntError,
43 },
44 #[error("invalid format specifier")]
45 #[diagnostic()]
46 InvalidFormatSpecifier {
47 #[label("this numeric format specifier is not recognized")]
48 span: SourceSpan,
49 },
50 #[error("invalid numeric precision")]
51 #[diagnostic()]
52 InvalidNumericPrecision {
53 #[label("the precision value here is too large")]
54 span: SourceSpan,
55 },
56 #[default]
58 #[error("an unknown error occurred")]
59 #[diagnostic()]
60 Unknown,
61}
62impl PartialEq for ExprError {
63 fn eq(&self, other: &Self) -> bool {
64 match (self, other) {
65 (Self::InvalidToken { .. }, Self::InvalidToken { .. }) => true,
66 (
67 Self::UnrecognizedToken {
68 token: at,
69 expected: a,
70 ..
71 },
72 Self::UnrecognizedToken {
73 token: bt,
74 expected: b,
75 ..
76 },
77 ) => at == bt && a == b,
78 (Self::ExtraToken { token: a, .. }, Self::ExtraToken { token: b, .. }) => a == b,
79 (
80 Self::UnrecognizedEof { expected: a, .. },
81 Self::UnrecognizedEof { expected: b, .. },
82 ) => a == b,
83 (Self::InvalidCall(a), Self::InvalidCall(b)) => a == b,
84 (Self::Number { .. }, Self::Number { .. }) => true,
85 (Self::InvalidFormatSpecifier { .. }, Self::InvalidFormatSpecifier { .. }) => true,
86 (Self::InvalidNumericPrecision { .. }, Self::InvalidNumericPrecision { .. }) => true,
87 (Self::Unknown, Self::Unknown) => true,
88 _ => false,
89 }
90 }
91}
92impl Spanned for ExprError {
93 fn span(&self) -> SourceSpan {
94 match self {
95 Self::InvalidCall(err) => err.span(),
96 Self::InvalidToken { span, .. }
97 | Self::UnrecognizedToken { span, .. }
98 | Self::ExtraToken { span, .. }
99 | Self::UnrecognizedEof { span, .. }
100 | Self::Number { span, .. }
101 | Self::InvalidFormatSpecifier { span, .. }
102 | Self::InvalidNumericPrecision { span, .. } => *span,
103 Self::Unknown => SourceSpan::from(0..0),
104 }
105 }
106}
107
108#[derive(Debug, Clone, Diagnostic, thiserror::Error)]
109pub enum InvalidCallExprError {
110 #[error("undefined function")]
111 #[diagnostic()]
112 Undefined {
113 #[label("no such function defined in this context")]
114 span: SourceSpan,
115 callee: String,
116 },
117 #[error("function '{callee}' expects {expected} arguments, but was given {given}")]
118 #[diagnostic()]
119 InvalidArity {
120 #[label("this function only takes {expected} arguments")]
121 span: SourceSpan,
122 callee: String,
123 expected: u8,
124 given: u8,
125 },
126}
127impl Spanned for InvalidCallExprError {
128 fn span(&self) -> SourceSpan {
129 match self {
130 Self::Undefined { span, .. } | Self::InvalidArity { span, .. } => *span,
131 }
132 }
133}
134impl PartialEq for InvalidCallExprError {
135 fn eq(&self, other: &Self) -> bool {
136 match (self, other) {
137 (Self::Undefined { callee: a, .. }, Self::Undefined { callee: b, .. }) => a == b,
138 (
139 Self::InvalidArity {
140 callee: a,
141 expected: ae,
142 given: ag,
143 ..
144 },
145 Self::InvalidArity {
146 callee: b,
147 expected: be,
148 given: bg,
149 ..
150 },
151 ) => a == b && ae == be && ag == bg,
152 _ => false,
153 }
154 }
155}