@algosail/tree-sitter 0.1.2 → 0.1.3
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/grammar.js +125 -128
- package/package.json +1 -1
- package/src/grammar.json +309 -561
- package/src/node-types.json +198 -437
- package/src/parser.c +3171 -3439
- package/tree-sitter-sail.wasm +0 -0
package/grammar.js
CHANGED
|
@@ -10,30 +10,96 @@ module.exports = grammar({
|
|
|
10
10
|
extras: ($) => [/\s+/],
|
|
11
11
|
|
|
12
12
|
conflicts: ($) => [
|
|
13
|
-
// '(' can start a comment OR a signature — tree-sitter resolves by
|
|
14
|
-
// looking for '--' inside.
|
|
15
13
|
[$.comment, $.signature],
|
|
16
14
|
[$.comment, $.sig_quotation],
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
[$.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
[$.
|
|
23
|
-
|
|
24
|
-
[$.
|
|
25
|
-
[$.
|
|
26
|
-
|
|
27
|
-
[$.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
|
|
16
|
+
[$.module_def, $.module_ref],
|
|
17
|
+
[$.group_def, $.group_ref],
|
|
18
|
+
[$.tag_def, $.tag_ref],
|
|
19
|
+
[$.map_def, $.map_ref],
|
|
20
|
+
[$.field_def, $.field_ref],
|
|
21
|
+
|
|
22
|
+
[$.group],
|
|
23
|
+
[$.tag],
|
|
24
|
+
[$.map],
|
|
25
|
+
[$.field],
|
|
26
|
+
[$.word],
|
|
27
|
+
|
|
28
|
+
[$.group_def],
|
|
29
|
+
[$.tag, $.group],
|
|
30
|
+
[$.word, $._expr],
|
|
31
31
|
],
|
|
32
32
|
|
|
33
33
|
rules: {
|
|
34
34
|
source_file: ($) => repeat($._top_level),
|
|
35
|
+
_top_level: ($) => choice($.comment, $.import, $.group, $.map, $.word),
|
|
36
|
+
|
|
37
|
+
// ~Module
|
|
38
|
+
module_def: ($) => /~[A-Z][a-zA-Z0-9_]*/,
|
|
39
|
+
// ~Module
|
|
40
|
+
module_ref: ($) => /~[A-Z][a-zA-Z0-9_]*/,
|
|
41
|
+
// &Group
|
|
42
|
+
group_def: ($) => /&[A-Z][a-zA-Z0-9_]*/,
|
|
43
|
+
// &Group
|
|
44
|
+
group_ref: ($) => /&[A-Z][a-zA-Z0-9_]*/,
|
|
45
|
+
// #Tag
|
|
46
|
+
tag_def: ($) => /#[A-Z][a-zA-Z0-9_]*/,
|
|
47
|
+
// #Tag
|
|
48
|
+
tag_ref: ($) => /#[A-Z][a-zA-Z0-9_]*/,
|
|
49
|
+
// _Tag
|
|
50
|
+
tag_pattern: ($) => /\_[A-Z][a-zA-Z0-9_]*/,
|
|
51
|
+
// _
|
|
52
|
+
default_pattern: ($) => token('_'),
|
|
53
|
+
// $Map
|
|
54
|
+
map_def: ($) => /\$[A-Z][a-zA-Z0-9_]*/,
|
|
55
|
+
// $Map
|
|
56
|
+
map_ref: ($) => /\$[A-Z][a-zA-Z0-9_]*/,
|
|
57
|
+
// .field
|
|
58
|
+
field_def: ($) => /\.[a-z][a-zA-Z0-9_]*/,
|
|
59
|
+
// $Map.field
|
|
60
|
+
field_ref: ($) => /\$[A-Z][a-zA-Z0-9_]*\.[a-z][a-zA-Z0-9_]*/,
|
|
61
|
+
// @word
|
|
62
|
+
word_def: ($) => /@[a-z][a-zA-Z0-9_]*/,
|
|
63
|
+
// /word
|
|
64
|
+
word_ref: ($) => /\/[a-z][a-zA-Z0-9_]*/,
|
|
65
|
+
|
|
66
|
+
// ~Module&Group
|
|
67
|
+
module_group_ref: ($) => /~[A-Z][a-zA-Z0-9_]*&[A-Z][a-zA-Z0-9_]*/,
|
|
68
|
+
// ~Module#Tag
|
|
69
|
+
module_tag_ref: ($) => /~[A-Z][a-zA-Z0-9_]*#[A-Z][a-zA-Z0-9_]*/,
|
|
70
|
+
// ~Module$Map
|
|
71
|
+
module_map_ref: ($) => /~[A-Z][a-zA-Z0-9_]*\$[A-Z][a-zA-Z0-9_]*/,
|
|
72
|
+
// ~Module$Map.field
|
|
73
|
+
module_field_ref: ($) => /~[A-Z][a-zA-Z0-9_]*\$[A-Z][a-zA-Z0-9_]*\.[a-z][a-zA-Z0-9_]*/,
|
|
74
|
+
// ~Module/word
|
|
75
|
+
module_word_ref: ($) => /~[A-Z][a-zA-Z0-9_]*\/[a-z][a-zA-Z0-9_]*/,
|
|
76
|
+
|
|
77
|
+
// Uppercase type: Int, Str, Maybe, List, etc.
|
|
78
|
+
type: ($) => /[A-Z][a-zA-Z0-9_]*/,
|
|
79
|
+
// Lowercase type variable: a, b, elem, etc.
|
|
80
|
+
type_var: ($) => /[a-z][a-zA-Z0-9_]*/,
|
|
81
|
+
// Lowercase type variable: a, b, elem, etc.
|
|
82
|
+
spread: ($) => /\.\.[a-z][a-zA-Z0-9_]*/,
|
|
83
|
+
|
|
84
|
+
// +Effect
|
|
85
|
+
effect_add: ($) => /\+[A-Z][a-zA-Z0-9_]*/,
|
|
86
|
+
// -Effect
|
|
87
|
+
effect_remove: ($) => /\-[A-Z][a-zA-Z0-9_]*/,
|
|
35
88
|
|
|
36
|
-
|
|
89
|
+
// :name
|
|
90
|
+
slot_push: ($) => /:[a-z][a-zA-Z0-9_]*/,
|
|
91
|
+
|
|
92
|
+
// ;name
|
|
93
|
+
slot_pop: ($) => /;[a-z][a-zA-Z0-9_]*/,
|
|
94
|
+
|
|
95
|
+
// 'raw string literal'
|
|
96
|
+
raw_string: ($) => /\'[^\']*\'/,
|
|
97
|
+
|
|
98
|
+
// Catch-all: any non-whitespace sequence that doesn't match a more specific
|
|
99
|
+
// rule. prec(-1) gives it the lowest priority so every other token wins
|
|
100
|
+
// when there is a tie. Structural characters ( ) [ ] are excluded because
|
|
101
|
+
// they are needed by the parser to delimit blocks and comments.
|
|
102
|
+
raw_value: ($) => token(prec(-1, /[^\s\[\]()']+/)),
|
|
37
103
|
|
|
38
104
|
// Comment / doc block: ( any text )
|
|
39
105
|
// comment_content is recursive: it can contain plain text and/or nested
|
|
@@ -42,46 +108,55 @@ module.exports = grammar({
|
|
|
42
108
|
comment_content: ($) => repeat1(choice(/[^()]+/, $.comment)),
|
|
43
109
|
|
|
44
110
|
// Import: +path/or/+pkg Alias
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
111
|
+
import: ($) => seq(field('path', $.path), field('module', $.module_def)),
|
|
112
|
+
path: ($) => /\+[^\s]+/,
|
|
113
|
+
// seq('+', field('url', alias(/[^\s]+/, $.url))),
|
|
48
114
|
|
|
49
115
|
// Tag group: &Name typeParam* (#TagCase typeParam*)*
|
|
50
|
-
|
|
116
|
+
group: ($) =>
|
|
51
117
|
seq(
|
|
52
|
-
field('
|
|
53
|
-
repeat($.
|
|
118
|
+
field('def', $.group_def),
|
|
119
|
+
repeat($.type_var),
|
|
54
120
|
optional(field('doc', $.comment)),
|
|
55
|
-
repeat($.
|
|
121
|
+
repeat($.tag),
|
|
56
122
|
),
|
|
57
|
-
|
|
58
|
-
tag_def: ($) =>
|
|
123
|
+
tag: ($) =>
|
|
59
124
|
seq(
|
|
60
|
-
field('
|
|
61
|
-
optional(field('type_param', $.
|
|
125
|
+
field('def', $.tag_def),
|
|
126
|
+
optional(field('type_param', $.type_var)),
|
|
62
127
|
optional(field('doc', $.comment)),
|
|
63
128
|
),
|
|
64
|
-
|
|
129
|
+
group_type: ($) =>
|
|
130
|
+
seq(
|
|
131
|
+
field('group', choice($.group_ref, $.module_group_ref)),
|
|
132
|
+
optional(field('params', $._generic)),
|
|
133
|
+
),
|
|
134
|
+
_generic: ($) => seq('{', repeat($._generic_content), '}'),
|
|
135
|
+
_generic_content: ($) => choice($.type, $.group_type, $.map_ref, $.module_map_ref),
|
|
65
136
|
|
|
66
137
|
// Map definition: %Name (.field Type)*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
map_name: ($) => seq('$', field('name', alias(UPPERNAME, $.map_ref))),
|
|
70
|
-
map_field: ($) =>
|
|
138
|
+
map: ($) => seq(field('def', $.map_def), optional(field('doc', $.comment)), repeat($.field)),
|
|
139
|
+
field: ($) =>
|
|
71
140
|
seq(
|
|
72
|
-
field('key', $.
|
|
73
|
-
field('type', $.
|
|
141
|
+
field('key', $.field_def),
|
|
142
|
+
field('type', $._field_types),
|
|
74
143
|
optional(field('doc', $.comment)),
|
|
75
144
|
),
|
|
76
|
-
|
|
145
|
+
_field_types: ($) => choice($.type, $.group_type, $.map_ref, $.module_map_ref),
|
|
77
146
|
|
|
78
147
|
// Word definition: @name ( sig ) expr*
|
|
79
148
|
// Signature is required per the spec ("Word definition must have a signature").
|
|
80
149
|
// prec.right makes the body's repeat greedy: prefer consuming '(' as a body
|
|
81
150
|
// comment rather than ending the word_def early.
|
|
82
|
-
|
|
83
|
-
prec.right(
|
|
84
|
-
|
|
151
|
+
word: ($) =>
|
|
152
|
+
prec.right(
|
|
153
|
+
seq(
|
|
154
|
+
field('name_def', $.word_def),
|
|
155
|
+
field('sig', $.signature),
|
|
156
|
+
optional(field('doc', $.comment)),
|
|
157
|
+
repeat($._expr),
|
|
158
|
+
),
|
|
159
|
+
),
|
|
85
160
|
|
|
86
161
|
// Signature: ( inputs -- outputs +effects )
|
|
87
162
|
// The required '--' token is what makes it unambiguous vs a comment.
|
|
@@ -92,10 +167,13 @@ module.exports = grammar({
|
|
|
92
167
|
$.effect_add,
|
|
93
168
|
$.effect_remove,
|
|
94
169
|
$.spread,
|
|
95
|
-
$.
|
|
96
|
-
$.
|
|
170
|
+
$.type,
|
|
171
|
+
$.type_var,
|
|
97
172
|
$.sig_list,
|
|
98
173
|
$.sig_quotation,
|
|
174
|
+
$.group_type,
|
|
175
|
+
$.map_ref,
|
|
176
|
+
$.module_map_ref,
|
|
99
177
|
),
|
|
100
178
|
|
|
101
179
|
// [ Type Type ... ] — list / tuple type in a signature
|
|
@@ -104,35 +182,20 @@ module.exports = grammar({
|
|
|
104
182
|
// ( a b -- c d ) — higher-order function type nested inside a signature
|
|
105
183
|
sig_quotation: ($) => seq('(', repeat($._sig_item), $.sig_arrow, repeat($._sig_item), ')'),
|
|
106
184
|
|
|
107
|
-
// +IO, +FAIL, etc.
|
|
108
|
-
effect_add: ($) => seq('+', field('name', alias(UPPERNAME, $.effect_ref))),
|
|
109
|
-
|
|
110
|
-
// -IO, -FAIL, etc. (uppercase after dash avoids matching negative numbers)
|
|
111
|
-
effect_remove: ($) => seq('-', field('name', alias(UPPERNAME, $.effect_ref))),
|
|
112
|
-
|
|
113
|
-
// ..a, ..row — spread / row-variable in a signature
|
|
114
|
-
spread: ($) => seq('..', field('name', alias(/[a-zA-Z][a-zA-Z0-9_]*/, $.spread_ref))),
|
|
115
|
-
|
|
116
|
-
// Uppercase type: Int, Str, Maybe, List, etc.
|
|
117
|
-
type_name: ($) => UPPERNAME,
|
|
118
|
-
|
|
119
|
-
// Lowercase type variable: a, b, elem, etc.
|
|
120
|
-
type_variable: ($) => LOWERNAME,
|
|
121
|
-
|
|
122
185
|
// Expressions inside word bodies
|
|
123
186
|
_expr: ($) =>
|
|
124
187
|
choice(
|
|
125
188
|
$.comment, // doc / inline comment block
|
|
126
189
|
$.quotation,
|
|
127
190
|
$.builtin_word,
|
|
128
|
-
$.
|
|
129
|
-
$.
|
|
130
|
-
$.
|
|
131
|
-
$.
|
|
132
|
-
$.map_access,
|
|
133
|
-
$.tag_constructor,
|
|
191
|
+
$.word_ref,
|
|
192
|
+
$.module_word_ref,
|
|
193
|
+
$.tag_ref,
|
|
194
|
+
$.module_tag_ref,
|
|
134
195
|
$.tag_pattern,
|
|
135
196
|
$.default_pattern,
|
|
197
|
+
$.field_ref,
|
|
198
|
+
$.module_field_ref,
|
|
136
199
|
$.slot_push,
|
|
137
200
|
$.slot_pop,
|
|
138
201
|
$.raw_string,
|
|
@@ -170,71 +233,5 @@ module.exports = grammar({
|
|
|
170
233
|
'ERROR',
|
|
171
234
|
),
|
|
172
235
|
),
|
|
173
|
-
|
|
174
|
-
// /wordName — call a locally defined word
|
|
175
|
-
word_call: ($) => seq('/', field('word', alias(LOWERNAME, $.word_ref))),
|
|
176
|
-
|
|
177
|
-
// ~Module/word — module-qualified word call
|
|
178
|
-
// Broken into named fields so the AST exposes module_ref and word_ref nodes.
|
|
179
|
-
module_word_call: ($) =>
|
|
180
|
-
seq(
|
|
181
|
-
'~',
|
|
182
|
-
field('module', alias(UPPERNAME, $.module_ref)),
|
|
183
|
-
'/',
|
|
184
|
-
field('word', alias(LOWERNAME, $.word_ref)),
|
|
185
|
-
),
|
|
186
|
-
|
|
187
|
-
// ~Module#TagName — module-qualified tag constructor
|
|
188
|
-
module_tag_constructor: ($) =>
|
|
189
|
-
seq(
|
|
190
|
-
'~',
|
|
191
|
-
field('module', alias(UPPERNAME, $.module_ref)),
|
|
192
|
-
'#',
|
|
193
|
-
field('tag', alias(UPPERNAME, $.tag_ref)),
|
|
194
|
-
),
|
|
195
|
-
|
|
196
|
-
// ~Module,Map.field — module-qualified map field accessor / lens
|
|
197
|
-
module_map_access: ($) =>
|
|
198
|
-
seq(
|
|
199
|
-
'~',
|
|
200
|
-
field('module', alias(UPPERNAME, $.module_ref)),
|
|
201
|
-
',',
|
|
202
|
-
field('map', alias(UPPERNAME, $.map_ref)),
|
|
203
|
-
'.',
|
|
204
|
-
field('field', alias(LOWERNAME, $.field_ref)),
|
|
205
|
-
),
|
|
206
|
-
|
|
207
|
-
// ,Map.field — local map field accessor / lens
|
|
208
|
-
map_access: ($) =>
|
|
209
|
-
seq(
|
|
210
|
-
',',
|
|
211
|
-
field('map', alias(UPPERNAME, $.map_ref)),
|
|
212
|
-
'.',
|
|
213
|
-
field('field', alias(LOWERNAME, $.field_ref)),
|
|
214
|
-
),
|
|
215
|
-
|
|
216
|
-
// #TagName — construct a tagged union value
|
|
217
|
-
tag_constructor: ($) => seq('#', field('name', alias(UPPERNAME, $.tag_ref))),
|
|
218
|
-
|
|
219
|
-
// _TagName — match/destructure a tag in MATCH
|
|
220
|
-
tag_pattern: ($) => seq('_', field('name', alias(UPPERNAME, $.tag_ref))),
|
|
221
|
-
|
|
222
|
-
// _ — match/destructure a default in MATCH
|
|
223
|
-
default_pattern: ($) => token('_'),
|
|
224
|
-
|
|
225
|
-
// :name — pop the top of the stack into a named local slot
|
|
226
|
-
slot_push: ($) => seq(':', field('name', alias(LOWERNAME, $.slot_ref))),
|
|
227
|
-
|
|
228
|
-
// ;name — push a named local slot back onto the stack
|
|
229
|
-
slot_pop: ($) => seq(';', field('name', alias(LOWERNAME, $.slot_ref))),
|
|
230
|
-
|
|
231
|
-
// 'raw string literal'
|
|
232
|
-
raw_string: ($) => /\'[^\']*\'/,
|
|
233
|
-
|
|
234
|
-
// Catch-all: any non-whitespace sequence that doesn't match a more specific
|
|
235
|
-
// rule. prec(-1) gives it the lowest priority so every other token wins
|
|
236
|
-
// when there is a tie. Structural characters ( ) [ ] are excluded because
|
|
237
|
-
// they are needed by the parser to delimit blocks and comments.
|
|
238
|
-
raw_value: ($) => token(prec(-1, /[^\s\[\]()']+/)),
|
|
239
236
|
},
|
|
240
237
|
})
|