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,77 @@
1
+ import moo, { Lexer } from "moo";
2
+ import { keywords } from "../utils/types.js";
3
+ import { makeLexer } from "moo-ignore";
4
+ import IndentationLexer from "moo-indentation-lexer";
5
+
6
+ export const HaskellLexerConfig = {
7
+ NL: { match: /\r?\n/, lineBreaks: true },
8
+ anonymousVariable: "_",
9
+ WS: / |\t/,
10
+ comment: /--.*?$|{-[\s\S]*?-}/,
11
+ number:
12
+ /0[xX][0-9a-fA-F]+|0[bB][01]+|0[oO][0-7]+|(?:\d*\.\d+|\d+)(?:[eE][+-]?\d+)?/,
13
+ char: /'(?:\\['\\bfnrtv0]|\\u[0-9a-fA-F]{4}|[^'\\\n\r])?'/,
14
+ string: /"(?:\\["\\bfnrtv0]|\\u[0-9a-fA-F]{4}|[^"\\\n\r])*"/,
15
+ //template: /`(?:\\[\s\S]|[^\\`])*`/,
16
+ backtick: "`",
17
+ lparen: "(",
18
+ rparen: ")",
19
+ lbracket: "{",
20
+ rbracket: "}",
21
+ lsquare: "[",
22
+ rsquare: "]",
23
+ rangeOperator: "..",
24
+ semicolon: ";",
25
+ typeArrow: "->",
26
+ leftArrow: "<-",
27
+ typeEquals: "::",
28
+ question: "?",
29
+ arrow: "=>",
30
+ bool: {
31
+ match: ["True", "False"],
32
+ },
33
+ op: /,|>>=|>>|\\\\|\\|\.|\+\+|\+|\-|\*\*|\*|===|!==|==|\/=|<=|>=|<|>|&&|\/|\|\||\.\.|\$|\^\^|\^|#|@|~|!!|!|%|\?|:|&|\||`/,
34
+ assign: "=",
35
+ constructor: {
36
+ match: /[A-Z][a-zA-Z0-9']*/,
37
+ type: moo.keywords({
38
+ typeClass: [
39
+ "Foldable",
40
+ "Bounded",
41
+ "Enum",
42
+ "Eq",
43
+ "Floating",
44
+ "Fractional",
45
+ "Functor",
46
+ "Integral",
47
+ "Ix",
48
+ "Monad",
49
+ "MonadPlus",
50
+ "Num",
51
+ "Ord",
52
+ "Random",
53
+ "RandomGen",
54
+ "Read",
55
+ "Real",
56
+ "RealFloat",
57
+ "RealFrac",
58
+ "Show",
59
+ ],
60
+ }),
61
+ },
62
+ variable: {
63
+ match: /[a-z_][a-zA-Z0-9_']*/,
64
+ type: moo.keywords({
65
+ otherwise: "otherwise",
66
+ error: "error",
67
+ keyword: keywords,
68
+ }),
69
+ },
70
+ };
71
+
72
+ export const HSLexer: Lexer = makeLexer(HaskellLexerConfig, []);
73
+ export const PreprocessorLexer: Lexer = new IndentationLexer({
74
+ lexer: moo.compile(HaskellLexerConfig),
75
+ indentationType: "WS",
76
+ newlineType: 'NL',
77
+ });
@@ -0,0 +1,375 @@
1
+ @{%
2
+ import { HSLexer } from "./lexer.js"
3
+
4
+ const filter = d => {
5
+ return d.filter((token) => token !== null);
6
+ };
7
+
8
+ %}
9
+ @preprocessor typescript
10
+ @lexer HSLexer
11
+
12
+ program ->
13
+ declaration:* {% (d) => d[0].filter(x => x !== null).join("\n") %}
14
+ | apply_operator {% id %}
15
+
16
+ declaration -> (function_declaration
17
+ | function_signature
18
+ | type_declaration
19
+ | data_declaration
20
+ | comment
21
+ | empty_line) {% (d) => d[0][0] %}
22
+
23
+ comment -> %comment {% d => null %}
24
+
25
+ empty_line -> _ %NL {% d => null %}
26
+
27
+ expression ->
28
+ (type_cast
29
+ | letin_expression
30
+ | if_expression
31
+ | case_expression) {% (d) => `${d[0][0]}` %}
32
+
33
+ type_cast -> apply_operator _ "::" _ type {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
34
+ | apply_operator {% (d) => d[0] %}
35
+
36
+ # Operation rules
37
+
38
+ apply_operator ->
39
+ logical_expression _ "$" _ apply_operator {% (d) => `${d[0]} $ ${d[4]}` %}
40
+ | logical_expression {% (d) => d[0] %}
41
+
42
+ logical_expression ->
43
+ comparison _ "&&" _ logical_expression {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
44
+ | comparison _ "||" _ logical_expression {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
45
+ | comparison {% (d) => d[0] %}
46
+
47
+ comparison ->
48
+ cons_expression _ comparison_operator _ cons_expression {% (d) => `${d[0]} ${d[2]} ${d[4]}` %}
49
+ | cons_expression {% (d) => d[0] %}
50
+
51
+ cons_expression ->
52
+ concatenation _ ":" _ cons_expression {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
53
+ | concatenation {% (d) => d[0] %}
54
+
55
+ concatenation ->
56
+ addition _ "++" _ concatenation {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
57
+ | addition {% (d) => d[0] %}
58
+
59
+ addition ->
60
+ addition _ "+" _ multiplication {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
61
+ | addition _ "-" _ multiplication {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
62
+ | multiplication {% (d) => d[0] %}
63
+
64
+ multiplication ->
65
+ multiplication _ "*" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
66
+ | multiplication _ "/" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
67
+ | power {% (d) => d[0] %}
68
+
69
+ power ->
70
+ unary_negation _ "**" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
71
+ | unary_negation _ "^" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
72
+ | unary_negation _ "^^" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
73
+ | unary_negation {% (d) => d[0] %}
74
+
75
+ unary_negation ->
76
+ "-" _ unary_negation {% (d) => `-${d[2]}` %}
77
+ | index_access {% (d) => d[0] %}
78
+
79
+ index_access ->
80
+ index_access _ "!!" _ composition_expression {% (d) => `${d[0]} !! ${d[4]}` %}
81
+ | composition_expression {% d => d[0] %}
82
+
83
+ composition_expression ->
84
+ composition_expression _ "." _ infix_operator_expression {% (d) => `${d[0]} . ${d[4]}` %}
85
+ | infix_operator_expression {% d => d[0] %}
86
+
87
+ infix_operator_expression ->
88
+ infix_operator_expression _ "`" _ variable _ "`" _ application {% (d) => `${d[0]} \`${d[4]}\` ${d[8]}` %}
89
+ | application {% d => d[0] %}
90
+
91
+ application ->
92
+ "error" __ primary {% d => `error ${d[2]}` %}
93
+ | primary ((__ | _ %NL __) primary):* {% (d) => {
94
+ if (d[1].length === 0) return d[0];
95
+ return [d[0], ...d[1].map(x => x[1])].join(" ");
96
+ } %}
97
+
98
+ operator ->
99
+ ("=="
100
+ | "/="
101
+ | "<"
102
+ | ">"
103
+ | "<="
104
+ | ">="
105
+ | "++"
106
+ | "+"
107
+ | ","
108
+ | "*"
109
+ | "/"
110
+ | ":") {% (d) => d[0][0].value %}
111
+
112
+ left_section -> "(" _ expression _ operator _ ")" {% (d) => `(${d[2]} ${d[4]})`%}
113
+
114
+ right_section -> "(" _ operator _ expression _ ")" {% (d) => `(${d[2]} ${d[4]})`%}
115
+
116
+ operator_section -> "(" _ operator _ ")" {% (d) => `(${d[2]})` %}
117
+
118
+ primary ->
119
+ primitive {% (d) => d[0] %}
120
+ #| primitive_operator {% (d) => d[0] %}
121
+ | variable {% (d) => d[0] %}
122
+ | constr {% (d) => d[0] %}
123
+ | tuple_expression {% (d) => d[0] %}
124
+ | left_section {% (d) => d[0] %}
125
+ | right_section {% (d) => d[0] %}
126
+ | operator_section {% (d) => d[0] %}
127
+ | "(" _ expression _ ")" {% (d) => `(${d[2]})` %}
128
+ | "[" _ range_expression _ "]" {% (d) => `[${d[2]}]` %}
129
+ | list_literal {% (d) => d[0] %}
130
+ | lambda_expression {% (d) => d[0] %}
131
+ | data_expression {% d => d[0] %}
132
+ | list_comprehension {% (d) => d[0] %}
133
+
134
+ # Expression rules
135
+
136
+ # List comprehension rules
137
+ list_comprehension ->
138
+ "[" _ expression _ "|" _ comprehension_clause_list _ "]" {% (d) => `[${d[2]} | ${d[6]}]` %}
139
+
140
+ comprehension_clause_list ->
141
+ comprehension_clause (_ "," _ comprehension_clause):* {% (d) => [d[0], ...d[1].map((x) => x[3])].join(`, `) %}
142
+
143
+ comprehension_clause ->
144
+ variable _ "<-" _ expression {% (d) => `${d[0]} <- ${d[4]}` %}
145
+ | expression {% (d) => d[0] %}
146
+
147
+ lambda_expression ->
148
+ "(" _ "\\" _ parameter_list _ "->" (_ | _ %NL __) expression (_ | _ %NL __) ")" {% (d) => `(\\${d[4]} -> ${d[8]})` %}
149
+
150
+ tuple_expression -> "(" _ tuple_value (_ "," _ tuple_value):+ _ ")" {% (d) => `(` + [d[2], ...d[3].map(x => `,${x[3]}`)].join(``) + `)` %}
151
+ tuple_value -> expression {% d => d[0] %}
152
+
153
+
154
+ data_expression -> constr _ %lbracket _ fields_expressions _ %rbracket {%
155
+ (d) => d[0] + ` { ` + d[4] + ` }`
156
+ %}
157
+
158
+ fields_expressions -> field_exp (_ "," _ field_exp):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(", ") %}
159
+
160
+ field_exp -> variable _ "=" _ expression {% (d) => d[0] + ` = ` + d[4] %}
161
+
162
+ if_expression ->
163
+ "if" (__ | (_ %NL _)) expression (__ | (_ %NL _)) "then" (__ | (_ %NL __)) expression (__ | (_ %NL _)) "else" (__ | (_ %NL __)) expression {%
164
+ (d) => `if ` + d[2] + ` then ` + d[6] + ` else ` + d[10]
165
+ %}
166
+
167
+ letin_expression -> "let" (_ | (_ "{" _) | (_ %NL __)) bindings_list:? (_ | (_ "}" _) | (_ %NL __)) "in" ((_ %NL __) | _) expression {% (d) => `let { ${(d[2] ?? ``)} }` + ` in ` + d[6] %}
168
+
169
+ case_expression ->
170
+ "case" ((_ %NL __) | _) expression ((_ %NL __) | _) "of" (_ | (_ "{" _) | (_ %NL __)) case_arms (_ "}" _):? {% (d) => `case ${d[2]} of { ${d[6]} }` %}
171
+
172
+ case_arms ->
173
+ case_arm (((_ %NL __) | (_ ";" _)) case_arm):* {% (d) => [d[0], ...d[1].map(x => x[1])].join("; ") %}
174
+
175
+ case_arm ->
176
+ pattern ((_ %NL __) | _) "->" ((_ %NL __) | _) expression {% (d) => d[0] + ` -> ` + d[4] %}
177
+
178
+ # Data rules
179
+
180
+ data_declaration -> "data" __ constr (__ type_variable):* _ "=" _ constructor_def (_ "|" _ constructor_def):* deriving_clause:? {%
181
+ (d) => `data ` + d[2] + (d[3] ? ` ` + d[3].map(x => x[1]).join(" ") : ``) + ` = ` + [d[7], ...d[8].map(x => `| ${x[3]}`)].join(" ") + (d[9] ?? ``)
182
+ %}
183
+
184
+ deriving_clause ->
185
+ __ "deriving" _ deriving_spec {% (d) => ` deriving ` + d[3] %}
186
+
187
+ deriving_spec ->
188
+ "(" _ deriving_classes _ ")" {% (d) => `(${d[2]})` %}
189
+ | constr {% (d) => d[0] %}
190
+
191
+ deriving_classes ->
192
+ %typeClass (_ "," _ %typeClass):* {% (d) => [d[0].value, ...d[1].map(x => x[3].value)].join(", ") %}
193
+
194
+ constructor_def ->
195
+ constr _ (%NL __):? %lbracket _ (%NL _):? field_list _ (%NL _):? %rbracket {% (d) => d[0] + ` { ` + d[6] + ` }` %}
196
+ | constr (__ simple_type):* {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
197
+
198
+ field_list -> field (_ "," _ (%NL _):? field):* {% (d) => [d[0], ...d[1].map(x => x[4])].join(", ") %}
199
+
200
+ field -> variable _ %typeEquals _ type {% (d) => d[0] + ` :: ` + d[4] %}
201
+
202
+ # Function rules
203
+
204
+ binding_name ->
205
+ "(" _ %op _ ")" {% d => `(${d[2].value})` %}
206
+ | variable {% d => d[0] %}
207
+
208
+ function_signature ->
209
+ binding_name (_ "," _ binding_name):* _ %typeEquals (_ | (_ %NL __)) type {% (d) => [`${d[0]} :: ${d[5]}`, ...d[1].map(x => `${x[3]} :: ${d[5]}`)].join("\n") %}
210
+
211
+ function_declaration ->
212
+ variable equation {% (d) => d[0] + d[1] %}
213
+ | "(" _ %op _ ")" equation {% (d) => `(${d[2]})` + d[5] %}
214
+
215
+ return_expression -> expression {% d => d[0] %}
216
+
217
+ where_clause -> "where" (_ | (_ "{" _) | (_ %NL __)) bindings_list (_ | (_ "}" _)) {% d => `where { ${d[2]} }` %}
218
+
219
+ bindings_list -> function_declaration (((_ ";" _) | (_ %NL __)) function_declaration):* {% d => [d[0], ...d[1].map(x => x[1])].join('; ') %}
220
+
221
+ equation ->
222
+ params (%NL __):? guarded_rhs (((_ %NL __) | _) where_clause):? {% (d) => {
223
+ const body = d[2];
224
+ const whereClause = d[3] ? ` ` + d[3][1] : ``;
225
+ return d[0] + ` ` + body + whereClause;
226
+ } %}
227
+ | params %assign ((_ %NL __) | _) return_expression (((_ %NL __) | _) where_clause):? {% d => d[0] + ` = ` + d[3] + (d[4] ? ` ` + d[4][1] : ``) %}
228
+
229
+ params ->
230
+ __ parameter_list _ {% d => ` ${d[1]}` %}
231
+ | _ {% d => `` %}
232
+
233
+ guarded_rhs ->
234
+ guarded_branch ((_ %NL __) | _) guarded_rhs {% (d) => `${d[0]} ${d[2]}` %}
235
+ | guarded_branch {% (d) => d[0] %}
236
+
237
+ guarded_branch ->
238
+ "|" ((_ %NL __) | _) condition ((_ %NL __) | _) "=" ((_ %NL __) | _) expression {% (d) => `| ${d[2]} = ${d[6]}` %}
239
+
240
+ condition ->
241
+ "otherwise" {% d => `otherwise` %}
242
+ | expression {% d => d[0] %}
243
+
244
+ parameter_list -> pattern (__ pattern):* {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
245
+
246
+ # Patterns
247
+
248
+ pattern -> ("~" _):? cons_pattern {% (d) => d[1] %}
249
+
250
+ cons_pattern ->
251
+ "(" _ cons_pattern (_ ":" _ cons_pattern):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[3])].join(":")})` %}
252
+ | simple_pattern {% (d) => d[0] %}
253
+
254
+ simple_pattern ->
255
+ (as_pattern
256
+ | constructor_pattern
257
+ | list_pattern
258
+ | tuple_pattern
259
+ #| record_pattern
260
+ | literal_pattern
261
+ | variable_pattern
262
+ | wildcard_pattern
263
+ | paren_pattern) {% (d) => d[0][0] %}
264
+
265
+ wildcard_pattern -> %anonymousVariable {% (d) => `_` %}
266
+
267
+ paren_pattern -> "(" _ pattern _ ")" {% (d) => `(${d[2]})` %}
268
+
269
+ variable_pattern -> variable {% (d) => d[0] %}
270
+
271
+ literal_pattern -> primitive {% (d) => d[0] %}
272
+
273
+ as_pattern -> (variable_pattern | wildcard_pattern) "@" pattern {% (d) => d[0][0] + `@` + d[2] %}
274
+
275
+ constructor_pattern ->
276
+ "(" _ constr (__ pattern):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[1])].join(" ")})` %}
277
+ | constr {% (d) => `${d[0]}` %}
278
+
279
+ # record_pattern ->
280
+ # constr:? _ %lbracket _ field_pattern_list _ %rbracket {% (d) => ({
281
+ # type: "RecordPattern",
282
+ # constructor: d[0] ? d[0].value : null,
283
+ # fields: d[4]
284
+ # }) %}
285
+
286
+ field_pattern_list -> field_pattern (_ "," _ field_pattern):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(`, `) %}
287
+
288
+ field_pattern -> variable _ "=" _ pattern {% (d) => d[0] + ` = ` + d[4] %}
289
+
290
+ list_pattern -> "[" _ pattern_list:? _ "]" {% (d) => `[${d[2] ?? ``}]` %}
291
+
292
+ pattern_list -> pattern (_ "," _ pattern):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(`, `) %}
293
+
294
+ tuple_pattern -> "(" _ pattern (_ "," _ pattern):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[3])].join(`, `)})` %}
295
+
296
+ # Type rules
297
+
298
+ type_declaration -> "type" __ constr (__ variable_list):? _ "=" _ type {% (d) => {
299
+ const varList = d[3] ? ` ` + d[3][1] : ``
300
+
301
+ return `type ${d[2]}` + varList + ` = ${d[7]}`
302
+ } %}
303
+
304
+ variable_list -> variable (__ variable):* {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
305
+
306
+ type -> function_type {% d => d[0] %}
307
+
308
+ constrained_type -> constraint_list _ %arrow _ type {% (d) => d[0] + ` -> ` + d[4] %}
309
+
310
+ context ->
311
+ constraint {% (d) => d[0] %}
312
+ | "(" _ constraint_list _ ")" {% (d) => `(${d[2]})` %}
313
+
314
+ constraint_list ->
315
+ constraint (_ "," _ constraint):* {% (d) =>
316
+ [d[0], ...d[1].map(x => x[3])].join(", ")
317
+ %}
318
+
319
+ constraint -> %typeClass (_ application_type):+ {% (d) => [d[0].value, ...d[1].map(x => x[1])].join(" ") %}
320
+
321
+ function_type ->
322
+ (context _ %arrow _):? (application_type (_ | (_ %NL __)) %typeArrow (_ | (_ %NL __))):* application_type {% (d) => {
323
+ const constraints = d[0] ? `${d[0][0]} => ` : ``;
324
+ const inputs = [...d[1].map(x => x[0]), d[2]].join(" -> ")
325
+ return constraints + inputs
326
+ }
327
+ %}
328
+
329
+ application_type ->
330
+ simple_type (_ simple_type):+ {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
331
+ | simple_type {% (d) => d[0] %}
332
+
333
+ simple_type ->
334
+ (type_variable | type_constructor) {% (d) => d[0][0] %}
335
+ | "[" _ type _ "]" {% (d) => `[${d[2]}]` %}
336
+ | "(" _ type (_ "," _ type):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[3])].join(`, `)})` %}
337
+ | "(" _ type _ ")" {% (d) => `(${d[2]})` %}
338
+
339
+ type_variable -> variable {% (d) => d[0] %}
340
+ type_constructor -> constr {% (d) => d[0] %}
341
+
342
+ # Misc rules
343
+
344
+ constr -> %constructor {% (d) => `${d[0].value}` %}
345
+ variable -> %variable {% (d) => `${d[0].value}` %}
346
+
347
+ list_literal ->
348
+ "[" _ "]" {% (d) => `[]` %}
349
+ | "[" _ expression_list _ "]" {% (d) => `[${d[2]}]` %}
350
+
351
+ range_expression ->
352
+ expression _ ".." {% (d) => d[0] + ".." %} # [start ..]
353
+ | expression _ ".." _ expression {% (d) => d[0] + ".." + d[4] %} # [start .. end]
354
+ | expression _ "," _ expression _ ".." {% (d) => d[0] + ", " + d[4] + ".." %} # [start, second ..]
355
+ | expression _ "," _ expression _ ".." _ expression {% (d) => d[0] + ", " + d[4] + ".." + d[6] %} # [start, second .. end]
356
+
357
+ expression_list -> expression (_ "," _ expression):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(`, `) %}
358
+
359
+ comparison_operator ->
360
+ ("=="
361
+ | "/="
362
+ | "<"
363
+ | ">"
364
+ | "<="
365
+ | ">=") {% (d) => d[0][0].value %}
366
+
367
+ primitive ->
368
+ (%number
369
+ | %char
370
+ | %string
371
+ | %bool) {% (d) => `${d[0][0].value}` %}
372
+
373
+ _ -> %WS:*
374
+
375
+ __ -> %WS:+