yukigo-haskell-parser 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/.mocharc.json +4 -0
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +10 -0
  4. package/dist/index.d.ts +7 -0
  5. package/dist/index.js +54 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/parser/grammar.d.ts +28 -0
  8. package/dist/parser/grammar.js +404 -0
  9. package/dist/parser/grammar.js.map +1 -0
  10. package/dist/parser/layoutPreprocessor.d.ts +1 -0
  11. package/dist/parser/layoutPreprocessor.js +22 -0
  12. package/dist/parser/layoutPreprocessor.js.map +1 -0
  13. package/dist/parser/lexer.d.ts +42 -0
  14. package/dist/parser/lexer.js +75 -0
  15. package/dist/parser/lexer.js.map +1 -0
  16. package/dist/parser/preprocessor.d.ts +28 -0
  17. package/dist/parser/preprocessor.js +453 -0
  18. package/dist/parser/preprocessor.js.map +1 -0
  19. package/dist/prelude.d.ts +1 -0
  20. package/dist/prelude.js +205 -0
  21. package/dist/prelude.js.map +1 -0
  22. package/dist/typechecker/DeclarationCollector.d.ts +15 -0
  23. package/dist/typechecker/DeclarationCollector.js +80 -0
  24. package/dist/typechecker/DeclarationCollector.js.map +1 -0
  25. package/dist/typechecker/TypeBuilder.d.ts +12 -0
  26. package/dist/typechecker/TypeBuilder.js +113 -0
  27. package/dist/typechecker/TypeBuilder.js.map +1 -0
  28. package/dist/typechecker/checker.d.ts +80 -0
  29. package/dist/typechecker/checker.js +269 -0
  30. package/dist/typechecker/checker.js.map +1 -0
  31. package/dist/typechecker/core.d.ts +14 -0
  32. package/dist/typechecker/core.js +142 -0
  33. package/dist/typechecker/core.js.map +1 -0
  34. package/dist/typechecker/inference.d.ts +69 -0
  35. package/dist/typechecker/inference.js +984 -0
  36. package/dist/typechecker/inference.js.map +1 -0
  37. package/dist/utils/helpers.d.ts +2 -0
  38. package/dist/utils/helpers.js +25 -0
  39. package/dist/utils/helpers.js.map +1 -0
  40. package/dist/utils/types.d.ts +6 -0
  41. package/dist/utils/types.js +53 -0
  42. package/dist/utils/types.js.map +1 -0
  43. package/package.json +36 -0
  44. package/src/index.ts +55 -0
  45. package/src/parser/grammar.ne +463 -0
  46. package/src/parser/grammar.ts +512 -0
  47. package/src/parser/layoutPreprocessor.ts +21 -0
  48. package/src/parser/lexer.ts +77 -0
  49. package/src/parser/preprocessor.ne +375 -0
  50. package/src/parser/preprocessor.ts +502 -0
  51. package/src/prelude.ts +206 -0
  52. package/src/typechecker/DeclarationCollector.ts +104 -0
  53. package/src/typechecker/TypeBuilder.ts +148 -0
  54. package/src/typechecker/checker.ts +395 -0
  55. package/src/typechecker/core.ts +162 -0
  56. package/src/typechecker/inference.ts +1327 -0
  57. package/src/utils/helpers.ts +29 -0
  58. package/src/utils/types.ts +56 -0
  59. package/tests/parser.spec.ts +823 -0
  60. package/tests/prelude.spec.ts +22 -0
  61. package/tests/preprocessor.spec.ts +69 -0
  62. package/tests/typechecker.spec.ts +310 -0
  63. package/tsconfig.json +17 -0
@@ -0,0 +1,463 @@
1
+ @{%
2
+ import { HSLexer } from "./lexer.js"
3
+ import {
4
+ TypeCast,
5
+ Application,
6
+ ConsExpression,
7
+ StringOperation,
8
+ LogicalBinaryOperation,
9
+ ComparisonOperation,
10
+ ArithmeticBinaryOperation,
11
+ Print,
12
+ ListBinaryOperation,
13
+ ListUnaryOperation,
14
+ ArithmeticUnaryOperation,
15
+ LogicalUnaryOperation,
16
+ SymbolPrimitive,
17
+ ListPrimitive,
18
+ Switch,
19
+ CompositionExpression,
20
+ Lambda,
21
+ TupleExpression,
22
+ DataExpression,
23
+ Function,
24
+ FieldExpression,
25
+ If,
26
+ Record,
27
+ Constructor,
28
+ Field,
29
+ ListComprehension,
30
+ Generator,
31
+ RangeExpression,
32
+ TypeSignature,
33
+ Return,
34
+ GuardedBody,
35
+ Equation,
36
+ Raise,
37
+ UnguardedBody,
38
+ Sequence,
39
+ Otherwise,
40
+ WildcardPattern,
41
+ ConsPattern,
42
+ VariablePattern,
43
+ LiteralPattern,
44
+ AsPattern,
45
+ ConstructorPattern,
46
+ ListPattern,
47
+ TuplePattern,
48
+ TypeAlias,
49
+ ParameterizedType,
50
+ Constraint,
51
+ TypeApplication,
52
+ LetInExpression,
53
+ SimpleType,
54
+ ListType,
55
+ TupleType,
56
+ NumberPrimitive,
57
+ CharPrimitive,
58
+ StringPrimitive,
59
+ BooleanPrimitive,
60
+ SourceLocation
61
+ } from "yukigo-ast";
62
+
63
+ const filter = d => {
64
+ return d.filter((token) => token !== null);
65
+ };
66
+
67
+ const loc = (token) => new SourceLocation(token.line, token.col);
68
+
69
+ %}
70
+ @preprocessor typescript
71
+ @lexer HSLexer
72
+
73
+ program -> declaration:+ {% (d) => d[0].filter(x => x !== null) %}
74
+
75
+ declaration -> (function_declaration
76
+ | function_signature
77
+ | type_declaration
78
+ | data_declaration
79
+ | comment
80
+ | empty_line
81
+ | apply_operator) {% (d) => d[0][0] %}
82
+
83
+ comment -> %comment {% d => null %}
84
+
85
+ empty_line -> _ %NL {% d => null %}
86
+
87
+ expression ->
88
+ (type_cast
89
+ | letin_expression
90
+ | if_expression
91
+ | case_expression) {% (d) => d[0][0] %}
92
+
93
+ type_cast -> apply_operator _ "::" _ type {% (d) => new TypeCast(d[0], d[4]) %}
94
+ | apply_operator {% id %}
95
+
96
+ # Operation rules
97
+
98
+ # priority 0
99
+ apply_operator ->
100
+ bind_expression _ "$" _ apply_operator {% (d) => new Application(d[0], d[4]) %}
101
+ | bind_expression {% id %}
102
+
103
+ # priority 1
104
+ bind_expression ->
105
+ logical_expression _ ">>=" _ bind_expression {% (d) => new Application(new Application(new SymbolPrimitive("(>>=)"), d[0]), d[4]) %}
106
+ | logical_expression _ ">>" _ bind_expression {% (d) => new Application(new Application(new SymbolPrimitive("(>>)"), d[0]), d[4]) %}
107
+ | logical_expression {% id %}
108
+
109
+ # priority 3
110
+ logical_expression ->
111
+ comparison _ "&&" _ logical_expression {% (d) => new LogicalBinaryOperation("And", d[0], d[4]) %}
112
+ | comparison _ "||" _ logical_expression {% (d) => new LogicalBinaryOperation("Or", d[0], d[4]) %}
113
+ | comparison {% id %}
114
+
115
+ # priority 4
116
+ comparison ->
117
+ cons_expression _ comparison_operator _ cons_expression {% (d) => new ComparisonOperation(d[2], d[0], d[4]) %}
118
+ | cons_expression {% id %}
119
+
120
+ # priority 5
121
+ cons_expression ->
122
+ concatenation _ ":" _ cons_expression {% (d) => new ConsExpression(d[0], d[4]) %}
123
+ | concatenation {% id %}
124
+
125
+ concatenation ->
126
+ addition _ "++" _ concatenation {% (d) => d[0] instanceof StringPrimitive || d[4] instanceof StringPrimitive ? new StringOperation("Concat", d[0], d[4]) : new ListBinaryOperation("Concat", d[0], d[4]) %}
127
+ | addition {% id %}
128
+
129
+ # priority 6
130
+ addition ->
131
+ addition _ "+" _ multiplication {% (d) => new ArithmeticBinaryOperation("Plus", d[0], d[4]) %}
132
+ | addition _ "-" _ multiplication {% (d) => new ArithmeticBinaryOperation("Minus", d[0], d[4]) %}
133
+ | multiplication {% id %}
134
+
135
+ # priority 7
136
+ multiplication ->
137
+ multiplication _ "*" _ power {% (d) => new ArithmeticBinaryOperation("Multiply", d[0], d[4]) %}
138
+ | multiplication _ "/" _ power {% (d) => new ArithmeticBinaryOperation("Divide", d[0], d[4]) %}
139
+ | power {% id %}
140
+
141
+ # priority 8
142
+ power ->
143
+ unary_negation _ "**" _ power {% (d) => new ArithmeticBinaryOperation("Power", d[0], d[4]) %}
144
+ | unary_negation _ "^" _ power {% (d) => new ArithmeticBinaryOperation("Power", d[0], d[4]) %}
145
+ | unary_negation _ "^^" _ power {% (d) => new ArithmeticBinaryOperation("Power", d[0], d[4]) %}
146
+ | unary_negation {% id %}
147
+
148
+ unary_negation ->
149
+ "-" _ unary_negation {% (d) => new ArithmeticUnaryOperation("Negation", d[2]) %}
150
+ | index_access {% id %}
151
+
152
+ # priority 9
153
+ index_access ->
154
+ index_access _ "!!" _ composition_expression {% (d) => new ListBinaryOperation("GetAt", d[0], d[4]) %}
155
+ | composition_expression {% id %}
156
+
157
+ composition_expression ->
158
+ composition_expression _ "." _ infix_operator_expression {% (d) => new CompositionExpression(d[0], d[4]) %}
159
+ | infix_operator_expression {% id %}
160
+
161
+ infix_operator_expression ->
162
+ infix_operator_expression _ "`" _ variable _ "`" _ application {% (d) => new Application(new Application(d[4], d[0]), d[8]) %}
163
+ | application {% id %}
164
+
165
+ application ->
166
+ "error" __ primary {% d => new Raise(d[2]) %}
167
+ | primary ((_ | (_ %NL __)) primary):* {% (d) => {
168
+ if (d[1].length === 0) return d[0];
169
+ return d[1].reduce((left, right) => new Application(left, right[1]), d[0]);
170
+ } %}
171
+
172
+ operator ->
173
+ ("=="
174
+ | "/="
175
+ | "<"
176
+ | ">"
177
+ | "<="
178
+ | "&&"
179
+ | "||"
180
+ | ">="
181
+ | "++"
182
+ | "+"
183
+ | ","
184
+ | "*"
185
+ | "/"
186
+ | ":") {% (d) => d[0][0].value %}
187
+
188
+ left_section -> "(" _ expression _ operator _ ")" {% (d) => new Application(new SymbolPrimitive(d[4]), d[2]) %}
189
+
190
+ right_section -> "(" _ operator _ expression _ ")" {% (d) => {
191
+ const flipBody = new SymbolPrimitive("flip");
192
+ const op = new SymbolPrimitive(d[2]);
193
+ const expr = d[4];
194
+ const flipAppliedToOp = new Application(flipBody, op);
195
+ return new Application(flipAppliedToOp, expr);
196
+ }
197
+ %}
198
+
199
+ operator_section -> "(" _ operator _ ")" {% (d) => new SymbolPrimitive(d[2]) %}
200
+
201
+ primary ->
202
+ primitive {% id %}
203
+ | variable {% id %}
204
+ | constr {% id %}
205
+ | tuple_expression {% id %}
206
+ | left_section {% id %}
207
+ | right_section {% id %}
208
+ | operator_section {% id %}
209
+ | list_literal {% id %}
210
+ | lambda_expression {% id %}
211
+ | data_expression {% id %}
212
+ | list_comprehension {% id %}
213
+ | "(" _ expression _ ")" {% (d) => d[2] %}
214
+ | "[" _ range_expression _ "]" {% (d) => d[2] %}
215
+ # Expression rules
216
+
217
+ # List comprehension rules
218
+ list_comprehension ->
219
+ "[" _ expression _ "|" _ comprehension_clause_list _ "]" {% (d) => {
220
+ return new ListComprehension(d[2], d[6]);
221
+ } %}
222
+
223
+ comprehension_clause_list ->
224
+ comprehension_clause (_ "," _ comprehension_clause):* {% (d) => {
225
+ return [d[0], ...d[1].map((x) => x[3])];
226
+ } %}
227
+
228
+ comprehension_clause ->
229
+ variable _ "<-" _ expression {% (d) => new Generator(d[0], d[4]) %}
230
+ | expression {% id %}
231
+
232
+ lambda_expression ->
233
+ "(" _ "\\" _ parameter_list _ "->" _ expression _ ")" {% (d) => new Lambda(d[4], d[8]) %}
234
+
235
+ tuple_expression -> "(" _ tuple_value (_ "," _ tuple_value):+ _ ")" {% (d) => new TupleExpression([d[2], ...d[3].map(x => x[3])]) %}
236
+ tuple_value -> expression {% id %}
237
+
238
+
239
+ data_expression -> constr _ %lbracket _ fields_expressions _ %rbracket {% (d) => new DataExpression(d[0], d[4]) %}
240
+
241
+ fields_expressions -> field_exp (_ "," _ field_exp):* {% (d) => [d[0], ...d[1].map(x => x[3])] %}
242
+
243
+ field_exp -> variable _ "=" _ expression {% (d) => new FieldExpression(d[0], d[4]) %}
244
+
245
+ if_expression -> "if" __ expression __ "then" __ expression __ "else" __ expression {% (d) => new If(d[2], d[6], d[10]) %}
246
+
247
+ letin_expression -> "let" (_ "{" _) bindings_list:? (_ "}" _) "in" _ expression {% (d) => new LetInExpression(new Sequence(d[2] ?? []), d[6]) %}
248
+
249
+ case_expression -> "case" _ expression _ "of" (_ "{" _) case_arms (_ "}" _) {% (d) => new Switch(d[2], d[6]) %}
250
+
251
+ case_arms -> case_arm ((_ ";" _) case_arm):* {% (d) => [d[0], ...d[1].map(x => x[1])] %}
252
+
253
+ case_arm -> pattern _ "->" _ expression {% (d) => ({condition: d[0], body: d[4] }) %}
254
+
255
+ # Data rules
256
+
257
+ data_declaration -> "data" __ constr (__ type_variable):* _ "=" _ constructor_def (_ "|" _ constructor_def):* deriving_clause:? {%
258
+ (d) => new Record(d[2], [d[7], ...d[8].map(x => x[3])], d[9])
259
+ %}
260
+
261
+ deriving_clause ->
262
+ _ "deriving" _ deriving_spec {% (d) => d[3] %}
263
+
264
+ deriving_spec ->
265
+ "(" _ deriving_classes _ ")" {% (d) => d[2] %}
266
+ | constr {% (d) => [d[0]] %}
267
+
268
+ deriving_classes ->
269
+ %typeClass (_ "," _ %typeClass):* {% (d) => [new SymbolPrimitive(d[0].value), ...d[1].map(x => new SymbolPrimitive(x[3].value))] %}
270
+
271
+ constructor_def ->
272
+ constr _ (%NL __):? %lbracket _ (%NL _):? field_list _ (%NL _):? %rbracket {% (d) => new Constructor(d[0], d[6]) %}
273
+ | constr (__ simple_type):* {% (d) => new Constructor(d[0], d[1].map(x => new Field(undefined, x[1]))) %}
274
+
275
+ field_list -> field (_ "," _ (%NL _):? field):* {% (d) => [d[0], ...d[1].map(x => x[4])]%}
276
+
277
+ field -> variable _ %typeEquals _ type {% (d) => new Field(d[0], d[4]) %}
278
+
279
+ # Function rules
280
+
281
+ binding_name ->
282
+ "(" _ %op _ ")" {% d => new SymbolPrimitive(`${d[2].value}`) %}
283
+ | variable {% id %}
284
+
285
+ function_signature -> binding_name (_ "," _ binding_name):* _ %typeEquals _ type {% (d) => new TypeSignature(d[0], d[5]) %}
286
+
287
+ function_declaration ->
288
+ variable equation {% (d) => new Function(d[0], [d[1]]) %}
289
+ | "(" _ %op _ ")" equation {% (d) => new Function(new SymbolPrimitive(`${d[2].value}`), [d[5]]) %}
290
+
291
+ return_expression -> expression {% d => new Return(d[0]) %}
292
+
293
+ where_clause -> "where" _ "{" _ bindings_list _ "}" {% d => d[4] %}
294
+
295
+ bindings_list -> function_declaration ((_ ";" _) function_declaration):* {% d => [d[0], ...d[1].map(x => x[1])] %}
296
+
297
+ equation ->
298
+ params (%NL __):? guarded_rhs (_ where_clause):? {% (d) => {
299
+ const body = d[2];
300
+ const finalBody = d[3]
301
+ ? new LetInExpression(d[3], body)
302
+ : body;
303
+ return new Equation(d[0], finalBody);
304
+ } %}
305
+ | params %assign ((_ %NL __) | _) return_expression (_ where_clause):? {% d => new Equation(d[0], new UnguardedBody(new Sequence(d[4] ? [...d[4][1], d[3]] : [d[3]])), d[3]) %}
306
+
307
+ params ->
308
+ __ parameter_list _ {% d => d[1] %}
309
+ | _ {% d => [] %}
310
+
311
+ guarded_rhs ->
312
+ guarded_branch ((_ %NL __) | _) guarded_rhs {% (d) => [d[0], ...d[2]] %}
313
+ | guarded_branch {% (d) => [d[0]] %}
314
+
315
+ guarded_branch ->
316
+ "|" ((_ %NL __) | _) condition ((_ %NL __) | _) "=" ((_ %NL __) | _) expression {% (d) => new GuardedBody(d[2], d[6]) %}
317
+
318
+ condition ->
319
+ "otherwise" {% d => new Otherwise() %}
320
+ | expression {% d => d[0] %}
321
+
322
+ parameter_list -> pattern (__ pattern):* {% (d) => [d[0], ...d[1].map(x => x[1])] %}
323
+
324
+ # Patterns
325
+
326
+ pattern -> cons_pattern {% id %}
327
+
328
+ cons_pattern ->
329
+ "(" _ cons_pattern (_ ":" _ cons_pattern):+ _ ")" {%
330
+ (d) => {
331
+ const patterns = [d[2], ...d[3].map(item => item[3])];
332
+ return patterns.reduceRight((tail, head, index, arr) => {
333
+ if (index === arr.length - 1) return tail;
334
+ return new ConsPattern(head, tail);
335
+ });
336
+ }
337
+ %}
338
+ | simple_pattern {% id %}
339
+
340
+ simple_pattern ->
341
+ (as_pattern
342
+ | constructor_pattern
343
+ | list_pattern
344
+ | tuple_pattern
345
+ #| record_pattern
346
+ | literal_pattern
347
+ | variable_pattern
348
+ | wildcard_pattern
349
+ | paren_pattern) {% (d) => d[0][0] %}
350
+
351
+ wildcard_pattern -> %anonymousVariable {% (d) => new WildcardPattern() %}
352
+
353
+ paren_pattern -> "(" _ pattern _ ")" {% (d) => d[2] %}
354
+
355
+ variable_pattern -> variable {% (d) => new VariablePattern(d[0]) %}
356
+
357
+ literal_pattern -> primitive {% (d) => new LiteralPattern(d[0]) %}
358
+
359
+ as_pattern -> (variable_pattern | wildcard_pattern) "@" pattern {% (d) => new AsPattern(d[0][0], d[2]) %}
360
+
361
+ constructor_pattern ->
362
+ "(" _ constr (__ pattern):+ _ ")" {% (d) => new ConstructorPattern(d[2].value, d[3].map(x => x[1])) %}
363
+ | constr {% (d) => new ConstructorPattern(d[0].value, []) %}
364
+
365
+ # record_pattern ->
366
+ # constr:? _ %lbracket _ field_pattern_list _ %rbracket {% (d) => ({
367
+ # type: "RecordPattern",
368
+ # constructor: d[0] ? d[0].value : null,
369
+ # fields: d[4]
370
+ # }) %}
371
+
372
+ field_pattern_list -> field_pattern (_ "," _ field_pattern):* {% (d) => [d[0], ...d[1].map(x => x[3])] %}
373
+
374
+ field_pattern -> variable _ "=" _ pattern {% (d) => ({ field: d[0].value, pattern: d[4] }) %}
375
+
376
+ list_pattern -> "[" _ pattern_list:? _ "]" {% (d) => new ListPattern(d[2] || []) %}
377
+
378
+ pattern_list -> pattern (_ "," _ pattern):* {% (d) => [d[0], ...d[1].map(x => x[3])] %}
379
+
380
+ tuple_pattern -> "(" _ pattern (_ "," _ pattern):+ _ ")" {% (d) => new TuplePattern([d[2], ...d[3].map(x => x[3])]) %}
381
+
382
+ # Type rules
383
+
384
+ type_declaration -> "type" __ constr (__ variable_list):? _ "=" _ type {% (d) => new TypeAlias(d[2], d[3] ? d[3][1] : [], d[7]) %}
385
+
386
+ variable_list -> variable (__ variable):* {% (d) => [d[0].value, ...d[1].map(x => x[1].value)] %}
387
+
388
+ type -> function_type {% id %}
389
+
390
+ constrained_type -> constraint_list _ %arrow _ type {% (d) => new ParameterizedType([], d[4], d[0]) %}
391
+
392
+ context ->
393
+ constraint {% (d) => [d[0]] %}
394
+ | "(" _ constraint_list _ ")" {% (d) => d[2] %}
395
+
396
+ constraint_list ->
397
+ constraint (_ "," _ constraint):* {% (d) =>
398
+ [d[0], ...d[1].map(x => x[3])]
399
+ %}
400
+
401
+ constraint -> %typeClass (_ application_type):+ {% (d) => new Constraint(d[0].value, d[1].map(x => x[1])) %}
402
+
403
+ function_type ->
404
+ (context _ %arrow _):? (application_type (_ | (_ %NL __)) %typeArrow (_ | (_ %NL __))):* application_type {% (d) => {
405
+ const constraints = d[0] ? d[0][0] : [];
406
+
407
+ if (d[1].length > 0)
408
+ return new ParameterizedType(d[1].map(x => x[0]), d[2], constraints);
409
+
410
+ if (constraints.length === 0)
411
+ return d[2];
412
+
413
+ return new ParameterizedType([], d[2], constraints);
414
+ }
415
+ %}
416
+
417
+ application_type ->
418
+ simple_type (_ simple_type):+ {% (d) => d[1].reduce((acc, arg) => new TypeApplication(acc, arg[1]), d[0]) %}
419
+ | simple_type {% id %}
420
+
421
+ simple_type ->
422
+ (type_variable | type_constructor) {% (d) => new SimpleType(d[0][0].value, []) %}
423
+ | "[" _ type _ "]" {% (d) => new ListType(d[2], []) %}
424
+ | "(" _ type (_ "," _ type):+ _ ")" {% (d) => new TupleType([d[2], ...d[3].map(x => x[3])], []) %}
425
+ | "(" _ type _ ")" {% (d) => d[2] %}
426
+
427
+ type_variable -> variable {% ([v]) => ({ value: v.value }) %}
428
+ type_constructor -> constr {% ([c]) => ({ value: c.value }) %}
429
+
430
+ # Misc rules
431
+
432
+ constr -> %constructor {% ([c]) => new SymbolPrimitive(c.value, loc(c)) %} # constr because js doesnt like rules called constructor
433
+ variable -> %variable {% ([v]) => new SymbolPrimitive(v.value, loc(v)) %}
434
+
435
+ list_literal ->
436
+ "[" _ "]" {% (_) => new ListPrimitive([]) %}
437
+ | "[" _ expression_list _ "]" {% ([_, __, list]) => new ListPrimitive(list) %}
438
+
439
+ range_expression ->
440
+ expression _ ".." {% (d) => new RangeExpression(d[0]) %} # [start ..]
441
+ | expression _ ".." _ expression {% (d) => new RangeExpression(d[0], d[4]) %} # [start .. end]
442
+ | expression _ "," _ expression _ ".." {% (d) => new RangeExpression(d[0], undefined, d[4]) %} # [start, second ..]
443
+ | expression _ "," _ expression _ ".." _ expression {% (d) => new RangeExpression(d[0], d[6], d[4]) %} # [start, second .. end]
444
+
445
+ expression_list -> expression (_ "," _ expression):* {% (d) => [d[0], ...d[1].map(x => x[3])] %}
446
+
447
+ comparison_operator ->
448
+ "==" {% (d) => "Equal" %}
449
+ | "/=" {% (d) => "NotEqual" %}
450
+ | "<" {% (d) => "LessThan" %}
451
+ | ">" {% (d) => "GreaterThan" %}
452
+ | "<=" {% (d) => "LessOrEqualThan" %}
453
+ | ">=" {% (d) => "GreaterOrEqualThan" %}
454
+
455
+ primitive ->
456
+ %number {% ([n]) => new NumberPrimitive(Number(n.value), loc(n)) %}
457
+ | %char {% ([c]) => new CharPrimitive(c.value, loc(c)) %}
458
+ | %string {% ([s]) => new StringPrimitive(s.value.slice(1, -1), loc(s)) %}
459
+ | %bool {% ([b]) => new BooleanPrimitive(b.value === 'True' ? true : false, loc(b)) %}
460
+
461
+ _ -> %WS:*
462
+
463
+ __ -> %WS:+