@willbooster/tree-sitter-haskell 0.0.0-stage → 1.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/LICENSE +21 -0
- package/README.md +155 -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 +102 -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/pat.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
const {
|
|
2
|
+
sep1,
|
|
3
|
+
sep2,
|
|
4
|
+
sep,
|
|
5
|
+
parens,
|
|
6
|
+
braces,
|
|
7
|
+
brackets,
|
|
8
|
+
unboxed_tuple_full,
|
|
9
|
+
unboxed_sum_single,
|
|
10
|
+
} = require('./util.js')
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
|
|
14
|
+
// ------------------------------------------------------------------------
|
|
15
|
+
// tuples and parens
|
|
16
|
+
// ------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
_pat_parens: $ => parens($, field('pattern', $._pat_texp)),
|
|
19
|
+
|
|
20
|
+
_pat_tuple_elems: $ => sep2(',', field('element', $._pat_texp)),
|
|
21
|
+
|
|
22
|
+
_pat_tuple: $ => parens($, $._pat_tuple_elems),
|
|
23
|
+
|
|
24
|
+
_pat_unboxed_tuple: $ => unboxed_tuple_full($, $._pat_texp),
|
|
25
|
+
|
|
26
|
+
_pat_unboxed_sum: $ => unboxed_sum_single($, $._pat_texp),
|
|
27
|
+
|
|
28
|
+
_pat_list: $ => brackets($, sep1(',', field('element', $._pat_texp)), optional(',')),
|
|
29
|
+
|
|
30
|
+
// ------------------------------------------------------------------------
|
|
31
|
+
// record
|
|
32
|
+
// ------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
field_pattern: $ => choice(
|
|
35
|
+
alias('..', $.wildcard),
|
|
36
|
+
seq(field('field', $._field_names), optional(seq('=', field('pattern', $._pat_texp)))),
|
|
37
|
+
),
|
|
38
|
+
|
|
39
|
+
_pat_record: $ => prec('record', seq(
|
|
40
|
+
field('constructor', $.pattern),
|
|
41
|
+
braces($, sep(',', field('field', $.field_pattern))),
|
|
42
|
+
)),
|
|
43
|
+
|
|
44
|
+
// ------------------------------------------------------------------------
|
|
45
|
+
// misc
|
|
46
|
+
// ------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* This dynamic precedence penalty is relevant for the conflict between `function` and `bind`.
|
|
50
|
+
* Consider:
|
|
51
|
+
*
|
|
52
|
+
* > f (A a) = exp
|
|
53
|
+
*
|
|
54
|
+
* Because of the "single choice disambiguated with named precedences" approach used for `pattern`, the left node in
|
|
55
|
+
* `pat_apply` can be a variable, even though it's not valid Haskell.
|
|
56
|
+
* While the static prec 'pat-name' covers this at generation time, Haskell's ambiguity requires us to use a runtime
|
|
57
|
+
* conflict for `function`/`bind`, where static prec is ineffective.
|
|
58
|
+
* Giving the reduction of `_var` to `pattern` a strong negative dynamic prec ensures that the runtime branch for
|
|
59
|
+
* `bind` has lower precedence because of `f`, so `function` always wins.
|
|
60
|
+
*
|
|
61
|
+
* While `bind` usually has a lower score than `function` anyway in this situation because it is slightly more
|
|
62
|
+
* complex, there are never any guarantees for runtime conflicts.
|
|
63
|
+
* In particular, the presence of minor parse errors later in the declaration can tip the scales randomly.
|
|
64
|
+
*/
|
|
65
|
+
_pat_name: $ => choice(
|
|
66
|
+
prec('pat-name', prec.dynamic(-1000, $._var)),
|
|
67
|
+
$._cons,
|
|
68
|
+
),
|
|
69
|
+
|
|
70
|
+
_pat_as: $ => prec('prefix', seq(field('bind', $.variable), $._tight_at, field('pattern', $.pattern))),
|
|
71
|
+
|
|
72
|
+
_pat_wildcard: _ => '_',
|
|
73
|
+
|
|
74
|
+
_pat_strict: $ => prec('prefix', seq($._any_prefix_bang, field('pattern', $.pattern))),
|
|
75
|
+
|
|
76
|
+
_pat_irrefutable: $ => prec('prefix', seq($._any_prefix_tilde, field('pattern', $.pattern))),
|
|
77
|
+
|
|
78
|
+
// ------------------------------------------------------------------------
|
|
79
|
+
// application
|
|
80
|
+
// ------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
_pat_apply_arg: $ => choice(
|
|
83
|
+
$.pattern,
|
|
84
|
+
alias($._at_type, $.type_binder),
|
|
85
|
+
$.explicit_type,
|
|
86
|
+
),
|
|
87
|
+
|
|
88
|
+
_pat_apply: $ => prec.left('apply', seq(
|
|
89
|
+
field('function', $.pattern),
|
|
90
|
+
field('argument', $._pat_apply_arg),
|
|
91
|
+
)),
|
|
92
|
+
|
|
93
|
+
// ------------------------------------------------------------------------
|
|
94
|
+
// operators
|
|
95
|
+
// ------------------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
_pat_negation: $ => seq('-', field('number', $._number)),
|
|
98
|
+
|
|
99
|
+
_pat_infix: $ => prec.right('infix', seq(
|
|
100
|
+
field('left_operand', $.pattern),
|
|
101
|
+
optional($._cond_no_section_op),
|
|
102
|
+
field('operator', choice(
|
|
103
|
+
$.constructor_operator,
|
|
104
|
+
$._conids_ticked,
|
|
105
|
+
seq($._cond_qualified_op, $._qconsym),
|
|
106
|
+
)),
|
|
107
|
+
field('right_operand', $.pattern),
|
|
108
|
+
)),
|
|
109
|
+
|
|
110
|
+
// ------------------------------------------------------------------------
|
|
111
|
+
// top level
|
|
112
|
+
// ------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
pattern: $ => choice(
|
|
115
|
+
alias($._pat_infix, $.infix),
|
|
116
|
+
alias($._pat_negation, $.negation),
|
|
117
|
+
alias($._pat_apply, $.apply),
|
|
118
|
+
$._pat_name,
|
|
119
|
+
alias($._pat_as, $.as),
|
|
120
|
+
alias($._pat_record, $.record),
|
|
121
|
+
alias($._pat_wildcard, $.wildcard),
|
|
122
|
+
alias($._pat_parens, $.parens),
|
|
123
|
+
alias($._pat_tuple, $.tuple),
|
|
124
|
+
alias($._pat_unboxed_tuple, $.unboxed_tuple),
|
|
125
|
+
alias($._pat_unboxed_sum, $.unboxed_sum),
|
|
126
|
+
alias($._pat_list, $.list),
|
|
127
|
+
alias($._plist, $.list),
|
|
128
|
+
alias($._pat_strict, $.strict),
|
|
129
|
+
alias($._pat_irrefutable, $.irrefutable),
|
|
130
|
+
$._universal,
|
|
131
|
+
),
|
|
132
|
+
|
|
133
|
+
patterns: $ => repeat1(prec('patterns', $._pat_apply_arg)),
|
|
134
|
+
|
|
135
|
+
_pat_signature: $ => prec.right('annotated', seq(
|
|
136
|
+
field('pattern', $.pattern),
|
|
137
|
+
$._type_annotation,
|
|
138
|
+
)),
|
|
139
|
+
|
|
140
|
+
_pat: $ => choice(
|
|
141
|
+
alias($._pat_signature, $.signature),
|
|
142
|
+
prec.right($.pattern),
|
|
143
|
+
),
|
|
144
|
+
|
|
145
|
+
view_pattern: $ => seq(field('expression', $._exp), $._arrow, field('pattern', $._pat_texp)),
|
|
146
|
+
|
|
147
|
+
_pat_texp: $ => choice($.view_pattern, $._pat),
|
|
148
|
+
|
|
149
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const {
|
|
2
|
+
layout,
|
|
3
|
+
optional_where,
|
|
4
|
+
} = require('./util.js')
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
// ------------------------------------------------------------------------
|
|
8
|
+
// pattern synonym
|
|
9
|
+
// ------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
_patsyn_signature: $ => seq(
|
|
12
|
+
field('synonym', choice($._con, alias($._con_binding_list, $.binding_list))),
|
|
13
|
+
$._colon2,
|
|
14
|
+
field('type', $.quantified_type),
|
|
15
|
+
),
|
|
16
|
+
|
|
17
|
+
_patsyn_cons: $ => layout($, alias($.bind, $.constructor_synonym)),
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This allows a `where` after any equation for parsing resilience, even though it's only valid for the arrow variant
|
|
21
|
+
* (explicitly bidirectional patterns).
|
|
22
|
+
* The `where` may also be empty.
|
|
23
|
+
*/
|
|
24
|
+
_patsyn_equation: $ => seq(
|
|
25
|
+
field('synonym', $.pattern),
|
|
26
|
+
choice(
|
|
27
|
+
'=',
|
|
28
|
+
$._larrow,
|
|
29
|
+
),
|
|
30
|
+
field('pattern', $._pat),
|
|
31
|
+
optional_where($, field('constructors', alias($._patsyn_cons, $.constructor_synonyms))),
|
|
32
|
+
),
|
|
33
|
+
|
|
34
|
+
pattern_synonym: $ => seq(
|
|
35
|
+
'pattern',
|
|
36
|
+
choice(
|
|
37
|
+
alias($._patsyn_signature, $.signature),
|
|
38
|
+
alias($._patsyn_equation, $.equation),
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
|
|
3
|
+
precedences: $ => [
|
|
4
|
+
|
|
5
|
+
// ------------------------------------------------
|
|
6
|
+
// associativity of expressions, patterns and types
|
|
7
|
+
// ------------------------------------------------
|
|
8
|
+
|
|
9
|
+
[
|
|
10
|
+
'projection',
|
|
11
|
+
'record',
|
|
12
|
+
'prefix',
|
|
13
|
+
'apply',
|
|
14
|
+
'negation',
|
|
15
|
+
'infix',
|
|
16
|
+
'implicit',
|
|
17
|
+
'fun',
|
|
18
|
+
'annotated',
|
|
19
|
+
$.quantified_type,
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
// ------------------------------------------------
|
|
23
|
+
// negation
|
|
24
|
+
// ------------------------------------------------
|
|
25
|
+
|
|
26
|
+
[
|
|
27
|
+
$._pat_negation,
|
|
28
|
+
$.literal,
|
|
29
|
+
],
|
|
30
|
+
|
|
31
|
+
// ------------------------------------------------
|
|
32
|
+
// function vs bind
|
|
33
|
+
// ------------------------------------------------
|
|
34
|
+
|
|
35
|
+
[
|
|
36
|
+
'bind',
|
|
37
|
+
'pat-name',
|
|
38
|
+
],
|
|
39
|
+
|
|
40
|
+
// ------------------------------------------------
|
|
41
|
+
// qualified names
|
|
42
|
+
// ------------------------------------------------
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Prioritize shifting over a tight infix dot over reducing to a qualified constructor or module.
|
|
46
|
+
*/
|
|
47
|
+
[
|
|
48
|
+
'qualifying-module',
|
|
49
|
+
'qualified-id',
|
|
50
|
+
],
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Prioritize qualified variables over record field projection on constructors.
|
|
54
|
+
*/
|
|
55
|
+
[
|
|
56
|
+
'qualifying-module',
|
|
57
|
+
'con',
|
|
58
|
+
],
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Prioritize qualified names over the infix operator dot in types.
|
|
62
|
+
*/
|
|
63
|
+
[
|
|
64
|
+
'qualifying-module',
|
|
65
|
+
'type-name',
|
|
66
|
+
],
|
|
67
|
+
|
|
68
|
+
// ------------------------------------------------
|
|
69
|
+
// types and constraints
|
|
70
|
+
// ------------------------------------------------
|
|
71
|
+
|
|
72
|
+
[
|
|
73
|
+
$.operator,
|
|
74
|
+
$._type_star,
|
|
75
|
+
],
|
|
76
|
+
|
|
77
|
+
[
|
|
78
|
+
$._type_wildcard,
|
|
79
|
+
$._type_param_wildcard,
|
|
80
|
+
],
|
|
81
|
+
|
|
82
|
+
[
|
|
83
|
+
$._constructor_ticked,
|
|
84
|
+
$._tycon_ticked,
|
|
85
|
+
],
|
|
86
|
+
|
|
87
|
+
[
|
|
88
|
+
'qtype-single',
|
|
89
|
+
'qtype-curried',
|
|
90
|
+
],
|
|
91
|
+
|
|
92
|
+
// ------------------------------------------------
|
|
93
|
+
// misc
|
|
94
|
+
// ------------------------------------------------
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* > f A a a = a
|
|
98
|
+
* > data A = A Int Int
|
|
99
|
+
*
|
|
100
|
+
* This should not be parsed as constructor application, but separate patterns.
|
|
101
|
+
*/
|
|
102
|
+
[
|
|
103
|
+
'patterns',
|
|
104
|
+
'apply',
|
|
105
|
+
],
|
|
106
|
+
|
|
107
|
+
],
|
|
108
|
+
|
|
109
|
+
}
|
package/grammar/th.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const {
|
|
2
|
+
layout_sort,
|
|
3
|
+
} = require('./util.js')
|
|
4
|
+
|
|
5
|
+
const quote_bracket = ($, quoter) => seq(
|
|
6
|
+
$._cond_quote_start,
|
|
7
|
+
'[',
|
|
8
|
+
field('quoter', quoter),
|
|
9
|
+
'|',
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
|
|
14
|
+
// ------------------------------------------------------------------------
|
|
15
|
+
// splice
|
|
16
|
+
// ------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Even though the doc states "arbitrary expression", it's very rare for any others than names and parenthesized
|
|
20
|
+
* expressions to occur, and it's very expensive to allow them.
|
|
21
|
+
* Even only allowing list and quotes adds a full megabyte to the parser size.
|
|
22
|
+
*/
|
|
23
|
+
_splice_exp: $ => choice(
|
|
24
|
+
$._exp_name,
|
|
25
|
+
alias($._exp_parens, $.parens),
|
|
26
|
+
$.literal,
|
|
27
|
+
),
|
|
28
|
+
|
|
29
|
+
_splice_dollars: $ => seq(
|
|
30
|
+
$._cond_splice,
|
|
31
|
+
choice('$', '$$'),
|
|
32
|
+
),
|
|
33
|
+
|
|
34
|
+
splice: $ => seq($._splice_dollars, field('expression', $._splice_exp)),
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Since `expression` includes `splice`, this allows for a top level dollar splice as well.
|
|
38
|
+
*/
|
|
39
|
+
top_splice: $ => $.expression,
|
|
40
|
+
|
|
41
|
+
quoter: $ => $._varids,
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* `_cond_quote_start` (in `quote_bracket`) is a zero-width token emitted by the scanner.
|
|
45
|
+
* While the quoter and the bar may not be preceded by whitespace, this is not necessary to ensure here with
|
|
46
|
+
* `token.immediate` since the scanner already verifies it.
|
|
47
|
+
*/
|
|
48
|
+
quasiquote: $ => seq(
|
|
49
|
+
quote_bracket($, $.quoter),
|
|
50
|
+
optional(field('body', $.quasiquote_body)),
|
|
51
|
+
choice(token('|]'), '⟧'),
|
|
52
|
+
),
|
|
53
|
+
|
|
54
|
+
quoted_decls: $ => layout_sort($, $._cmd_layout_start_quote, field('declaration', $.declaration)),
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* An "expression quotation" is valid in an expression, and its body may contain an expression, type, pattern or
|
|
58
|
+
* declaration layout.
|
|
59
|
+
*
|
|
60
|
+
* Which of these are valid is decided by the quoter: `e`, `t`, `p` or `d`.
|
|
61
|
+
* If the quoter is empty, or the special oxford bracket character is used, the body is parsed as an expression.
|
|
62
|
+
*/
|
|
63
|
+
_exp_quote: $ => seq(
|
|
64
|
+
choice(
|
|
65
|
+
seq(choice('⟦', quote_bracket($, optional('e'))), optional(alias($._exp, $.quoted_expression))),
|
|
66
|
+
seq(quote_bracket($, 't'), optional(alias($._ktype, $.quoted_type))),
|
|
67
|
+
seq(quote_bracket($, 'p'), optional(alias($._pat, $.quoted_pattern))),
|
|
68
|
+
seq(quote_bracket($, 'd'), optional($.quoted_decls)),
|
|
69
|
+
),
|
|
70
|
+
choice(token('|]'), '⟧'),
|
|
71
|
+
),
|
|
72
|
+
|
|
73
|
+
_exp_typed_quote: $ => seq(
|
|
74
|
+
$._cond_quote_start,
|
|
75
|
+
'[',
|
|
76
|
+
optional('e'),
|
|
77
|
+
'||',
|
|
78
|
+
optional(alias($._exp, $.quoted_expression)),
|
|
79
|
+
token('||]'),
|
|
80
|
+
),
|
|
81
|
+
|
|
82
|
+
}
|