@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 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
- // After word_def's signature, '(' is ambiguous: body comment vs next
18
- // top-level item. Declare as GLR self-conflict so both are explored.
19
- [$.word_def],
20
- // After tag_group_name + type_variables, '(' is ambiguous: doc comment
21
- // for this tag_group vs a top-level comment that follows it.
22
- [$.tag_group],
23
- [$.tag_def],
24
- [$.map_def],
25
- [$.map_field],
26
- // tag_group contains tag_def children; both can follow an uppercase name
27
- [$.tag_def, $.tag_group],
28
- // module_alias and type_name are both /[A-Z][a-zA-Z0-9_]*/
29
- // [$.type_name, $.module_alias],
30
- // type_variable and identifier are both lowercase words
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
- _top_level: ($) => choice($.comment, $.import_decl, $.tag_group, $.map_def, $.word_def),
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
- import_decl: ($) => seq(field('path', $.import_path), field('alias', $.module_alias)),
46
- import_path: ($) => seq('+', field('url', alias(/[^\s]+/, $.url))),
47
- module_alias: ($) => seq('~', field('module', alias(UPPERNAME, $.module_ref))),
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
- tag_group: ($) =>
116
+ group: ($) =>
51
117
  seq(
52
- field('name_def', $.tag_group_name),
53
- repeat($.type_variable),
118
+ field('def', $.group_def),
119
+ repeat($.type_var),
54
120
  optional(field('doc', $.comment)),
55
- repeat($.tag_def),
121
+ repeat($.tag),
56
122
  ),
57
- tag_group_name: ($) => seq('&', field('name', alias(UPPERNAME, $.group_ref))),
58
- tag_def: ($) =>
123
+ tag: ($) =>
59
124
  seq(
60
- field('name_def', $.tag_name),
61
- optional(field('type_param', $.type_variable)),
125
+ field('def', $.tag_def),
126
+ optional(field('type_param', $.type_var)),
62
127
  optional(field('doc', $.comment)),
63
128
  ),
64
- tag_name: ($) => seq('#', field('name', alias(UPPERNAME, $.tag_ref))),
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
- map_def: ($) =>
68
- seq(field('name_def', $.map_name), optional(field('doc', $.comment)), repeat($.map_field)),
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', $.map_field_name),
73
- field('type', $.type_name),
141
+ field('key', $.field_def),
142
+ field('type', $._field_types),
74
143
  optional(field('doc', $.comment)),
75
144
  ),
76
- map_field_name: ($) => seq('.', field('name', alias(LOWERNAME, $.field_ref))),
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
- word_def: ($) =>
83
- prec.right(seq(field('name_def', $.word_name), field('sig', $.signature), repeat($._expr))),
84
- word_name: ($) => seq('@', field('name', alias(LOWERNAME, $.word_ref))),
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
- $.type_name,
96
- $.type_variable,
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
- $.word_call,
129
- $.module_word_call,
130
- $.module_tag_constructor,
131
- $.module_map_access,
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
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algosail/tree-sitter",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Tree-sitter grammar for the Sail language",
5
5
  "main": "bindings/node",
6
6
  "types": "bindings/node",