Skip to main content

nash_parse/
error.rs

1//! Syntax error types for the Nash parser.
2//!
3//! Ported from Elm's `Reporting/Error/Syntax.hs`.
4//! These types form a nested hierarchy that enables high-quality error messages.
5//!
6//! Note: `Type`, `Expr`, `Pattern` here are ERROR types describing parse failures,
7//! not AST types. They are allocated in the arena like everything else.
8
9use crate::{Col, Row};
10
11// =============================================================================
12// Top-level Error
13// =============================================================================
14
15#[derive(Debug)]
16pub enum Error<'a> {
17    ModuleNameUnspecified(&'a str),
18    ModuleNameMismatch {
19        expected: &'a str,
20        actual: &'a str,
21        row: Row,
22        col: Col,
23    },
24    UnexpectedPort {
25        row: Row,
26        col: Col,
27    },
28    NoPorts {
29        row: Row,
30        col: Col,
31    },
32    NoPortsInPackage {
33        name: &'a str,
34        row: Row,
35        col: Col,
36    },
37    NoPortModulesInPackage {
38        row: Row,
39        col: Col,
40    },
41    NoEffectsOutsideKernel {
42        row: Row,
43        col: Col,
44    },
45    ParseError(&'a Module<'a>),
46}
47
48// =============================================================================
49// Module Errors
50// =============================================================================
51
52#[derive(Debug)]
53pub enum Module<'a> {
54    Space(Space, Row, Col),
55    BadEnd(Row, Col),
56    Problem(Row, Col),
57    Name(Row, Col),
58    Exposing(&'a Exposing, Row, Col),
59    PortProblem(Row, Col),
60    PortName(Row, Col),
61    PortExposing(&'a Exposing, Row, Col),
62    Effect(Row, Col),
63    FreshLine(Row, Col),
64    ImportStart(Row, Col),
65    ImportName(Row, Col),
66    ImportAs(Row, Col),
67    ImportAlias(Row, Col),
68    ImportExposing(Row, Col),
69    ImportExposingList(&'a Exposing, Row, Col),
70    ImportEnd(Row, Col),
71    ImportIndentName(Row, Col),
72    ImportIndentAlias(Row, Col),
73    ImportIndentExposingList(Row, Col),
74    Infix(Row, Col),
75    Declarations(&'a Decl<'a>, Row, Col),
76}
77
78#[derive(Debug)]
79pub enum Exposing {
80    Space(Space, Row, Col),
81    Start(Row, Col),
82    Value(Row, Col),
83    Operator(Row, Col),
84    OperatorReserved(BadOperator, Row, Col),
85    OperatorRightParen(Row, Col),
86    TypePrivacy(Row, Col),
87    End(Row, Col),
88    IndentEnd(Row, Col),
89    IndentValue(Row, Col),
90}
91
92// =============================================================================
93// Declaration Errors
94// =============================================================================
95
96#[derive(Debug)]
97pub enum Decl<'a> {
98    Start(Row, Col),
99    Space(Space, Row, Col),
100    Port(&'a Port<'a>, Row, Col),
101    Type(&'a DeclType<'a>, Row, Col),
102    Def(&'a str, &'a DeclDef<'a>, Row, Col),
103    FreshLineAfterDocComment(Row, Col),
104}
105
106#[derive(Debug)]
107pub enum DeclDef<'a> {
108    Space(Space, Row, Col),
109    Equals(Row, Col),
110    Type(&'a Type<'a>, Row, Col),
111    Arg(&'a Pattern<'a>, Row, Col),
112    Body(&'a Expr<'a>, Row, Col),
113    NameRepeat(Row, Col),
114    NameMatch(&'a str, Row, Col),
115    IndentType(Row, Col),
116    IndentEquals(Row, Col),
117    IndentBody(Row, Col),
118}
119
120#[derive(Debug)]
121pub enum Port<'a> {
122    Space(Space, Row, Col),
123    Name(Row, Col),
124    Colon(Row, Col),
125    Type(&'a Type<'a>, Row, Col),
126    IndentName(Row, Col),
127    IndentColon(Row, Col),
128    IndentType(Row, Col),
129}
130
131#[derive(Debug)]
132pub enum DeclType<'a> {
133    Space(Space, Row, Col),
134    Name(Row, Col),
135    Alias(&'a TypeAlias<'a>, Row, Col),
136    Union(&'a CustomType<'a>, Row, Col),
137    IndentName(Row, Col),
138}
139
140#[derive(Debug)]
141pub enum TypeAlias<'a> {
142    Space(Space, Row, Col),
143    Name(Row, Col),
144    Equals(Row, Col),
145    Body(&'a Type<'a>, Row, Col),
146    IndentEquals(Row, Col),
147    IndentBody(Row, Col),
148}
149
150#[derive(Debug)]
151pub enum CustomType<'a> {
152    Space(Space, Row, Col),
153    Name(Row, Col),
154    Equals(Row, Col),
155    Bar(Row, Col),
156    Variant(Row, Col),
157    VariantArg(&'a Type<'a>, Row, Col),
158    IndentEquals(Row, Col),
159    IndentBar(Row, Col),
160    IndentAfterBar(Row, Col),
161    IndentAfterEquals(Row, Col),
162}
163
164// =============================================================================
165// Expression Errors
166// =============================================================================
167
168#[derive(Debug)]
169pub enum Expr<'a> {
170    Let(&'a Let<'a>, Row, Col),
171    Case(&'a Case<'a>, Row, Col),
172    If(&'a If<'a>, Row, Col),
173    List(&'a List<'a>, Row, Col),
174    Record(&'a Record<'a>, Row, Col),
175    Tuple(&'a Tuple<'a>, Row, Col),
176    Func(&'a Func<'a>, Row, Col),
177    Dot(Row, Col),
178    Access(Row, Col),
179    OperatorRight(&'a str, Row, Col),
180    OperatorReserved(BadOperator, Row, Col),
181    Start(Row, Col),
182    Char(Char, Row, Col),
183    String(StringError, Row, Col),
184    Number(Number, Row, Col),
185    Space(Space, Row, Col),
186    EndlessShader(Row, Col),
187    ShaderProblem(Row, Col),
188    IndentOperatorRight(&'a str, Row, Col),
189}
190
191#[derive(Debug)]
192pub enum Record<'a> {
193    Open(Row, Col),
194    End(Row, Col),
195    Field(Row, Col),
196    Equals(Row, Col),
197    Expr(&'a Expr<'a>, Row, Col),
198    Space(Space, Row, Col),
199    IndentOpen(Row, Col),
200    IndentEnd(Row, Col),
201    IndentField(Row, Col),
202    IndentEquals(Row, Col),
203    IndentExpr(Row, Col),
204}
205
206#[derive(Debug)]
207pub enum Tuple<'a> {
208    Expr(&'a Expr<'a>, Row, Col),
209    Space(Space, Row, Col),
210    End(Row, Col),
211    OperatorClose(Row, Col),
212    OperatorReserved(BadOperator, Row, Col),
213    IndentExpr1(Row, Col),
214    IndentExprN(Row, Col),
215    IndentEnd(Row, Col),
216}
217
218#[derive(Debug)]
219pub enum List<'a> {
220    Space(Space, Row, Col),
221    Open(Row, Col),
222    Expr(&'a Expr<'a>, Row, Col),
223    End(Row, Col),
224    IndentOpen(Row, Col),
225    IndentEnd(Row, Col),
226    IndentExpr(Row, Col),
227}
228
229#[derive(Debug)]
230pub enum Func<'a> {
231    Space(Space, Row, Col),
232    Arg(&'a Pattern<'a>, Row, Col),
233    Body(&'a Expr<'a>, Row, Col),
234    Arrow(Row, Col),
235    IndentArg(Row, Col),
236    IndentArrow(Row, Col),
237    IndentBody(Row, Col),
238}
239
240#[derive(Debug)]
241pub enum Case<'a> {
242    Space(Space, Row, Col),
243    Of(Row, Col),
244    Pattern(&'a Pattern<'a>, Row, Col),
245    Arrow(Row, Col),
246    Expr(&'a Expr<'a>, Row, Col),
247    Branch(&'a Expr<'a>, Row, Col),
248    IndentOf(Row, Col),
249    IndentExpr(Row, Col),
250    IndentPattern(Row, Col),
251    IndentArrow(Row, Col),
252    IndentBranch(Row, Col),
253    PatternAlignment(u16, Row, Col),
254}
255
256#[derive(Debug)]
257pub enum If<'a> {
258    Space(Space, Row, Col),
259    Then(Row, Col),
260    Else(Row, Col),
261    ElseBranchStart(Row, Col),
262    Condition(&'a Expr<'a>, Row, Col),
263    ThenBranch(&'a Expr<'a>, Row, Col),
264    ElseBranch(&'a Expr<'a>, Row, Col),
265    IndentCondition(Row, Col),
266    IndentThen(Row, Col),
267    IndentThenBranch(Row, Col),
268    IndentElseBranch(Row, Col),
269    IndentElse(Row, Col),
270}
271
272#[derive(Debug)]
273pub enum Let<'a> {
274    Space(Space, Row, Col),
275    In(Row, Col),
276    DefAlignment(u16, Row, Col),
277    DefName(Row, Col),
278    Def(&'a str, &'a Def<'a>, Row, Col),
279    Destruct(&'a Destruct<'a>, Row, Col),
280    Body(&'a Expr<'a>, Row, Col),
281    IndentDef(Row, Col),
282    IndentIn(Row, Col),
283    IndentBody(Row, Col),
284}
285
286#[derive(Debug)]
287pub enum Def<'a> {
288    Space(Space, Row, Col),
289    Type(&'a Type<'a>, Row, Col),
290    NameRepeat(Row, Col),
291    NameMatch(&'a str, Row, Col),
292    Arg(&'a Pattern<'a>, Row, Col),
293    Equals(Row, Col),
294    Body(&'a Expr<'a>, Row, Col),
295    IndentEquals(Row, Col),
296    IndentType(Row, Col),
297    IndentBody(Row, Col),
298    Alignment(u16, Row, Col),
299}
300
301#[derive(Debug)]
302pub enum Destruct<'a> {
303    Space(Space, Row, Col),
304    Pattern(&'a Pattern<'a>, Row, Col),
305    Equals(Row, Col),
306    Body(&'a Expr<'a>, Row, Col),
307    IndentEquals(Row, Col),
308    IndentBody(Row, Col),
309}
310
311// =============================================================================
312// Pattern Errors
313// =============================================================================
314
315#[derive(Debug)]
316pub enum Pattern<'a> {
317    Record(&'a PRecord, Row, Col),
318    Tuple(&'a PTuple<'a>, Row, Col),
319    List(&'a PList<'a>, Row, Col),
320    Start(Row, Col),
321    Char(Char, Row, Col),
322    String(StringError, Row, Col),
323    Number(Number, Row, Col),
324    Float(u16, Row, Col),
325    Alias(Row, Col),
326    WildcardNotVar(&'a str, i32, Row, Col),
327    Space(Space, Row, Col),
328    IndentStart(Row, Col),
329    IndentAlias(Row, Col),
330}
331
332#[derive(Debug)]
333pub enum PRecord {
334    Open(Row, Col),
335    End(Row, Col),
336    Field(Row, Col),
337    Space(Space, Row, Col),
338    IndentOpen(Row, Col),
339    IndentEnd(Row, Col),
340    IndentField(Row, Col),
341}
342
343#[derive(Debug)]
344pub enum PTuple<'a> {
345    Open(Row, Col),
346    End(Row, Col),
347    Expr(&'a Pattern<'a>, Row, Col),
348    Space(Space, Row, Col),
349    IndentEnd(Row, Col),
350    IndentExpr1(Row, Col),
351    IndentExprN(Row, Col),
352}
353
354#[derive(Debug)]
355pub enum PList<'a> {
356    Open(Row, Col),
357    End(Row, Col),
358    Expr(&'a Pattern<'a>, Row, Col),
359    Space(Space, Row, Col),
360    IndentOpen(Row, Col),
361    IndentEnd(Row, Col),
362    IndentExpr(Row, Col),
363}
364
365// =============================================================================
366// Type Errors
367// =============================================================================
368
369#[derive(Debug)]
370pub enum Type<'a> {
371    Record(&'a TRecord<'a>, Row, Col),
372    Tuple(&'a TTuple<'a>, Row, Col),
373    Start(Row, Col),
374    Space(Space, Row, Col),
375    IndentStart(Row, Col),
376}
377
378#[derive(Debug)]
379pub enum TRecord<'a> {
380    Open(Row, Col),
381    End(Row, Col),
382    Field(Row, Col),
383    Colon(Row, Col),
384    Type(&'a Type<'a>, Row, Col),
385    Space(Space, Row, Col),
386    IndentOpen(Row, Col),
387    IndentField(Row, Col),
388    IndentColon(Row, Col),
389    IndentType(Row, Col),
390    IndentEnd(Row, Col),
391}
392
393#[derive(Debug)]
394pub enum TTuple<'a> {
395    Open(Row, Col),
396    End(Row, Col),
397    Type(&'a Type<'a>, Row, Col),
398    Space(Space, Row, Col),
399    IndentType1(Row, Col),
400    IndentTypeN(Row, Col),
401    IndentEnd(Row, Col),
402}
403
404// =============================================================================
405// Literal Errors (no lifetimes - leaf types)
406// =============================================================================
407
408#[derive(Debug)]
409pub enum Char {
410    Endless,
411    Escape(Escape),
412    NotString(u16),
413}
414
415#[derive(Debug)]
416pub enum StringError {
417    EndlessSingle,
418    EndlessMulti,
419    Escape(Escape),
420}
421
422#[derive(Debug)]
423pub enum Escape {
424    Unknown,
425    BadUnicodeFormat(u16),
426    BadUnicodeCode(u16),
427    BadUnicodeLength {
428        code: u16,
429        expected: i32,
430        actual: i32,
431    },
432}
433
434#[derive(Debug)]
435pub enum Number {
436    End,
437    Dot(i32),
438    HexDigit,
439    NoLeadingZero,
440}
441
442// =============================================================================
443// Misc (no lifetimes - leaf types)
444// =============================================================================
445
446#[derive(Debug)]
447pub enum Space {
448    HasTab,
449    EndlessMultiComment,
450}
451
452#[derive(Debug)]
453pub enum BadOperator {
454    Dot,
455    Pipe,
456    Arrow,
457    Equals,
458    HasType,
459}