@willbooster/tree-sitter-haskell 0.0.0-stage → 1.0.1
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.
- package/LICENSE +21 -0
- package/README.md +150 -2
- package/grammar/class.js +130 -0
- package/grammar/conflicts.js +116 -0
- package/grammar/context.js +69 -0
- package/grammar/data.js +241 -0
- package/grammar/decl.js +184 -0
- package/grammar/exp.js +413 -0
- package/grammar/externals.js +177 -0
- package/grammar/general.js +54 -0
- package/grammar/id.js +132 -0
- package/grammar/inline.js +99 -0
- package/grammar/lexeme.js +59 -0
- package/grammar/literal.js +102 -0
- package/grammar/module.js +150 -0
- package/grammar/operator.js +75 -0
- package/grammar/pat.js +149 -0
- package/grammar/patsyn.js +42 -0
- package/grammar/precedences.js +109 -0
- package/grammar/th.js +82 -0
- package/grammar/type.js +451 -0
- package/grammar/util.js +162 -0
- package/grammar.js +101 -0
- package/package.json +74 -4
- package/queries/highlights.scm +448 -0
- package/queries/injections.scm +76 -0
- package/queries/locals.scm +4 -0
- package/src/node-types.json +6412 -0
- package/tree-sitter-haskell.wasm +0 -0
- package/tree-sitter.json +40 -0
package/grammar/type.js
ADDED
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
const {
|
|
2
|
+
parens,
|
|
3
|
+
braces,
|
|
4
|
+
brackets,
|
|
5
|
+
prefix_at,
|
|
6
|
+
sep1,
|
|
7
|
+
sep2,
|
|
8
|
+
unboxed_tuple_full,
|
|
9
|
+
unboxed_sum_full,
|
|
10
|
+
forall,
|
|
11
|
+
layout,
|
|
12
|
+
layout_single,
|
|
13
|
+
optional_where,
|
|
14
|
+
} = require('./util.js')
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
|
|
18
|
+
// ------------------------------------------------------------------------
|
|
19
|
+
// type parameters
|
|
20
|
+
// ------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
_inferred_tyvar: $ => braces($, $._ktype_param),
|
|
23
|
+
|
|
24
|
+
_type_param_parens: $ => parens($, $._ktype_param),
|
|
25
|
+
|
|
26
|
+
_type_param_wildcard: _ => '_',
|
|
27
|
+
|
|
28
|
+
_type_param_annotated: $ => prec('annotated', seq($.type_param, $._kind_annotation)),
|
|
29
|
+
|
|
30
|
+
_type_param_invisible: $ => prefix_at($, field('bind', $.type_param)),
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* This is a supertype.
|
|
34
|
+
*/
|
|
35
|
+
type_param: $ => choice(
|
|
36
|
+
alias($._type_param_wildcard, $.wildcard),
|
|
37
|
+
alias($._type_param_invisible, $.invisible),
|
|
38
|
+
alias($._type_param_parens, $.parens),
|
|
39
|
+
field('bind', $.variable),
|
|
40
|
+
),
|
|
41
|
+
|
|
42
|
+
_ktype_param: $ => choice(
|
|
43
|
+
$.type_param,
|
|
44
|
+
alias($._type_param_annotated, $.annotated),
|
|
45
|
+
),
|
|
46
|
+
|
|
47
|
+
type_params: $ => repeat1(prec('patterns', $.type_param)),
|
|
48
|
+
|
|
49
|
+
quantified_variables: $ => repeat1(choice($.type_param, alias($._inferred_tyvar, $.inferred))),
|
|
50
|
+
|
|
51
|
+
// ------------------------------------------------------------------------
|
|
52
|
+
// tuples and parens
|
|
53
|
+
// ------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
_type_parens: $ => parens($, field('type', $._ktype)),
|
|
56
|
+
|
|
57
|
+
_type_tuple_elems: $ => sep2(',', field('element', $._ktype)),
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Tuple types must either be saturated or empty, sections aren't legal.
|
|
61
|
+
* We could be lenient here, but it seems useful to have a different node name for the prefix variant.
|
|
62
|
+
*/
|
|
63
|
+
_type_tuple: $ => parens($, $._type_tuple_elems),
|
|
64
|
+
|
|
65
|
+
_type_unboxed_tuple: $ => unboxed_tuple_full($, $._ktype),
|
|
66
|
+
|
|
67
|
+
_type_unboxed_sum: $ => unboxed_sum_full($, $._ktype),
|
|
68
|
+
|
|
69
|
+
_type_list: $ => brackets($, sep1(',', field('element', $._ktype))),
|
|
70
|
+
|
|
71
|
+
// ------------------------------------------------------------------------
|
|
72
|
+
// names etc
|
|
73
|
+
// ------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
_type_promoted: $ => seq(
|
|
76
|
+
'\'',
|
|
77
|
+
choice(
|
|
78
|
+
alias($._plist, $.empty_list),
|
|
79
|
+
alias($._type_tuple, $.tuple),
|
|
80
|
+
alias($._type_list, $.list),
|
|
81
|
+
$.prefix_tuple,
|
|
82
|
+
$.unit,
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
|
|
86
|
+
_type_name: $ => choice(
|
|
87
|
+
$.variable,
|
|
88
|
+
$._promoted_tycons,
|
|
89
|
+
prec('type-name', $._tycons),
|
|
90
|
+
),
|
|
91
|
+
|
|
92
|
+
_type_star: _ => choice('*', '★'),
|
|
93
|
+
|
|
94
|
+
_type_wildcard: _ => '_',
|
|
95
|
+
|
|
96
|
+
// ------------------------------------------------------------------------
|
|
97
|
+
// application
|
|
98
|
+
// ------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
_at_type: $ => prefix_at($, field('type', $.type)),
|
|
101
|
+
|
|
102
|
+
_type_apply_arg: $ => choice($.type, alias($._at_type, $.kind_application)),
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Type application, as in `Either e (Int, Text)` or `TypeRep @Int`.
|
|
106
|
+
*/
|
|
107
|
+
_type_apply: $ => prec.left('apply', seq(
|
|
108
|
+
field('constructor', $.type),
|
|
109
|
+
field('argument', $._type_apply_arg),
|
|
110
|
+
)),
|
|
111
|
+
|
|
112
|
+
// ------------------------------------------------------------------------
|
|
113
|
+
// infix
|
|
114
|
+
// ------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
_type_infix: $ => prec.right('infix', seq(
|
|
117
|
+
field('left_operand', $.type),
|
|
118
|
+
field('operator', $._tyops),
|
|
119
|
+
field('right_operand', $.type),
|
|
120
|
+
)),
|
|
121
|
+
|
|
122
|
+
// ------------------------------------------------------------------------
|
|
123
|
+
// unquantified type
|
|
124
|
+
// ------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* This is a supertype.
|
|
128
|
+
*/
|
|
129
|
+
type: $ => choice(
|
|
130
|
+
$._type_name,
|
|
131
|
+
alias($._type_star, $.star),
|
|
132
|
+
alias($._type_wildcard, $.wildcard),
|
|
133
|
+
alias($._type_parens, $.parens),
|
|
134
|
+
alias($._type_promoted, $.promoted),
|
|
135
|
+
alias($._type_list, $.list),
|
|
136
|
+
alias($._plist, $.prefix_list),
|
|
137
|
+
alias($._type_unboxed_tuple, $.unboxed_tuple),
|
|
138
|
+
alias($._type_unboxed_sum, $.unboxed_sum),
|
|
139
|
+
alias($._type_tuple, $.tuple),
|
|
140
|
+
alias($._type_infix, $.infix),
|
|
141
|
+
alias($._type_apply, $.apply),
|
|
142
|
+
$._universal,
|
|
143
|
+
),
|
|
144
|
+
|
|
145
|
+
// ------------------------------------------------------------------------
|
|
146
|
+
// forall
|
|
147
|
+
// ------------------------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
_forall_keyword: _ => choice('forall', '∀'),
|
|
150
|
+
|
|
151
|
+
_forall_body: $ => seq(
|
|
152
|
+
field('quantifier', $._forall_keyword),
|
|
153
|
+
optional(field('variables', $.quantified_variables)),
|
|
154
|
+
),
|
|
155
|
+
|
|
156
|
+
forall: $ => prec('qtype-single', seq(
|
|
157
|
+
$._forall_body,
|
|
158
|
+
'.',
|
|
159
|
+
)),
|
|
160
|
+
|
|
161
|
+
forall_required: $ => prec('qtype-single', seq(
|
|
162
|
+
$._forall_body,
|
|
163
|
+
$._arrow,
|
|
164
|
+
)),
|
|
165
|
+
|
|
166
|
+
_forall: $ => choice(
|
|
167
|
+
$.forall,
|
|
168
|
+
$.forall_required,
|
|
169
|
+
),
|
|
170
|
+
|
|
171
|
+
_qtype_forall: $ => prec.right('qtype-curried', seq(
|
|
172
|
+
$._forall_body,
|
|
173
|
+
'.',
|
|
174
|
+
field('type', $.quantified_type),
|
|
175
|
+
)),
|
|
176
|
+
|
|
177
|
+
_qtype_forall_required: $ => prec.right('qtype-curried', seq(
|
|
178
|
+
$._forall_body,
|
|
179
|
+
$._arrow,
|
|
180
|
+
field('type', $.quantified_type),
|
|
181
|
+
)),
|
|
182
|
+
|
|
183
|
+
// ------------------------------------------------------------------------
|
|
184
|
+
// function
|
|
185
|
+
// ------------------------------------------------------------------------
|
|
186
|
+
|
|
187
|
+
_fun_arrow: $ => seq(
|
|
188
|
+
optional($._phantom_arrow),
|
|
189
|
+
field('arrow', $._arrow),
|
|
190
|
+
),
|
|
191
|
+
|
|
192
|
+
modifier: $ => prec('prefix', seq($._prefix_percent, $.type)),
|
|
193
|
+
|
|
194
|
+
_linear_fun_arrow: $ => choice(
|
|
195
|
+
seq(
|
|
196
|
+
field('multiplicity', $.modifier),
|
|
197
|
+
$._fun_arrow,
|
|
198
|
+
),
|
|
199
|
+
seq(
|
|
200
|
+
optional($._phantom_arrow),
|
|
201
|
+
field('arrow', $._linear_arrow),
|
|
202
|
+
),
|
|
203
|
+
),
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* These also allow tight infix because unpack pragmas can precede them without space.
|
|
207
|
+
* Technically pragmas aren't considered for tight infix, but it's simpler to do it this way than to track that in the
|
|
208
|
+
* scanner.
|
|
209
|
+
*/
|
|
210
|
+
strict_field: $ => prec('prefix', seq($._any_prefix_bang, field('type', $.type))),
|
|
211
|
+
lazy_field: $ => prec('prefix', seq($._any_prefix_tilde, field('type', $.type))),
|
|
212
|
+
|
|
213
|
+
_parameter_type: $ => field('parameter', choice($.strict_field, $.lazy_field, $.quantified_type)),
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* We allow strict and lazy field types in function types so that GADTs don't need a separate rule tree.
|
|
217
|
+
*/
|
|
218
|
+
_qtype_function: $ => prec.right(seq(
|
|
219
|
+
$._parameter_type,
|
|
220
|
+
$._fun_arrow,
|
|
221
|
+
field('result', $.quantified_type),
|
|
222
|
+
)),
|
|
223
|
+
|
|
224
|
+
_qtype_linear_function: $ => prec.right(seq(
|
|
225
|
+
$._parameter_type,
|
|
226
|
+
$._linear_fun_arrow,
|
|
227
|
+
field('result', $.quantified_type),
|
|
228
|
+
)),
|
|
229
|
+
|
|
230
|
+
// ------------------------------------------------------------------------
|
|
231
|
+
// context
|
|
232
|
+
// ------------------------------------------------------------------------
|
|
233
|
+
|
|
234
|
+
_qtype_context: $ => prec.right('qtype-curried', seq(
|
|
235
|
+
$._context_inline,
|
|
236
|
+
field('type', $.quantified_type),
|
|
237
|
+
)),
|
|
238
|
+
|
|
239
|
+
// ------------------------------------------------------------------------
|
|
240
|
+
// top level
|
|
241
|
+
// ------------------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* This is a supertype.
|
|
245
|
+
*/
|
|
246
|
+
quantified_type: $ => choice(
|
|
247
|
+
alias($._qtype_function, $.function),
|
|
248
|
+
alias($._qtype_linear_function, $.linear_function),
|
|
249
|
+
alias($._qtype_forall, $.forall),
|
|
250
|
+
alias($._qtype_forall_required, $.forall_required),
|
|
251
|
+
alias($._qtype_context, $.context),
|
|
252
|
+
$.implicit_parameter,
|
|
253
|
+
prec.right($.type),
|
|
254
|
+
),
|
|
255
|
+
|
|
256
|
+
_type_annotation: $ => seq(
|
|
257
|
+
$._colon2,
|
|
258
|
+
field('type', $.quantified_type),
|
|
259
|
+
),
|
|
260
|
+
|
|
261
|
+
_kind_annotation: $ => seq(
|
|
262
|
+
$._colon2,
|
|
263
|
+
field('kind', $.quantified_type),
|
|
264
|
+
),
|
|
265
|
+
|
|
266
|
+
_type_signature: $ => prec.right('annotated', seq(
|
|
267
|
+
field('type', $.quantified_type),
|
|
268
|
+
$._kind_annotation,
|
|
269
|
+
)),
|
|
270
|
+
|
|
271
|
+
_ktype: $ => choice(
|
|
272
|
+
alias($._type_signature, $.signature),
|
|
273
|
+
$.quantified_type,
|
|
274
|
+
),
|
|
275
|
+
|
|
276
|
+
// ------------------------------------------------------------------------
|
|
277
|
+
// type head
|
|
278
|
+
// ------------------------------------------------------------------------
|
|
279
|
+
|
|
280
|
+
_type_head_name: $ => field('name', choice(
|
|
281
|
+
$._tycon,
|
|
282
|
+
$.unit,
|
|
283
|
+
alias($._plist, $.prefix_list),
|
|
284
|
+
)),
|
|
285
|
+
|
|
286
|
+
_type_head_parens: $ => parens(
|
|
287
|
+
$,
|
|
288
|
+
choice(
|
|
289
|
+
$._type_head,
|
|
290
|
+
$._type_head_params,
|
|
291
|
+
),
|
|
292
|
+
),
|
|
293
|
+
|
|
294
|
+
_type_head_params: $ => choice(
|
|
295
|
+
$._type_head_name,
|
|
296
|
+
alias($._type_head_parens, $.parens),
|
|
297
|
+
),
|
|
298
|
+
|
|
299
|
+
_type_head_infix: $ => prec('infix', seq(
|
|
300
|
+
field('left_operand', $.type_param),
|
|
301
|
+
field('operator', $._tyconops),
|
|
302
|
+
field('right_operand', $.type_param),
|
|
303
|
+
)),
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* A type head introduces the name and parameters in the declaration of a data type/family, type synonym/family, or
|
|
307
|
+
* class.
|
|
308
|
+
*
|
|
309
|
+
* It can be in prefix or infix form:
|
|
310
|
+
*
|
|
311
|
+
* > A a b
|
|
312
|
+
* > a +++ b
|
|
313
|
+
*
|
|
314
|
+
* Parameters can be visible or invisible, the latter marked by a prefix `@`.
|
|
315
|
+
* They can be plain or parenthesized variable names, the latter with an optional kind signature.
|
|
316
|
+
* They can be wildcards.
|
|
317
|
+
*
|
|
318
|
+
* Examples: `a`, `@a`, `(a :: Type)`, `@(_ :: Type -> Type)`
|
|
319
|
+
*
|
|
320
|
+
* The rules are slightly relaxed compared to GHC.
|
|
321
|
+
*/
|
|
322
|
+
_type_head: $ => choice(
|
|
323
|
+
seq($._type_head_params, optional(field('patterns', $.type_params))),
|
|
324
|
+
alias($._type_head_infix, $.infix),
|
|
325
|
+
),
|
|
326
|
+
|
|
327
|
+
// ------------------------------------------------------------------------
|
|
328
|
+
// type instance head
|
|
329
|
+
// ------------------------------------------------------------------------
|
|
330
|
+
|
|
331
|
+
_type_instance_head_parens: $ => parens(
|
|
332
|
+
$,
|
|
333
|
+
choice(
|
|
334
|
+
$._type_instance_head,
|
|
335
|
+
$._type_instance_head_params,
|
|
336
|
+
),
|
|
337
|
+
optional($._kind_annotation),
|
|
338
|
+
),
|
|
339
|
+
|
|
340
|
+
_type_instance_head_params: $ => choice(
|
|
341
|
+
field('name', $._tycons),
|
|
342
|
+
alias($._type_instance_head_parens, $.parens),
|
|
343
|
+
),
|
|
344
|
+
|
|
345
|
+
type_patterns: $ => repeat1(prec('patterns', $._type_apply_arg)),
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* The equivalent of a type head, for type instances, which can contain full type patterns rather than just variable
|
|
349
|
+
* binders.
|
|
350
|
+
*/
|
|
351
|
+
_type_instance_head: $ => choice(
|
|
352
|
+
seq($._type_instance_head_params, optional(field('patterns', $.type_patterns))),
|
|
353
|
+
seq($._cond_infix, alias($._type_infix, $.infix)),
|
|
354
|
+
),
|
|
355
|
+
|
|
356
|
+
// ------------------------------------------------------------------------
|
|
357
|
+
// type decl
|
|
358
|
+
// ------------------------------------------------------------------------
|
|
359
|
+
|
|
360
|
+
type_synomym: $ => seq(
|
|
361
|
+
'type',
|
|
362
|
+
$._type_head,
|
|
363
|
+
'=',
|
|
364
|
+
field('type', $._ktype),
|
|
365
|
+
),
|
|
366
|
+
|
|
367
|
+
kind_signature: $ => seq(
|
|
368
|
+
'type',
|
|
369
|
+
$._type_head,
|
|
370
|
+
$._kind_annotation,
|
|
371
|
+
),
|
|
372
|
+
|
|
373
|
+
// ------------------------------------------------------------------------
|
|
374
|
+
// type instance
|
|
375
|
+
// ------------------------------------------------------------------------
|
|
376
|
+
|
|
377
|
+
_type_instance_common: $ => seq(
|
|
378
|
+
$._type_instance_head,
|
|
379
|
+
'=',
|
|
380
|
+
$.quantified_type,
|
|
381
|
+
),
|
|
382
|
+
|
|
383
|
+
_type_instance: $ => seq(
|
|
384
|
+
forall($),
|
|
385
|
+
$._type_instance_common,
|
|
386
|
+
),
|
|
387
|
+
|
|
388
|
+
type_instance: $ => seq(
|
|
389
|
+
'type',
|
|
390
|
+
'instance',
|
|
391
|
+
$._type_instance,
|
|
392
|
+
),
|
|
393
|
+
|
|
394
|
+
// ------------------------------------------------------------------------
|
|
395
|
+
// type family
|
|
396
|
+
// ------------------------------------------------------------------------
|
|
397
|
+
|
|
398
|
+
type_family_result: $ => seq('=', field('result', $.quantified_type)),
|
|
399
|
+
|
|
400
|
+
type_family_injectivity: $ => seq(
|
|
401
|
+
$._bar,
|
|
402
|
+
field('result', $.variable),
|
|
403
|
+
$._arrow,
|
|
404
|
+
field('determined', repeat1($.variable)),
|
|
405
|
+
),
|
|
406
|
+
|
|
407
|
+
_tyfam_inj: $ => seq(
|
|
408
|
+
$.type_family_result,
|
|
409
|
+
optional($.type_family_injectivity),
|
|
410
|
+
),
|
|
411
|
+
|
|
412
|
+
_tyfam: $ => seq(
|
|
413
|
+
$._type_head,
|
|
414
|
+
optional(choice($._kind_annotation, $._tyfam_inj)),
|
|
415
|
+
),
|
|
416
|
+
|
|
417
|
+
_tyfam_equations: $ => layout($, field('equation', alias($._type_instance, $.equation))),
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* This syntax is valid in `.hs-boot` files.
|
|
421
|
+
*/
|
|
422
|
+
abstract_family: $ => layout_single($, '..'),
|
|
423
|
+
|
|
424
|
+
type_family: $ => seq(
|
|
425
|
+
'type',
|
|
426
|
+
'family',
|
|
427
|
+
$._tyfam,
|
|
428
|
+
optional_where($, field('closed_family', choice(
|
|
429
|
+
alias($._tyfam_equations, $.equations),
|
|
430
|
+
$.abstract_family,
|
|
431
|
+
))),
|
|
432
|
+
),
|
|
433
|
+
|
|
434
|
+
// ------------------------------------------------------------------------
|
|
435
|
+
// role
|
|
436
|
+
// ------------------------------------------------------------------------
|
|
437
|
+
|
|
438
|
+
type_role: _ => choice(
|
|
439
|
+
'representational',
|
|
440
|
+
'nominal',
|
|
441
|
+
'phantom',
|
|
442
|
+
'_',
|
|
443
|
+
),
|
|
444
|
+
|
|
445
|
+
role_annotation: $ => seq(
|
|
446
|
+
'type',
|
|
447
|
+
'role',
|
|
448
|
+
field('type', $._tycons),
|
|
449
|
+
repeat1(field('role', $.type_role)),
|
|
450
|
+
)
|
|
451
|
+
}
|
package/grammar/util.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// ------------------------------------------------------------------------
|
|
2
|
+
// structure
|
|
3
|
+
// ------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
const sep1 = (s, rule) => seq(rule, repeat(seq(s, rule)))
|
|
6
|
+
|
|
7
|
+
const sep2 = (s, rule) => seq(rule, repeat1(seq(s, rule)))
|
|
8
|
+
|
|
9
|
+
const sep = (s, rule) => optional(sep1(s, rule))
|
|
10
|
+
|
|
11
|
+
// ------------------------------------------------------------------------
|
|
12
|
+
// syntax
|
|
13
|
+
// ------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
const parens = ($, ...rule) => seq($._paren_open, ...rule, $._paren_close)
|
|
16
|
+
|
|
17
|
+
const braces = ($, ...rule) => seq('{', $._cmd_brace_open, ...rule, '}', $._cmd_brace_close)
|
|
18
|
+
|
|
19
|
+
const brackets = ($, ...rule) => seq($._bracket_open, ...rule, $._bracket_close)
|
|
20
|
+
|
|
21
|
+
const ticked = (...rule) => seq('`', ...rule, '`')
|
|
22
|
+
|
|
23
|
+
const promoted = (...rule) => seq('\'', ...rule)
|
|
24
|
+
|
|
25
|
+
const prefix_at = ($, ...rule) => prec('prefix', seq($._prefix_at, ...rule))
|
|
26
|
+
|
|
27
|
+
const semi = $ => choice(repeat1(';'), $._cond_layout_semicolon)
|
|
28
|
+
|
|
29
|
+
const semi_opt = $ => optional(semi($))
|
|
30
|
+
|
|
31
|
+
const semis = ($, rule) => sep1(semi($), rule)
|
|
32
|
+
|
|
33
|
+
// ------------------------------------------------------------------------
|
|
34
|
+
// layout
|
|
35
|
+
// ------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* More general variant of `layout_sort`.
|
|
39
|
+
*/
|
|
40
|
+
const layout_sort_single = ($, start, rule) => seq(
|
|
41
|
+
choice(start, alias($._cmd_layout_start_explicit, '{')),
|
|
42
|
+
rule,
|
|
43
|
+
$._layout_end,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Wrap a repeated rule in a layout.
|
|
48
|
+
* This is used for `where`, `let`, `of`, `if` and `do`, and the toplevel module.
|
|
49
|
+
* The `start` rule must be one of the externals starting with `_cmd_layout_<type>`, which instruct the scanner to push
|
|
50
|
+
* a layout context with the current column as its indentation.
|
|
51
|
+
* When a `_cond_layout_end` or `_cond_layout_semicolon` is encountered by the scanner, the recorded indent is compared
|
|
52
|
+
* to the current one to make a decision.
|
|
53
|
+
*/
|
|
54
|
+
const layout_sort = ($, start, rule) => seq(
|
|
55
|
+
choice(start, alias($._cmd_layout_start_explicit, '{')),
|
|
56
|
+
optional(seq(
|
|
57
|
+
semi_opt($),
|
|
58
|
+
semis($, rule),
|
|
59
|
+
semi_opt($),
|
|
60
|
+
)),
|
|
61
|
+
$._layout_end,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Same as `layout`, but using `layout_sort_single`.
|
|
66
|
+
* This is necessary for braces without repeating layout elements.
|
|
67
|
+
* Usually it is enough to just use `braces` for this (e.g. records), but if the rule is in a choice with a full
|
|
68
|
+
* layout, we need to allow the layout start token since the scanner emits that unconditionally based on preceding
|
|
69
|
+
* tokens.
|
|
70
|
+
*/
|
|
71
|
+
const layout_single = ($, rule) => layout_sort_single($, $._cmd_layout_start, rule)
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Alias for `layout_sort` using the common layout type for the start token, which corresponds to declarations and GADT
|
|
75
|
+
* constructors.
|
|
76
|
+
*/
|
|
77
|
+
const layout = ($, rule) => layout_sort($, $._cmd_layout_start, rule)
|
|
78
|
+
|
|
79
|
+
// ------------------------------------------------------------------------
|
|
80
|
+
// unboxed
|
|
81
|
+
// ------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
const unboxed = ($, ...rules) => seq($._unboxed_open, ...rules, $._unboxed_close)
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* At least one element is filled, for expressions.
|
|
87
|
+
*/
|
|
88
|
+
const unboxed_tuple_nonempty = ($, rule) => unboxed(
|
|
89
|
+
$,
|
|
90
|
+
repeat(','),
|
|
91
|
+
field('element', rule),
|
|
92
|
+
repeat(seq(',', optional(field('element', rule))))
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* All elements are filled in, for types and patterns.
|
|
97
|
+
*/
|
|
98
|
+
const unboxed_tuple_full = ($, rule) => unboxed($, sep1(',', field('element', rule)))
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Exactly one element is filled in, used by expressions, patterns and the special data constructors.
|
|
102
|
+
*/
|
|
103
|
+
const unboxed_sum_single = ($, rule) => unboxed(
|
|
104
|
+
$,
|
|
105
|
+
choice(
|
|
106
|
+
seq(repeat1($._unboxed_bar), field('element', rule)),
|
|
107
|
+
seq(field('element', rule), $._unboxed_bar)
|
|
108
|
+
),
|
|
109
|
+
repeat($._unboxed_bar),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* All elements are filled in, for types.
|
|
114
|
+
*/
|
|
115
|
+
const unboxed_sum_full = ($, rule) => unboxed($, sep2($._unboxed_bar, field('element', rule)))
|
|
116
|
+
|
|
117
|
+
// ------------------------------------------------------------------------
|
|
118
|
+
// where
|
|
119
|
+
// ------------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
const optional_where = ($, rule) => optional(seq($._where, optional(rule)))
|
|
122
|
+
|
|
123
|
+
// ------------------------------------------------------------------------
|
|
124
|
+
// misc
|
|
125
|
+
// ------------------------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
const qualified = ($, id) => prec('qualified-id', seq(
|
|
128
|
+
field('module', alias($._qualifying_module, $.module)),
|
|
129
|
+
field('id', id),
|
|
130
|
+
))
|
|
131
|
+
|
|
132
|
+
const context = $ => optional(field('context', $.context))
|
|
133
|
+
|
|
134
|
+
const forall = $ => optional(field('forall', $._forall))
|
|
135
|
+
|
|
136
|
+
module.exports = {
|
|
137
|
+
sep1,
|
|
138
|
+
sep2,
|
|
139
|
+
sep,
|
|
140
|
+
parens,
|
|
141
|
+
braces,
|
|
142
|
+
brackets,
|
|
143
|
+
ticked,
|
|
144
|
+
promoted,
|
|
145
|
+
prefix_at,
|
|
146
|
+
semi,
|
|
147
|
+
semi_opt,
|
|
148
|
+
semis,
|
|
149
|
+
layout_sort_single,
|
|
150
|
+
layout_sort,
|
|
151
|
+
layout_single,
|
|
152
|
+
layout,
|
|
153
|
+
unboxed,
|
|
154
|
+
unboxed_tuple_nonempty,
|
|
155
|
+
unboxed_tuple_full,
|
|
156
|
+
unboxed_sum_single,
|
|
157
|
+
unboxed_sum_full,
|
|
158
|
+
optional_where,
|
|
159
|
+
qualified,
|
|
160
|
+
context,
|
|
161
|
+
forall,
|
|
162
|
+
}
|
package/grammar.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const
|
|
2
|
+
class_ = require('./grammar/class.js'),
|
|
3
|
+
conflicts = require('./grammar/conflicts.js'),
|
|
4
|
+
context = require('./grammar/context.js'),
|
|
5
|
+
data = require('./grammar/data.js'),
|
|
6
|
+
decl = require('./grammar/decl.js'),
|
|
7
|
+
exp = require('./grammar/exp.js'),
|
|
8
|
+
externals = require('./grammar/externals.js'),
|
|
9
|
+
general = require('./grammar/general.js'),
|
|
10
|
+
id = require('./grammar/id.js'),
|
|
11
|
+
inline = require('./grammar/inline.js'),
|
|
12
|
+
lexeme = require('./grammar/lexeme.js'),
|
|
13
|
+
literal = require('./grammar/literal.js'),
|
|
14
|
+
module_ = require('./grammar/module.js'),
|
|
15
|
+
operator = require('./grammar/operator.js'),
|
|
16
|
+
pat = require('./grammar/pat.js'),
|
|
17
|
+
patsyn = require('./grammar/patsyn.js'),
|
|
18
|
+
precedences = require('./grammar/precedences.js'),
|
|
19
|
+
th = require('./grammar/th.js'),
|
|
20
|
+
type = require('./grammar/type.js')
|
|
21
|
+
|
|
22
|
+
module.exports = grammar({
|
|
23
|
+
name: 'haskell',
|
|
24
|
+
|
|
25
|
+
rules: {
|
|
26
|
+
haskell: $ => seq(
|
|
27
|
+
optional($.header),
|
|
28
|
+
optional($._body),
|
|
29
|
+
),
|
|
30
|
+
|
|
31
|
+
...general,
|
|
32
|
+
...type,
|
|
33
|
+
...context,
|
|
34
|
+
...exp,
|
|
35
|
+
...pat,
|
|
36
|
+
...module_,
|
|
37
|
+
...data,
|
|
38
|
+
...class_,
|
|
39
|
+
...decl,
|
|
40
|
+
...patsyn,
|
|
41
|
+
...th,
|
|
42
|
+
...literal,
|
|
43
|
+
...id,
|
|
44
|
+
...operator,
|
|
45
|
+
...lexeme,
|
|
46
|
+
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
...externals,
|
|
50
|
+
...precedences,
|
|
51
|
+
...inline,
|
|
52
|
+
...conflicts,
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* These rules may occur anywhere in the grammar and don't have to be specified in productions.
|
|
56
|
+
*/
|
|
57
|
+
extras: $ => [
|
|
58
|
+
/\p{Zs}/,
|
|
59
|
+
/\n/,
|
|
60
|
+
/\r/,
|
|
61
|
+
$.cpp,
|
|
62
|
+
$.comment,
|
|
63
|
+
$.haddock,
|
|
64
|
+
$.pragma,
|
|
65
|
+
],
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Rules with leading underscore are generally omitted from the AST, and can therefore not be used in queries.
|
|
69
|
+
* The rules listed in this attribute are omitted from the AST, but their names can be used in queries in place of
|
|
70
|
+
* their children; as well as in combination with them, using the syntax `expression/variable`.
|
|
71
|
+
* This is most useful for choice rules that represent syntactic categories, like expressions, patterns, and types in
|
|
72
|
+
* Haskell.
|
|
73
|
+
*
|
|
74
|
+
* See the readme for a detailed explanation.
|
|
75
|
+
*/
|
|
76
|
+
supertypes: $ => [
|
|
77
|
+
$.expression,
|
|
78
|
+
$.pattern,
|
|
79
|
+
$.type,
|
|
80
|
+
$.quantified_type,
|
|
81
|
+
$.constraint,
|
|
82
|
+
$.constraints,
|
|
83
|
+
$.type_param,
|
|
84
|
+
$.declaration,
|
|
85
|
+
$.decl,
|
|
86
|
+
$.class_decl,
|
|
87
|
+
$.instance_decl,
|
|
88
|
+
$.statement,
|
|
89
|
+
$.qualifier,
|
|
90
|
+
$.guard,
|
|
91
|
+
],
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* This rule is used to detect that a reserved keyword is a prefix of an identifier.
|
|
95
|
+
*
|
|
96
|
+
* For example, if the identifier `ifM` occurs in a position where the keyword `if` is valid (so most expressions),
|
|
97
|
+
* the fact that `ifM` matches `variable` prevents tree-sitter from lexing `if` followed by `M` as a `name`.
|
|
98
|
+
*/
|
|
99
|
+
word: $ => $.variable,
|
|
100
|
+
|
|
101
|
+
})
|