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