@willbooster/tree-sitter-haskell 9.0.0 → 11.0.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.
- package/README.md +11 -8
- package/grammar/conflicts.js +22 -19
- package/grammar/context.js +8 -9
- package/grammar/exp.js +29 -27
- package/grammar/externals.js +0 -7
- package/grammar/inline.js +7 -0
- package/grammar/pat.js +20 -13
- package/grammar/precedences.js +0 -1
- package/grammar/type.js +13 -10
- package/grammar.js +5 -14
- package/hsc/src/node-types.json +445 -166
- package/package.json +8 -8
- package/queries/highlights.scm +36 -65
- package/queries/locals.scm +3 -3
- package/queries/tags.scm +35 -19
- package/src/node-types.json +445 -166
- package/tree-sitter-haskell.wasm +0 -0
- package/tree-sitter-hsc.wasm +0 -0
- package/tree-sitter.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://github.com/WillBooster/tree-sitter-haskell/actions/workflows/test.yml)
|
|
6
6
|
[](https://github.com/WillBooster/tree-sitter-haskell/actions/workflows/test-rust.yml)
|
|
7
7
|
[](https://github.com/semantic-release/semantic-release)
|
|
8
|
-
[](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
|
|
9
9
|
[](https://crates.io/crates/willbooster-tree-sitter-haskell)
|
|
10
10
|
|
|
11
11
|
Haskell grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter), forked from
|
|
@@ -13,10 +13,9 @@ Haskell grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter), f
|
|
|
13
13
|
to its authors and contributors. This is not an official release of that project.
|
|
14
14
|
|
|
15
15
|
This fork is based on upstream's version 0.23.1 grammar and generates the parser with the
|
|
16
|
-
[WillBooster/tree-sitter](https://github.com/WillBooster/tree-sitter) generator. The parser carries that fork's own ABI number
|
|
16
|
+
[WillBooster/tree-sitter](https://github.com/WillBooster/tree-sitter) generator. The parser carries that fork's own ABI number. This package supports the fork's runtime version 10.0.1 or later in the 10.x series; upstream's runtime rejects it.
|
|
17
17
|
[Upstream's README at that version](https://github.com/tree-sitter/tree-sitter-haskell/blob/v0.23.1/README.md) lists
|
|
18
|
-
the supported language extensions
|
|
19
|
-
readme that the comments in `grammar.js` refer to.
|
|
18
|
+
the supported language extensions. The fork's node and query contracts are described below.
|
|
20
19
|
|
|
21
20
|
## Differences from upstream
|
|
22
21
|
|
|
@@ -40,7 +39,7 @@ reports an error: the lexers of the WillBooster/tree-sitter generator let charac
|
|
|
40
39
|
## Usage
|
|
41
40
|
|
|
42
41
|
The npm package ships `tree-sitter-haskell.wasm` for
|
|
43
|
-
[@willbooster/web-tree-sitter](https://www.npmjs.com/package/@willbooster/web-tree-sitter) version
|
|
42
|
+
[@willbooster/web-tree-sitter](https://www.npmjs.com/package/@willbooster/web-tree-sitter) version 10.0.1 or later in the 10.x series, which runs in Node.js, Bun, browsers, and Cloudflare Workers. In Node.js and Bun, load the grammar from its path:
|
|
44
43
|
|
|
45
44
|
```js
|
|
46
45
|
import { fileURLToPath } from 'node:url';
|
|
@@ -88,7 +87,11 @@ Declaration names and variable/operator callees remain indexed through nested pa
|
|
|
88
87
|
|
|
89
88
|
Function and type declaration-head parentheses are anonymous syntax: the enclosing declaration directly exposes its `name`, parameter groups and infix `head` fields. Parentheses inside parameters and types retain their existing nodes. A grouped variable name, including a qualified name, uses one `parenthesized_name` node with a direct name child, independent of grouping depth. A symbolic variable operator keeps its required prefix parentheses in `prefix_id`: `(<+>)` and `(Demo.<+>)` remain `prefix_id`, while redundant grouping such as `((<+>))` adds one `parenthesized_name` wrapper around that node. This also applies to unapplied names; only function position creates a call reference or call highlight. A parenthesized simple binding name uses `parenthesized_name` in the `bind` node's `name` field, retaining one wrapper at any grouping depth. Complex expressions retain ordinary `parens` nodes. These changes affect public syntax trees.
|
|
90
89
|
|
|
91
|
-
|
|
90
|
+
Operator uses retain unresolved source order. Expressions use `operator_chain` with repeated `operand` and `operator` fields: `6 * 7 == 42` has operands `6`, `7`, `42` and operators `*`, `==`. Application stays inside an operand; explicit parentheses and greedy block bodies retain their own grouping. A `prefix_operator` field records each named `prefix_negation` token at its source position, including unary-only chains. Its semantic extent depends on fixities and language extensions, so the tree does not assign it an operand subtree.
|
|
91
|
+
|
|
92
|
+
Type, pattern and constraint operators use `infix_chain` with repeated `operand` and `operator` fields, even for a single operator. Function, type and data declaration heads retain the `infix` node because they define one operator. Instance and standalone deriving implementation tags identify a class only for a single-operator head; multi-operator heads require fixity resolution by the caller.
|
|
93
|
+
|
|
94
|
+
Queries distinguish operands through the `expression_operand`, `type_operand`, `pattern_operand`, `binding_pattern_operand` and `constraint_operand` supertypes. For example, `(expression_operand/variable)` selects an expression variable and `(binding_pattern_operand/variable)` selects an explicit module-binding name. Match chains directly with `(operator_chain)` or `(infix_chain)` and their fields. The concrete operand node names remain shared across contexts. A `binding_field_pattern/field_pattern` with a `field` field and no `pattern` field is a module binding record pun. The `decl` supertype covers bindings in local blocks and declaration quotes; module declarations use `declaration`.
|
|
92
95
|
|
|
93
96
|
In a repository checkout, configure the CLI parser directories to include the grammar, then run `script/tree-sitter tags file.hs` to inspect the tags.
|
|
94
97
|
|
|
@@ -98,8 +101,8 @@ fuzzed with:
|
|
|
98
101
|
|
|
99
102
|
```toml
|
|
100
103
|
[dependencies]
|
|
101
|
-
tree-sitter = { package = "willbooster-tree-sitter", version = "
|
|
102
|
-
tree-sitter-haskell = { package = "willbooster-tree-sitter-haskell", version = "
|
|
104
|
+
tree-sitter = { package = "willbooster-tree-sitter", version = "10.0.1" }
|
|
105
|
+
tree-sitter-haskell = { package = "willbooster-tree-sitter-haskell", version = "11" }
|
|
103
106
|
```
|
|
104
107
|
|
|
105
108
|
```rust
|
package/grammar/conflicts.js
CHANGED
|
@@ -4,25 +4,28 @@ module.exports = {
|
|
|
4
4
|
// GHC DisambECP (notes Ambiguous syntactic categories, PatBuilder and Declaration/signature overlap)
|
|
5
5
|
// disambiguates expressions, patterns and declaration heads after parsing; these alternatives must remain
|
|
6
6
|
// available until following syntax determines their role, including for top-level expression splices.
|
|
7
|
-
[$.
|
|
8
|
-
[$.
|
|
9
|
-
[$.
|
|
10
|
-
[$.
|
|
11
|
-
[$.
|
|
12
|
-
[$.
|
|
13
|
-
[$.
|
|
14
|
-
[$._grouped_name, $.
|
|
15
|
-
[$.
|
|
16
|
-
[$._grouped_name, $.
|
|
17
|
-
[$.
|
|
18
|
-
[$.
|
|
19
|
-
[$.
|
|
20
|
-
[$.
|
|
21
|
-
[$.
|
|
22
|
-
[$.
|
|
23
|
-
[$.
|
|
24
|
-
[$.
|
|
25
|
-
[$.
|
|
7
|
+
[$.expression_operand, $.pattern_operand, $.binding_pattern_operand],
|
|
8
|
+
[$.expression_operand, $.pattern_operand],
|
|
9
|
+
[$.expression_operand, $.binding_pattern_operand],
|
|
10
|
+
[$.pattern_operand, $.binding_pattern_operand],
|
|
11
|
+
[$.prefix_negation, $._pat_negation],
|
|
12
|
+
[$._type_apply, $._type_infix_chain],
|
|
13
|
+
[$._type_infix_chain],
|
|
14
|
+
[$._grouped_name, $.expression_operand, $.pattern_operand, $._binding_name_parens],
|
|
15
|
+
[$.pattern_operand, $._binding_name_parens],
|
|
16
|
+
[$._grouped_name, $.expression_operand, $.pattern_operand, $._function_name, $._binding_name_parens],
|
|
17
|
+
[$._grouped_name, $.expression_operand, $.binding_pattern_operand],
|
|
18
|
+
[$._grouped_name, $.expression_operand, $.pattern_operand],
|
|
19
|
+
[$.pattern_operand, $._function_name, $._binding_name_parens],
|
|
20
|
+
[$._grouped_name, $.expression_operand, $.pattern_operand, $.binding_pattern_operand],
|
|
21
|
+
[$.pattern_operand, $.signature],
|
|
22
|
+
[$.pattern_operand, $._function_name],
|
|
23
|
+
[$.expression_operand, $.pattern_operand, $._function_name],
|
|
24
|
+
[$._grouped_name, $.expression_operand],
|
|
25
|
+
[$._grouped_name, $.expression_operand, $.pattern_operand, $.binding_pattern_operand, $._function_name, $._binding_name_parens],
|
|
26
|
+
[$.binding_pattern_operand, $.signature],
|
|
27
|
+
[$.pattern_operand, $.binding_pattern_operand, $._function_name],
|
|
28
|
+
[$.expression_operand, $.pattern_operand, $.binding_pattern_operand, $._function_name],
|
|
26
29
|
// The hash opening an unboxed tuple can also begin a symbolic operator.
|
|
27
30
|
[$._operator_hash_head, $._unboxed_open],
|
|
28
31
|
],
|
package/grammar/context.js
CHANGED
|
@@ -10,16 +10,11 @@ module.exports = {
|
|
|
10
10
|
// ------------------------------------------------------------------------
|
|
11
11
|
|
|
12
12
|
_class_apply: $ => prec.left('apply', seq(
|
|
13
|
-
field('constructor', $.
|
|
13
|
+
field('constructor', $.constraint_operand),
|
|
14
14
|
field('argument', $._type_apply_arg),
|
|
15
15
|
)),
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
$._cond_infix,
|
|
19
|
-
field('left_operand', $.type),
|
|
20
|
-
field('operator', $._tyops),
|
|
21
|
-
field('right_operand', $.type),
|
|
22
|
-
)),
|
|
17
|
+
_class_infix_chain: $ => seq($._cond_infix, $._type_infix_chain),
|
|
23
18
|
|
|
24
19
|
_ctr_parens: $ => parens($, $.constraints),
|
|
25
20
|
|
|
@@ -34,9 +29,8 @@ module.exports = {
|
|
|
34
29
|
*/
|
|
35
30
|
implicit_parameter: $ => prec.left(seq(field('name', $.implicit_variable), $._type_annotation)),
|
|
36
31
|
|
|
37
|
-
|
|
32
|
+
constraint_operand: $ => choice(
|
|
38
33
|
$._type_name,
|
|
39
|
-
alias($._class_infix, $.infix),
|
|
40
34
|
alias($._class_apply, $.apply),
|
|
41
35
|
alias($._ctr_parens, $.parens),
|
|
42
36
|
alias($._ctr_tuple, $.tuple),
|
|
@@ -44,6 +38,11 @@ module.exports = {
|
|
|
44
38
|
$._universal,
|
|
45
39
|
),
|
|
46
40
|
|
|
41
|
+
constraint: $ => choice(
|
|
42
|
+
alias($._class_infix_chain, $.infix_chain),
|
|
43
|
+
$.constraint_operand,
|
|
44
|
+
),
|
|
45
|
+
|
|
47
46
|
_ctr_forall: $ => prec('fun', seq($._forall_body, '.', field('constraint', $.constraints))),
|
|
48
47
|
|
|
49
48
|
_ctr_context: $ => prec('fun', seq($._context_inline, field('constraint', $.constraints))),
|
package/grammar/exp.js
CHANGED
|
@@ -258,7 +258,7 @@ module.exports = {
|
|
|
258
258
|
),
|
|
259
259
|
|
|
260
260
|
_exp_record: $ => prec('record', seq(
|
|
261
|
-
field('expression', $.
|
|
261
|
+
field('expression', $.expression_operand),
|
|
262
262
|
braces($, sep(',', field('field', $.field_update)))),
|
|
263
263
|
),
|
|
264
264
|
|
|
@@ -271,7 +271,7 @@ module.exports = {
|
|
|
271
271
|
|
|
272
272
|
_exp_projection: $ => seq(
|
|
273
273
|
prec('projection', seq(
|
|
274
|
-
field('expression', $.
|
|
274
|
+
field('expression', $.expression_operand),
|
|
275
275
|
$._tight_dot,
|
|
276
276
|
)),
|
|
277
277
|
field('field', $.field_name),
|
|
@@ -288,9 +288,9 @@ module.exports = {
|
|
|
288
288
|
parenthesized_name: $ => prec.dynamic(1, parens($, $._grouped_name)),
|
|
289
289
|
|
|
290
290
|
_exp_apply: $ => prec.left('apply', seq(
|
|
291
|
-
field('function', $.
|
|
291
|
+
field('function', $.expression_operand),
|
|
292
292
|
field('argument', choice(
|
|
293
|
-
$.
|
|
293
|
+
$.expression_operand,
|
|
294
294
|
alias($._at_type, $.type_application),
|
|
295
295
|
$.explicit_type,
|
|
296
296
|
)),
|
|
@@ -326,43 +326,40 @@ module.exports = {
|
|
|
326
326
|
field('right_operand', $.expression),
|
|
327
327
|
),
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
field('minus', '-'),
|
|
331
|
-
prec('negation', field('expression', $.expression)),
|
|
332
|
-
),
|
|
329
|
+
prefix_negation: _ => '-',
|
|
333
330
|
|
|
334
|
-
|
|
335
|
-
* Infix expressions have severe conflicts with several structures:
|
|
336
|
-
*
|
|
337
|
-
* - Negation is supposed to bind less tight than application and tighter than infix, which requires an unsolvable
|
|
338
|
-
* precedence configuration
|
|
339
|
-
* - Qualified operators cannot be identified with single-token lookahead, which causes ambiguity with function
|
|
340
|
-
* application
|
|
341
|
-
* - Left operator sections require infix expressions in their operand to reduce before the section operator, but
|
|
342
|
-
* single-token lookahead also makes this decision impossible
|
|
343
|
-
*
|
|
344
|
-
* All of these are solved with external symbols.
|
|
345
|
-
* Consult `grammar/externals.js` for more information.
|
|
346
|
-
*/
|
|
347
|
-
_exp_infix: $ => prec.right('infix', seq(
|
|
348
|
-
field('left_operand', $.expression),
|
|
331
|
+
_exp_infix_operator: $ => seq(
|
|
349
332
|
optional($._cond_no_section_op),
|
|
350
333
|
field('operator', choice(
|
|
351
334
|
seq($._cond_minus, $._operator_minus),
|
|
352
335
|
$._exp_op,
|
|
353
336
|
seq($._cond_qualified_op, $._qsym),
|
|
354
337
|
)),
|
|
355
|
-
|
|
338
|
+
),
|
|
339
|
+
|
|
340
|
+
_exp_chain_operand: $ => seq(
|
|
341
|
+
repeat(field('prefix_operator', $.prefix_negation)),
|
|
342
|
+
field('operand', $.expression_operand),
|
|
343
|
+
),
|
|
344
|
+
|
|
345
|
+
_exp_operator_chain: $ => prec.right('infix', choice(
|
|
346
|
+
seq(
|
|
347
|
+
repeat1(field('prefix_operator', $.prefix_negation)),
|
|
348
|
+
field('operand', $.expression_operand),
|
|
349
|
+
repeat(prec.right('infix', seq($._exp_infix_operator, $._exp_chain_operand))),
|
|
350
|
+
),
|
|
351
|
+
seq(
|
|
352
|
+
field('operand', $.expression_operand),
|
|
353
|
+
repeat1(prec.right('infix', seq($._exp_infix_operator, $._exp_chain_operand))),
|
|
354
|
+
),
|
|
356
355
|
)),
|
|
357
356
|
|
|
358
357
|
// ------------------------------------------------------------------------
|
|
359
358
|
// top level
|
|
360
359
|
// ------------------------------------------------------------------------
|
|
361
360
|
|
|
362
|
-
|
|
361
|
+
expression_operand: $ => choice(
|
|
363
362
|
$.parenthesized_name,
|
|
364
|
-
alias($._exp_infix, $.infix),
|
|
365
|
-
alias($._exp_negation, $.negation),
|
|
366
363
|
alias($._exp_apply, $.apply),
|
|
367
364
|
alias($._exp_record, $.record),
|
|
368
365
|
alias($._exp_projection, $.projection),
|
|
@@ -392,6 +389,11 @@ module.exports = {
|
|
|
392
389
|
$._universal,
|
|
393
390
|
),
|
|
394
391
|
|
|
392
|
+
expression: $ => choice(
|
|
393
|
+
alias($._exp_operator_chain, $.operator_chain),
|
|
394
|
+
$.expression_operand,
|
|
395
|
+
),
|
|
396
|
+
|
|
395
397
|
_exp_signature: $ => prec.right('annotated', seq(
|
|
396
398
|
field('expression', $.expression),
|
|
397
399
|
$._type_annotation,
|
package/grammar/externals.js
CHANGED
|
@@ -141,13 +141,6 @@ module.exports = {
|
|
|
141
141
|
// Without this, we would get wrong token ranges for the operator.
|
|
142
142
|
$._cond_no_section_op,
|
|
143
143
|
|
|
144
|
-
// This symbol always succeeds when a minus is ahead.
|
|
145
|
-
// Infix expressions with minus as the operator conflict with function application.
|
|
146
|
-
// `a - b` can be parsed as `a (- b)`, which would normally be solved by a simple precedence entry, but is
|
|
147
|
-
// impossible to express because it contradicts another conflict: Negation in the left operand, `- a + b`, which
|
|
148
|
-
// must be parsed as `(- a) + b`.
|
|
149
|
-
// Simply sequencing this external before the operator solves this conflict, because a minus following an expression
|
|
150
|
-
// can never be negation; it can only occur at the beginning of an expression.
|
|
151
144
|
$._cond_minus,
|
|
152
145
|
|
|
153
146
|
/**
|
package/grammar/inline.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
|
|
3
3
|
inline: $ => [
|
|
4
|
+
$.expression,
|
|
5
|
+
$.pattern,
|
|
6
|
+
$.binding_pattern,
|
|
7
|
+
$.type,
|
|
8
|
+
$.constraint,
|
|
9
|
+
|
|
4
10
|
|
|
5
11
|
// ------------------------------------------------
|
|
6
12
|
// variable
|
|
@@ -43,6 +49,7 @@ module.exports = {
|
|
|
43
49
|
// expression
|
|
44
50
|
// ------------------------------------------------
|
|
45
51
|
|
|
52
|
+
$._exp_chain_operand,
|
|
46
53
|
$._exp_name,
|
|
47
54
|
$._exp_typed_hole,
|
|
48
55
|
$._exp_greedy,
|
package/grammar/pat.js
CHANGED
|
@@ -34,7 +34,7 @@ const patternRules = (name, recordField) => {
|
|
|
34
34
|
// ------------------------------------------------------------------------
|
|
35
35
|
|
|
36
36
|
[name('_pat_record')]: $ => prec('record', seq(
|
|
37
|
-
field('constructor', rule($, '
|
|
37
|
+
field('constructor', rule($, 'pattern_operand')),
|
|
38
38
|
braces($, sep(',', field('field', recordField($)))),
|
|
39
39
|
)),
|
|
40
40
|
|
|
@@ -48,11 +48,11 @@ const patternRules = (name, recordField) => {
|
|
|
48
48
|
*
|
|
49
49
|
* > f (A a) = exp
|
|
50
50
|
*
|
|
51
|
-
* Because of the "single choice disambiguated with named precedences" approach used for `
|
|
51
|
+
* Because of the "single choice disambiguated with named precedences" approach used for `pattern_operand`, the left node in
|
|
52
52
|
* `pat_apply` can be a variable, even though it's not valid Haskell.
|
|
53
53
|
* While the static prec 'pat-name' covers this at generation time, Haskell's ambiguity requires us to use a runtime
|
|
54
54
|
* conflict for `function`/`bind`, where static prec is ineffective.
|
|
55
|
-
* Giving the reduction of `_var` to `
|
|
55
|
+
* Giving the reduction of `_var` to `pattern_operand` a strong negative dynamic prec ensures that the runtime branch for
|
|
56
56
|
* `bind` has lower precedence because of `f`, so `function` always wins.
|
|
57
57
|
*
|
|
58
58
|
* While `bind` usually has a lower score than `function` anyway in this situation because it is slightly more
|
|
@@ -64,26 +64,26 @@ const patternRules = (name, recordField) => {
|
|
|
64
64
|
$._cons,
|
|
65
65
|
),
|
|
66
66
|
|
|
67
|
-
[name('_pat_as')]: $ => prec('prefix', seq(field('bind', $.variable), $._tight_at, field('pattern', rule($, '
|
|
67
|
+
[name('_pat_as')]: $ => prec('prefix', seq(field('bind', $.variable), $._tight_at, field('pattern', rule($, 'pattern_operand')))),
|
|
68
68
|
|
|
69
69
|
[name('_pat_wildcard')]: _ => '_',
|
|
70
70
|
|
|
71
|
-
[name('_pat_strict')]: $ => prec('prefix', seq($._any_prefix_bang, field('pattern', rule($, '
|
|
71
|
+
[name('_pat_strict')]: $ => prec('prefix', seq($._any_prefix_bang, field('pattern', rule($, 'pattern_operand')))),
|
|
72
72
|
|
|
73
|
-
[name('_pat_irrefutable')]: $ => prec('prefix', seq($._any_prefix_tilde, field('pattern', rule($, '
|
|
73
|
+
[name('_pat_irrefutable')]: $ => prec('prefix', seq($._any_prefix_tilde, field('pattern', rule($, 'pattern_operand')))),
|
|
74
74
|
|
|
75
75
|
// ------------------------------------------------------------------------
|
|
76
76
|
// application
|
|
77
77
|
// ------------------------------------------------------------------------
|
|
78
78
|
|
|
79
79
|
[name('_pat_apply_arg')]: $ => choice(
|
|
80
|
-
rule($, '
|
|
80
|
+
rule($, 'pattern_operand'),
|
|
81
81
|
alias($._at_type, $.type_binder),
|
|
82
82
|
$.explicit_type,
|
|
83
83
|
),
|
|
84
84
|
|
|
85
85
|
[name('_pat_apply')]: $ => prec.left('apply', seq(
|
|
86
|
-
field('function', rule($, '
|
|
86
|
+
field('function', rule($, 'pattern_operand')),
|
|
87
87
|
field('argument', rule($, '_pat_apply_arg')),
|
|
88
88
|
)),
|
|
89
89
|
|
|
@@ -93,23 +93,25 @@ const patternRules = (name, recordField) => {
|
|
|
93
93
|
|
|
94
94
|
[name('_pat_negation')]: $ => seq('-', field('number', $._number)),
|
|
95
95
|
|
|
96
|
-
[name('
|
|
97
|
-
field('left_operand', rule($, 'pattern')),
|
|
96
|
+
[name('_pat_infix_operator')]: $ => seq(
|
|
98
97
|
optional($._cond_no_section_op),
|
|
99
98
|
field('operator', choice(
|
|
100
99
|
$.constructor_operator,
|
|
101
100
|
$._conids_ticked,
|
|
102
101
|
seq($._cond_qualified_op, $._qconsym),
|
|
103
102
|
)),
|
|
104
|
-
|
|
103
|
+
),
|
|
104
|
+
|
|
105
|
+
[name('_pat_infix_chain')]: $ => prec.right('infix', seq(
|
|
106
|
+
field('operand', rule($, 'pattern_operand')),
|
|
107
|
+
repeat1(prec.right('infix', seq(rule($, '_pat_infix_operator'), field('operand', rule($, 'pattern_operand'))))),
|
|
105
108
|
)),
|
|
106
109
|
|
|
107
110
|
// ------------------------------------------------------------------------
|
|
108
111
|
// top level
|
|
109
112
|
// ------------------------------------------------------------------------
|
|
110
113
|
|
|
111
|
-
[name('
|
|
112
|
-
alias(rule($, '_pat_infix'), $.infix),
|
|
114
|
+
[name('pattern_operand')]: $ => choice(
|
|
113
115
|
alias(rule($, '_pat_negation'), $.negation),
|
|
114
116
|
alias(rule($, '_pat_apply'), $.apply),
|
|
115
117
|
rule($, '_pat_name'),
|
|
@@ -127,6 +129,11 @@ const patternRules = (name, recordField) => {
|
|
|
127
129
|
$._universal,
|
|
128
130
|
),
|
|
129
131
|
|
|
132
|
+
[name('pattern')]: $ => choice(
|
|
133
|
+
alias(rule($, '_pat_infix_chain'), $.infix_chain),
|
|
134
|
+
rule($, 'pattern_operand'),
|
|
135
|
+
),
|
|
136
|
+
|
|
130
137
|
[name('_pat_signature')]: $ => prec.right('annotated', seq(
|
|
131
138
|
field('pattern', rule($, 'pattern')),
|
|
132
139
|
$._type_annotation,
|
package/grammar/precedences.js
CHANGED
package/grammar/type.js
CHANGED
|
@@ -94,12 +94,12 @@ module.exports = {
|
|
|
94
94
|
// application
|
|
95
95
|
// ------------------------------------------------------------------------
|
|
96
96
|
|
|
97
|
-
_at_type: $ => prefix_at($, field('type', $.
|
|
97
|
+
_at_type: $ => prefix_at($, field('type', $.type_operand)),
|
|
98
98
|
|
|
99
|
-
_type_apply_arg: $ => choice($.
|
|
99
|
+
_type_apply_arg: $ => choice($.type_operand, alias($._at_type, $.kind_application)),
|
|
100
100
|
|
|
101
101
|
_type_apply: $ => prec.left('apply', seq(
|
|
102
|
-
field('constructor', $.
|
|
102
|
+
field('constructor', $.type_operand),
|
|
103
103
|
field('argument', $._type_apply_arg),
|
|
104
104
|
)),
|
|
105
105
|
|
|
@@ -107,17 +107,16 @@ module.exports = {
|
|
|
107
107
|
// infix
|
|
108
108
|
// ------------------------------------------------------------------------
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
field('
|
|
112
|
-
field('operator', $._tyops),
|
|
113
|
-
field('right_operand', $.type),
|
|
110
|
+
_type_infix_chain: $ => prec.right('infix', seq(
|
|
111
|
+
field('operand', $.type_operand),
|
|
112
|
+
repeat1(seq(field('operator', $._tyops), field('operand', $.type_operand))),
|
|
114
113
|
)),
|
|
115
114
|
|
|
116
115
|
// ------------------------------------------------------------------------
|
|
117
116
|
// unquantified type
|
|
118
117
|
// ------------------------------------------------------------------------
|
|
119
118
|
|
|
120
|
-
|
|
119
|
+
type_operand: $ => choice(
|
|
121
120
|
$._type_name,
|
|
122
121
|
alias($._type_star, $.star),
|
|
123
122
|
alias($._type_wildcard, $.wildcard),
|
|
@@ -128,11 +127,15 @@ module.exports = {
|
|
|
128
127
|
alias($._type_unboxed_tuple, $.unboxed_tuple),
|
|
129
128
|
alias($._type_unboxed_sum, $.unboxed_sum),
|
|
130
129
|
alias($._type_tuple, $.tuple),
|
|
131
|
-
alias($._type_infix, $.infix),
|
|
132
130
|
alias($._type_apply, $.apply),
|
|
133
131
|
$._universal,
|
|
134
132
|
),
|
|
135
133
|
|
|
134
|
+
type: $ => choice(
|
|
135
|
+
alias($._type_infix_chain, $.infix_chain),
|
|
136
|
+
$.type_operand,
|
|
137
|
+
),
|
|
138
|
+
|
|
136
139
|
// ------------------------------------------------------------------------
|
|
137
140
|
// forall
|
|
138
141
|
// ------------------------------------------------------------------------
|
|
@@ -318,7 +321,7 @@ module.exports = {
|
|
|
318
321
|
|
|
319
322
|
_type_instance_head: $ => choice(
|
|
320
323
|
seq($._type_instance_head_params, optional(field('patterns', $.type_patterns))),
|
|
321
|
-
seq($._cond_infix, field('head', alias($.
|
|
324
|
+
seq($._cond_infix, field('head', alias($._type_infix_chain, $.infix_chain))),
|
|
322
325
|
),
|
|
323
326
|
|
|
324
327
|
// ------------------------------------------------------------------------
|
package/grammar.js
CHANGED
|
@@ -64,23 +64,14 @@ module.exports = grammar({
|
|
|
64
64
|
$.pragma,
|
|
65
65
|
],
|
|
66
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
67
|
supertypes: $ => [
|
|
77
|
-
$.
|
|
78
|
-
$.
|
|
79
|
-
$.
|
|
68
|
+
$.expression_operand,
|
|
69
|
+
$.pattern_operand,
|
|
70
|
+
$.binding_pattern_operand,
|
|
80
71
|
$.binding_field_pattern,
|
|
81
|
-
$.
|
|
72
|
+
$.type_operand,
|
|
82
73
|
$.quantified_type,
|
|
83
|
-
$.
|
|
74
|
+
$.constraint_operand,
|
|
84
75
|
$.constraints,
|
|
85
76
|
$.type_param,
|
|
86
77
|
$.declaration,
|