Skip to main content

m2_syn/schema/
nodes.rs

1crate::syntax! {
2// P = precedence, B = binary binding strength, U = unary binding strength.
3// `L` and `R` derive B from P. Columns absent for a role are omitted, and
4// spellings with identical metadata share one row.
5tokens {
6    // Operators                          roles                 (P, B, U)
7    [->] [<-] [=] [=>]                   { infix }              (14, R)
8    [>>]                                 { bin, aug }           (14, R)
9    [<<]                                 { bin, pref, aug }     (18, L)
10    [|-]                                 { bin, pref, aug }     (20, L)
11    [===>]                               { bin, aug }           (22, R)
12    [<===]                               { bin, pref }          (22, R)
13    [<==>]                               { bin, aug }           (24, R)
14    [==>]                                { bin, aug }           (26, R)
15    [<==]                                { bin, pref }          (26, R)
16    [or]                                 { bin }                (28, R)
17    [??]                                 { bin, pref, aug }     (28, R)
18    [xor]                                { bin }                (30, R)
19    [and]                                { bin }                (32, R)
20    [not]                                { pref }               (34)
21    [!=] [=!=] [==] [===]                { bin }                (36, R)
22    [<] [<=] [>] [>=] [?]                { bin, pref }          (36, R)
23    [~]                                  { bin, pref, aug }     (36, R)
24    [||]                                 { bin, aug }           (38, L)
25    [:]                                  { bin, aug }           (40, R)
26    [|]                                  { bin, aug }           (42, L)
27    [^^]                                 { bin, aug }           (44, L)
28    [&]                                  { bin, aug }           (46, L)
29    [..] [..<]                           { bin, aug }           (48, L)
30    [++]                                 { bin, aug }           (50, L)
31    [+] [-]                              { bin, pref, aug }     (50, L)
32    ["·"]                                { bin, aug }           (52, L)
33    [**] ["⊠"] ["⧢"]                     { bin, aug }           (54, L)
34    [%] [/] [/ /]                        { bin, aug }           (58, L)
35    [*]                                  { bin, pref, aug }     (58, L)
36    ["\\"] ["\\\\"]                      { bin, aug }           (58, R)
37    [@]                                  { bin, aug }           (60, R)
38    [(*)]                                { post }               (64)
39    [@@] [@@?]                           { bin, aug }           (66, L)
40    [^*] [^~] [_*] [_~]                  { post }               (68)
41    [#?] [.] [.?]                        { bin }                (70, L)
42    [^<] [^<=] [^>] [^>=]                { bin }                (70, L)
43    [_<] [_<=] [_>] [_>=]                { bin }                (70, L)
44    [^] [^**] [_] [|_]                   { bin, aug }           (70, L)
45    [#]                                  { bin, pref }          (70, L, 61)
46    [!] [^!] [_!]                        { post }               (72)
47
48    // Keywords
49    [else] [then] [do] [list] [except]                          (12)
50    [when] [of] [in] [from] [to]                                (16)
51    [break] [continue] [return]
52    [catch] [throw] [trap]
53    [if] [while] [try]
54    [TEST] [time] [timing]
55    [elapsedTime] [elapsedTiming]
56    [breakpoint] [profile] [shield]
57    [step] [finish]                                             (62, 12)
58    [for] [new]                                                 (62, 16)
59    [symbol] [global] [local] [threadLocal] [threadVariable]    (62, 74)
60
61    // Separators
62    [;]                                                         (8)
63    [,]                                                         (10)
64}
65
66// Leaves retain their source text. Canonical names select the specialized
67// storage and parsing behavior supplied by the schema macro.
68strutuct! { Symbol }
69strutuct! { Empty }
70strutuct! { Adj }
71strutuct! { EOC }
72strutuct! { EOF }
73strutuct! { EscapeSequence }
74strutuct! { FloatLiteral }
75strutuct! { IntegerLiteral }
76strutuct! { RawStringContent }
77strutuct! { StringContent }
78
79// `Lines<T>` is stored as `Vec<T>` and printed one element per line.
80#[comments]
81#[cell_stream]
82strutuct!{ SourceFile
83    cells: Lines<Cell>,
84    eof: EOF,
85}
86
87#[comments]
88strutuct!{ Cell
89    content: PackedContent,
90    semicolon: Token![;]?,
91    eoc: EOC,
92}
93
94strutuct!{ Component
95    Expr(Expr*)
96    Empty(Empty)
97}
98
99strutuct!{ ExprPack
100    pack: Punctuated<Component>,
101}
102
103strutuct!{ PackedContent
104    Expr(Expr*)
105    Pack(ExprPack)
106}
107
108strutuct!{ Statement
109    content: PackedContent,
110    semicolon: Token![;],
111}
112
113#[delimiter(bracket)]
114strutuct!{ Array
115    statements: Vec<Statement>,
116    elements: PackedContent?,
117}
118
119#[delimiter(brace)]
120strutuct!{ List
121    statements: Vec<Statement>,
122    elements: PackedContent?,
123}
124
125#[delimiter(angle_bar)]
126strutuct!{ AngleBarList
127    statements: Vec<Statement>,
128    elements: PackedContent?,
129}
130
131#[delimiter(parenthesis)]
132strutuct!{ Sequence
133    statements: Vec<Statement>,
134    elements: PackedContent?,
135}
136
137#[delimiter(parenthesis)]
138strutuct!{ Holder
139    muted: Vec<Statement>,
140    value: Expr*?,
141}
142
143strutuct!{ StringElement
144    Escape(EscapeSequence)
145    Content(StringContent)
146}
147
148#[literal(string)]
149strutuct!{ StringLiteral
150    elements: Vec<StringElement>,
151}
152
153strutuct!{ RawStringElement
154    Escape(EscapeSequence)
155    Content(RawStringContent)
156}
157
158#[literal(raw_string)]
159strutuct!{ RawStringLiteral
160    elements: Vec<RawStringElement>,
161}
162
163strutuct!{ AssignmentArgument
164    List(AssignmentList*)
165    Empty(Empty)
166    Symbol(Symbol)
167    Op(ExprOp)
168}
169
170strutuct!{ AssignmentListContent
171    Argument(AssignmentArgument)
172    Pack {
173        arguments: Punctuated<AssignmentArgument>,
174    }
175}
176
177strutuct!{ AssignmentList
178    contents: Delimited<Option<AssignmentListContent>>,
179}
180
181strutuct!{ ArgumentListContent
182    Symbol(Symbol)
183    Pack {
184        arguments: Punctuated<Symbol>,
185    }
186}
187
188// These products are shared by otherwise independent expression families.
189strutuct!{ TypeAnnotation
190    typical_value: Expr*,
191    operator: Token![=>],
192}
193
194strutuct!{ ThenClause
195    then_token: Token![then],
196    expr: Expr*,
197}
198
199strutuct!{ ElseClause
200    else_token: Token![else],
201    expr: Expr*,
202}
203
204strutuct!{ RangeBoundFrom
205    from_token: Token![from],
206    value: Expr*,
207}
208
209strutuct!{ RangeBoundTo
210    to_token: Token![to],
211    value: Expr*,
212}
213
214strutuct!{ WhenCondition
215    when_token: Token![when],
216    condition: Expr*,
217}
218
219strutuct!{ ListStep
220    list_token: Token![list],
221    expr: Expr*,
222}
223
224strutuct!{ DoStep
225    do_token: Token![do],
226    statement: Expr*,
227}
228
229strutuct!{ LoopBody
230    list_step: ListStep?,
231    do_step: DoStep?,
232}
233
234strutuct!{ OfClass
235    of_token: Token![of],
236    parent: Expr*,
237}
238
239strutuct!{ FromInstance
240    from_token: Token![from],
241    instance: Expr*,
242}
243
244strutuct!{ TryFallback
245    Else(ElseClause)
246    Except {
247        except_token: Token![except],
248        exception: Symbol,
249        do_token: Token![do],
250        value: Expr*,
251    }
252}
253
254// Semantic alternatives are nested so every layer becomes a dispatch point.
255// The short layer names keep the generated cumulative type names readable.
256strutuct!{ Expr
257    Literal {
258        Float(FloatLiteral)
259        Integer(IntegerLiteral)
260        RawString(RawStringLiteral)
261        String(StringLiteral)
262    }
263
264    Collection {
265        Sequence(Sequence)
266        List(List)
267        Array(Array)
268        AngleBar(AngleBarList)
269    }
270    Holder(Holder)
271    Op {
272        Bin {
273            Adj {
274                left_operand: Expr*,
275                operator: Adj,
276                right_operand: Expr*,
277            }
278            Regular {
279                left_operand: Expr*,
280                operator: BinaryOperator,
281                right_operand: Expr*,
282            }
283            Member {
284                Dot {
285                    receiver: Expr*,
286                    operator: Token![.],
287                    member: Expr*,
288                }
289                Optional {
290                    receiver: Expr*,
291                    operator: Token![.?],
292                    member: Expr*,
293                }
294            }
295            Index {
296                receiver: Expr*,
297                operator: Token![#],
298                index: Expr*,
299            }
300        }
301        Prefix {
302            operator: PrefixOperator,
303            operand: Expr*,
304        }
305        Postfix {
306            operand: Expr*,
307            operator: PostfixOperator,
308        }
309    }
310    Assign {
311        Simple {
312            Global {
313                variable: Symbol,
314                operator: Token![=],
315                value: Expr*,
316            }
317            Local {
318                variable: Symbol,
319                operator: Token![:=],
320                value: Expr*,
321            }
322        }
323        Parallel {
324            Global {
325                argument_list: AssignmentList*,
326                operator: Token![=],
327                value: Expr*,
328            }
329            Local {
330                argument_list: AssignmentList*,
331                operator: Token![:=],
332                value: Expr*,
333            }
334        }
335        Evaluated {
336            evaluated_domain: Expr*,
337            operator: Token![<-],
338            value: Expr*,
339        }
340        Augmented {
341            target: Expr*,
342            operator: AugmentedOperator,
343            value: Expr*,
344        }
345        Install {
346            Method {
347                method: Expr*,
348                operator: Adj,
349                signature: Expr*,
350                assign_op: Token![:=],
351                typical_value: TypeAnnotation?,
352                function: Expr*,
353            }
354            Op {
355                domain_expr: ExprOp,
356                assign_op: Token![:=],
357                typical_value: TypeAnnotation?,
358                function: Expr*,
359            }
360            New {
361                new_statement: ExprNew,
362                operator: Token![:=],
363                function: Expr*,
364            }
365        }
366        Op {
367            argument_expr: ExprOp,
368            operator: Token![=],
369            value_expr: Expr*,
370        }
371    }
372    Option {
373        key: Expr*,
374        operator: Token![=>],
375        value: Expr*,
376    }
377    Lambda {
378        Variadic {
379            argument: Symbol,
380            operator: Token![->],
381            body: Expr*,
382        }
383        List {
384            arguments: Delimited<Option<ArgumentListContent>>,
385            operator: Token![->],
386            body: Expr*,
387        }
388    }
389    If {
390        if_token: Token![if],
391        condition: Expr*,
392        then_clause: ThenClause,
393        else_clause: ElseClause?,
394    }
395    For {
396        Bare {
397            for_token: Token![for],
398            variable: Symbol,
399            condition: WhenCondition?,
400            body: LoopBody,
401        }
402        Range {
403            for_token: Token![for],
404            variable: Symbol,
405            lower_bound: RangeBoundFrom?,
406            upper_bound: RangeBoundTo?,
407            condition: WhenCondition?,
408            body: LoopBody,
409        }
410        In {
411            for_token: Token![for],
412            variable: Symbol,
413            in_token: Token![in],
414            collection: Expr*,
415            condition: WhenCondition?,
416            body: LoopBody,
417        }
418    }
419    While {
420        while_token: Token![while],
421        condition: Expr*,
422        body: LoopBody,
423    }
424    Try {
425        try_token: Token![try],
426        value: Expr*,
427        on_success: ThenClause?,
428        fallback: TryFallback?,
429    }
430    Quote {
431        Symbol {
432            specifier: Token![symbol],
433            symbol: Symbol,
434        }
435        Local {
436            specifier: Token![local],
437            symbol: Symbol,
438        }
439        Global {
440            specifier: Token![global],
441            symbol: Symbol,
442        }
443        ThreadVariable {
444            specifier: Token![threadVariable],
445            symbol: Symbol,
446        }
447        ThreadLocal {
448            specifier: Token![threadLocal],
449            symbol: Symbol,
450        }
451    }
452    New {
453        new_token: Token![new],
454        class: Expr*,
455        parent_class: OfClass?,
456        instance: FromInstance?,
457    }
458    Control {
459        Break {
460            break_token: Token![break],
461            value: Expr*?,
462        }
463        Continue {
464            continue_token: Token![continue],
465            value: Expr*?,
466        }
467        Return {
468            return_token: Token![return],
469            value: Expr*?,
470        }
471    }
472    Catch {
473        catch_token: Token![catch],
474        value: Expr*,
475    }
476    Throw {
477        throw_token: Token![throw],
478        value: Expr*,
479    }
480    Trap {
481        trap_token: Token![trap],
482        value: Expr*,
483    }
484    Debug {
485        Test {
486            keyword: Token![TEST],
487            value: Expr*?,
488        }
489        Step {
490            keyword: Token![step],
491            value: Expr*?,
492        }
493        Finish {
494            keyword: Token![finish],
495            value: Expr*?,
496        }
497        Shield {
498            keyword: Token![shield],
499            value: Expr*?,
500        }
501        Breakpoint {
502            keyword: Token![breakpoint],
503            value: Expr*?,
504        }
505    }
506    Profile {
507        ElapsedTime {
508            modifier: Token![elapsedTime],
509            value: Expr*,
510        }
511        ElapsedTiming {
512            modifier: Token![elapsedTiming],
513            value: Expr*,
514        }
515        Profile {
516            modifier: Token![profile],
517            value: Expr*,
518        }
519        Time {
520            modifier: Token![time],
521            value: Expr*,
522        }
523        Timing {
524            modifier: Token![timing],
525            value: Expr*,
526        }
527    }
528    Symbol(Symbol)
529}
530}