tree-sitter-rake 0.4.0-beta

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 ADDED
@@ -0,0 +1,598 @@
1
+ // Tree-sitter grammar for Rake's canonical source language.
2
+ // The generated parser is syntax-only; semantic and target guarantees remain
3
+ // compiler checks. Indentation is structural: src/scanner.c supplies the
4
+ // newline, indent and dedent tokens the compiler's layout filter produces, and
5
+ // lines inside parentheses, brackets or braces continue the logical line.
6
+
7
+ const PREC = {
8
+ conditional: 0,
9
+ or: 1,
10
+ and: 2,
11
+ compare: 3,
12
+ add: 4,
13
+ multiply: 5,
14
+ unary: 6,
15
+ call: 8,
16
+ postfix: 9,
17
+ static_call: 10,
18
+ };
19
+
20
+ export default grammar({
21
+ name: 'rake',
22
+
23
+ externals: $ => [$._newline, $._indent, $._dedent, $._error_sentinel, $.block_comment],
24
+
25
+ extras: $ => [/[\s⁠​]/, $.line_comment, $.block_comment],
26
+ word: $ => $.identifier,
27
+
28
+ rules: {
29
+ source_file: $ => repeat($._definition),
30
+
31
+ _definition: $ => choice(
32
+ seq($.stack_definition, $._newline),
33
+ seq($.record_definition, $._newline),
34
+ $.crunch_definition,
35
+ $.rake_definition,
36
+ $.run_definition,
37
+ $.slow_definition,
38
+ seq($.extern_definition, $._newline),
39
+ seq($.state_definition, $._newline),
40
+ seq($.embed_definition, $._newline),
41
+ seq($.const_definition, $._newline),
42
+ ),
43
+
44
+ line_comment: _ => /~~[^\n]*/,
45
+
46
+ stack_definition: $ => seq(
47
+ 'stack',
48
+ field('name', $.type_identifier),
49
+ '{',
50
+ repeat1($.field_group),
51
+ '}',
52
+ ),
53
+
54
+ field_group: $ => seq(
55
+ field('type', $.storage_type),
56
+ ':',
57
+ commaSep1(field('name', $.identifier)),
58
+ ';',
59
+ ),
60
+
61
+ record_definition: $ => seq(
62
+ 'record',
63
+ field('name', $.type_identifier),
64
+ optional(seq('from', field('header', $.string_literal))),
65
+ '{',
66
+ repeat1($.record_field_group),
67
+ '}',
68
+ ),
69
+
70
+ record_field_group: $ => seq(
71
+ field('type', $.type),
72
+ ':',
73
+ commaSep1(field('name', $.identifier)),
74
+ ';',
75
+ ),
76
+
77
+ crunch_definition: $ => seq(
78
+ 'crunch',
79
+ field('name', $.identifier),
80
+ $.parameter_list,
81
+ '->',
82
+ field('result', $.type),
83
+ $._block,
84
+ ),
85
+
86
+ rake_definition: $ => seq(
87
+ 'rake',
88
+ field('name', $.identifier),
89
+ $.parameter_list,
90
+ '->',
91
+ field('result', $.type),
92
+ ':',
93
+ $._newline,
94
+ $._indent,
95
+ repeat(seq($.let_statement, $._newline)),
96
+ repeat1($.tine_declaration),
97
+ repeat1($.through_statement),
98
+ $.return_sweep_statement,
99
+ $._dedent,
100
+ ),
101
+
102
+ run_definition: $ => seq(
103
+ 'run',
104
+ field('name', $.identifier),
105
+ $.parameter_list,
106
+ optional(seq('->', field('result', $.type))),
107
+ $._block,
108
+ ),
109
+
110
+ slow_definition: $ => seq(
111
+ 'slow',
112
+ field('name', $.identifier),
113
+ $.parameter_list,
114
+ optional(seq('->', field('result', $.type))),
115
+ $._block,
116
+ ),
117
+
118
+ extern_definition: $ => seq(
119
+ 'extern',
120
+ 'slow',
121
+ field('name', $.identifier),
122
+ $.parameter_list,
123
+ optional(seq('->', field('result', $.type))),
124
+ 'from',
125
+ field('header', $.string_literal),
126
+ ),
127
+
128
+ state_definition: $ => seq(
129
+ 'state',
130
+ field('name', $.identifier),
131
+ ':',
132
+ field('type', $.type),
133
+ optional(seq(':=', field('value', $.expression))),
134
+ ),
135
+
136
+ embed_definition: $ => seq(
137
+ 'embed',
138
+ field('name', $.identifier),
139
+ 'from',
140
+ field('file', $.string_literal),
141
+ ),
142
+
143
+ const_definition: $ => seq(
144
+ 'const',
145
+ field('name', $.identifier),
146
+ ':',
147
+ field('type', $.type),
148
+ '=',
149
+ field('value', $.expression),
150
+ ),
151
+
152
+ parameter_list: $ => seq('(', commaSep($.parameter), ')'),
153
+
154
+ parameter: $ => choice(
155
+ $.value_parameter,
156
+ $.scalar_parameter,
157
+ ),
158
+
159
+ value_parameter: $ => seq(
160
+ field('name', $.identifier),
161
+ ':',
162
+ field('type', $.type),
163
+ ),
164
+
165
+ scalar_parameter: $ => seq(
166
+ '<',
167
+ field('name', alias($.identifier, $.scalar_name)),
168
+ ':',
169
+ field('type', $.type),
170
+ '>',
171
+ ),
172
+
173
+ type: $ => choice(
174
+ $.storage_type,
175
+ $.rack_type,
176
+ $.mask_type,
177
+ $.pack_type,
178
+ $.stack_type,
179
+ $.array_type,
180
+ $.view_type,
181
+ $.pointer_type,
182
+ $.mutable_type,
183
+ $.type_identifier,
184
+ ),
185
+
186
+ storage_type: _ => choice(
187
+ 'f32', 'f64',
188
+ 'i8', 'i16', 'i32', 'i64',
189
+ 'u8', 'u16', 'u32', 'u64',
190
+ 'bool',
191
+ ),
192
+
193
+ rack_type: _ => choice(
194
+ 'f32s', 'f64s',
195
+ 'i8s', 'i16s', 'i32s', 'i64s',
196
+ 'u8s', 'u16s', 'u32s', 'u64s',
197
+ 'bools',
198
+ ),
199
+
200
+ mask_type: _ => 'mask',
201
+ pack_type: $ => seq('pack', field('schema', $.type_identifier)),
202
+ stack_type: $ => seq('stack', field('schema', $.type_identifier)),
203
+ array_type: $ => seq('[', field('count', $.integer_literal), ']', field('element', $.type)),
204
+ view_type: $ => seq('[', ']', field('element', $.type)),
205
+ pointer_type: $ => seq('ptr', field('target', $.type)),
206
+ mutable_type: $ => seq('mut', field('target', $.type)),
207
+
208
+ // A body: a line ending in ':' followed by indented statements.
209
+ _block: $ => seq(':', $._newline, $._indent, repeat1($._statement), $._dedent),
210
+
211
+ _statement: $ => choice(
212
+ seq($.block_comment, optional($._newline)),
213
+ seq($._simple_statement, $._newline),
214
+ $._compound_statement,
215
+ ),
216
+
217
+ _simple_statement: $ => choice(
218
+ $.let_statement,
219
+ $.uniform_binding,
220
+ $.fused_binding,
221
+ $.mutable_binding,
222
+ $.assignment_statement,
223
+ $.return_statement,
224
+ $.yield_statement,
225
+ $.break_statement,
226
+ $.continue_statement,
227
+ $.expression_statement,
228
+ ),
229
+
230
+ _compound_statement: $ => choice(
231
+ $.if_statement,
232
+ $.while_statement,
233
+ $.traversal_statement,
234
+ $.for_statement,
235
+ $.repeat_statement,
236
+ ),
237
+
238
+ let_statement: $ => seq(
239
+ 'let',
240
+ field('name', $.identifier),
241
+ optional(seq(':', field('type', $.type))),
242
+ '=',
243
+ field('value', $.expression),
244
+ ),
245
+
246
+ uniform_binding: $ => seq(
247
+ 'let',
248
+ '<',
249
+ field('name', alias($.identifier, $.scalar_name)),
250
+ ':',
251
+ field('type', $.type),
252
+ '>',
253
+ '=',
254
+ field('value', $.expression),
255
+ ),
256
+
257
+ fused_binding: $ => seq(
258
+ '|',
259
+ field('name', $.identifier),
260
+ optional(seq(':', field('type', $.type))),
261
+ '<|',
262
+ field('value', $.expression),
263
+ ),
264
+
265
+ mutable_binding: $ => choice(
266
+ seq(
267
+ field('name', $.identifier),
268
+ optional(seq(':', field('type', $.type))),
269
+ ':=',
270
+ field('value', $.expression),
271
+ ),
272
+ seq(
273
+ '(',
274
+ field('name', $.identifier),
275
+ ':',
276
+ field('type', $.type),
277
+ ')',
278
+ ':=',
279
+ field('value', $.expression),
280
+ ),
281
+ ),
282
+
283
+ assignment_statement: $ => seq(
284
+ field('target', $._postfix_expression),
285
+ '<-',
286
+ field('value', $.expression),
287
+ ),
288
+
289
+ expression_statement: $ => $.expression,
290
+
291
+ return_statement: $ => seq('return', optional(field('value', $.expression))),
292
+ yield_statement: $ => seq('yield', field('value', $.expression)),
293
+ break_statement: _ => 'break',
294
+ continue_statement: _ => 'continue',
295
+
296
+ if_statement: $ => seq(
297
+ 'if',
298
+ field('condition', $.expression),
299
+ $._block,
300
+ optional($.else_clause),
301
+ ),
302
+
303
+ else_clause: $ => seq('else', choice($._block, $.if_statement)),
304
+
305
+ while_statement: $ => seq('while', field('condition', $.expression), $._block),
306
+
307
+ traversal_statement: $ => seq(
308
+ 'for',
309
+ field('binding', $.identifier),
310
+ 'in',
311
+ field('pack', $.identifier),
312
+ 'using',
313
+ field('domain', $.rack_type),
314
+ 'up',
315
+ 'to',
316
+ field('count', $._simple_value),
317
+ $._block,
318
+ ),
319
+
320
+ for_statement: $ => seq(
321
+ 'for',
322
+ field('variable', $._loop_variable),
323
+ 'from',
324
+ field('start', $.expression),
325
+ 'up',
326
+ 'to',
327
+ field('end', $.expression),
328
+ optional(seq('by', field('step', $.expression))),
329
+ $._block,
330
+ ),
331
+
332
+ repeat_statement: $ => seq(
333
+ 'repeat',
334
+ field('variable', $._loop_variable),
335
+ 'from',
336
+ field('start', $.expression),
337
+ 'up',
338
+ 'to',
339
+ field('end', $.expression),
340
+ $._block,
341
+ ),
342
+
343
+ _loop_variable: $ => choice($.identifier, $.scalar_variable),
344
+
345
+ scalar_variable: $ => seq(
346
+ '<',
347
+ field('name', alias($.identifier, $.scalar_name)),
348
+ ':',
349
+ field('type', $.type),
350
+ '>',
351
+ ),
352
+
353
+ tine_declaration: $ => seq(
354
+ 'tine',
355
+ field('name', $.tine),
356
+ 'when',
357
+ field('condition', $.predicate),
358
+ $._newline,
359
+ ),
360
+
361
+ predicate: $ => choice(
362
+ prec.left(1, seq($.predicate, 'or', $.predicate)),
363
+ prec.left(2, seq($.predicate, 'and', $.predicate)),
364
+ prec.right(3, seq('not', $.predicate)),
365
+ prec.left(4, seq(
366
+ $.predicate_arithmetic,
367
+ choice('<', '<=', '>', '>=', '=', '!='),
368
+ $.predicate_arithmetic,
369
+ )),
370
+ $.tine,
371
+ seq('(', $.predicate, ')'),
372
+ ),
373
+
374
+ predicate_arithmetic: $ => choice(
375
+ prec.left(5, seq($.predicate_arithmetic, choice('+', '-'), $.predicate_arithmetic)),
376
+ prec.left(6, seq($.predicate_arithmetic, choice('*', '/', '%'), $.predicate_arithmetic)),
377
+ prec.right(7, seq('-', $.predicate_arithmetic)),
378
+ $.predicate_atom,
379
+ ),
380
+
381
+ predicate_atom: $ => choice(
382
+ $.identifier,
383
+ $.integer_literal,
384
+ $.float_literal,
385
+ $.boolean_literal,
386
+ $.scalar_expression,
387
+ prec.left(9, seq($.predicate_atom, '.', $.identifier)),
388
+ seq('(', $.predicate_arithmetic, ')'),
389
+ ),
390
+
391
+ through_statement: $ => seq(
392
+ 'through',
393
+ field('mask', choice($.tine, seq('(', $.predicate, ')'))),
394
+ 'else',
395
+ field('passthrough', $._simple_value),
396
+ 'into',
397
+ field('name', $.identifier),
398
+ ':',
399
+ $._newline,
400
+ $._indent,
401
+ repeat(seq(choice($.let_statement, $.fused_binding), $._newline)),
402
+ field('value', $.expression),
403
+ $._newline,
404
+ $._dedent,
405
+ ),
406
+
407
+ _simple_value: $ => choice(
408
+ $.scalar_expression,
409
+ $.integer_literal,
410
+ $.float_literal,
411
+ $.boolean_literal,
412
+ ),
413
+
414
+ return_sweep_statement: $ => seq(
415
+ 'return',
416
+ 'sweep',
417
+ ':',
418
+ $._newline,
419
+ $._indent,
420
+ repeat1($.sweep_arm),
421
+ $._dedent,
422
+ ),
423
+
424
+ sweep_arm: $ => seq(
425
+ '|',
426
+ field('selector', choice($.tine, '_')),
427
+ '=>',
428
+ field('value', $.expression),
429
+ $._newline,
430
+ ),
431
+
432
+ expression: $ => choice(
433
+ $.conditional_expression,
434
+ $.binary_expression,
435
+ $.unary_expression,
436
+ $._postfix_expression,
437
+ ),
438
+
439
+ _postfix_expression: $ => choice(
440
+ $.field_expression,
441
+ $.index_expression,
442
+ $.shuffle_expression,
443
+ $.static_move_expression,
444
+ $.call_expression,
445
+ $.conversion_expression,
446
+ $.record_expression,
447
+ $.array_expression,
448
+ $.scalar_expression,
449
+ $.tine,
450
+ $.primary_expression,
451
+ ),
452
+
453
+ conditional_expression: $ => prec.right(PREC.conditional, seq(
454
+ 'if',
455
+ field('condition', $.expression),
456
+ 'then',
457
+ field('consequence', $.expression),
458
+ 'else',
459
+ field('alternative', $.expression),
460
+ )),
461
+
462
+ binary_expression: $ => choice(
463
+ prec.left(PREC.or, seq($.expression, 'or', $.expression)),
464
+ prec.left(PREC.and, seq($.expression, 'and', $.expression)),
465
+ prec.left(PREC.compare, seq($.expression, choice('<', '<=', '>', '>=', '=', '!='), $.expression)),
466
+ prec.left(PREC.add, seq($.expression, choice('+', '-'), $.expression)),
467
+ prec.left(PREC.multiply, seq($.expression, choice('*', '/', '%'), $.expression)),
468
+ ),
469
+
470
+ unary_expression: $ => prec.right(PREC.unary, seq(choice('-', 'not'), $.expression)),
471
+
472
+ call_expression: $ => prec(PREC.call, seq(
473
+ field('function', choice($.identifier, 'fma')),
474
+ '(',
475
+ commaSep($.expression),
476
+ ')',
477
+ )),
478
+
479
+ // i32(x) checks the value fits; wrap(u8, x) keeps the low bits;
480
+ // bitcast(u32, x) reinterprets an equal-width value.
481
+ conversion_expression: $ => prec(PREC.call, choice(
482
+ seq(field('type', $.storage_type), '(', field('value', $.expression), ')'),
483
+ seq(
484
+ field('kind', choice('wrap', 'bitcast')),
485
+ '(',
486
+ field('type', $.type),
487
+ ',',
488
+ field('value', $.expression),
489
+ ')',
490
+ ),
491
+ )),
492
+
493
+ record_expression: $ => seq(
494
+ field('record', $.type_identifier),
495
+ '{',
496
+ commaSep($.field_initializer),
497
+ '}',
498
+ ),
499
+
500
+ field_initializer: $ => seq(
501
+ field('field', $.identifier),
502
+ ':',
503
+ field('value', $.expression),
504
+ ),
505
+
506
+ array_expression: $ => choice(
507
+ seq('[', commaSep1($.expression), ']'),
508
+ seq('[', field('value', $.expression), ';', field('count', $.integer_literal), ']'),
509
+ ),
510
+
511
+ shuffle_expression: $ => prec(PREC.static_call, seq(
512
+ 'shuffle',
513
+ '(',
514
+ field('value', $.expression),
515
+ ',',
516
+ optional(seq(field('second_value', $.expression), ',')),
517
+ '[',
518
+ commaSep1(field('index', $.integer_literal)),
519
+ ']',
520
+ ')',
521
+ )),
522
+
523
+ static_move_expression: $ => prec(PREC.static_call, seq(
524
+ field('function', choice(
525
+ 'shift_left', 'shift_right', 'rotate_left', 'rotate_right',
526
+ )),
527
+ '(',
528
+ field('value', $.expression),
529
+ ',',
530
+ field('amount', $.integer_literal),
531
+ ')',
532
+ )),
533
+
534
+ field_expression: $ => prec.left(PREC.postfix, seq(
535
+ field('value', $._postfix_expression),
536
+ '.',
537
+ field('field', $.identifier),
538
+ )),
539
+
540
+ index_expression: $ => prec.left(PREC.postfix, seq(
541
+ field('value', $._postfix_expression),
542
+ '[',
543
+ optional('unchecked'),
544
+ field('index', $.expression),
545
+ ']',
546
+ )),
547
+
548
+ scalar_expression: $ => seq(
549
+ '<',
550
+ field('value', $.scalar_value),
551
+ '>',
552
+ ),
553
+
554
+ scalar_value: $ => choice(
555
+ $.identifier,
556
+ $.integer_literal,
557
+ $.float_literal,
558
+ $.boolean_literal,
559
+ seq('-', choice($.integer_literal, $.float_literal)),
560
+ prec.left(PREC.postfix, seq($.scalar_value, '.', $.identifier)),
561
+ prec.left(PREC.postfix, seq($.scalar_value, '[', optional('unchecked'), $.expression, ']')),
562
+ ),
563
+
564
+ tine: $ => seq(
565
+ '#',
566
+ alias(token.immediate(/[a-zA-Z_][a-zA-Z0-9_]*/), $.tine_name),
567
+ ),
568
+
569
+ primary_expression: $ => choice(
570
+ $.identifier,
571
+ $.integer_literal,
572
+ $.float_literal,
573
+ $.boolean_literal,
574
+ $.string_literal,
575
+ $.lane_index,
576
+ $.lanes,
577
+ seq('(', $.expression, ')'),
578
+ ),
579
+
580
+ // An identifier starting in upper case is a type name, as in the compiler's lexer.
581
+ identifier: _ => /[a-z_][a-zA-Z0-9_]*/,
582
+ type_identifier: _ => /[A-Z][a-zA-Z0-9_]*/,
583
+ integer_literal: _ => /0x[0-9a-fA-F]+|[0-9]+/,
584
+ float_literal: _ => /([0-9]+\.[0-9]*([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)/,
585
+ string_literal: _ => /"([^"\\\n]|\\.)*"/,
586
+ boolean_literal: _ => choice('true', 'false'),
587
+ lane_index: _ => '@',
588
+ lanes: _ => 'lanes',
589
+ },
590
+ });
591
+
592
+ function commaSep(rule) {
593
+ return optional(commaSep1(rule));
594
+ }
595
+
596
+ function commaSep1(rule) {
597
+ return seq(rule, repeat(seq(',', rule)));
598
+ }
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "tree-sitter-rake",
3
+ "version": "0.4.0-beta",
4
+ "description": "Tree-sitter grammar for Rake, a vector-first SIMD language",
5
+ "main": "bindings/node",
6
+ "types": "bindings/node",
7
+ "type": "module",
8
+ "files": [
9
+ "binding.gyp",
10
+ "bindings/node",
11
+ "grammar.js",
12
+ "queries",
13
+ "src"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/rakelang/tree-sitter-rake.git"
18
+ },
19
+ "keywords": [
20
+ "tree-sitter",
21
+ "rake",
22
+ "simd",
23
+ "vector",
24
+ "parser"
25
+ ],
26
+ "author": "Kieran Rosenberg",
27
+ "license": "MIT",
28
+ "dependencies": {
29
+ "node-addon-api": "^8.3.1",
30
+ "node-gyp-build": "^4.8.4"
31
+ },
32
+ "devDependencies": {
33
+ "tree-sitter": "^0.25.1",
34
+ "tree-sitter-cli": "^0.26.8"
35
+ },
36
+ "scripts": {
37
+ "build": "tree-sitter generate",
38
+ "test": "tree-sitter generate && tree-sitter test && node --test bindings/node/binding_test.js",
39
+ "test:differential": "bash ../rake/test/parser_differential.sh",
40
+ "parse": "tree-sitter parse"
41
+ },
42
+ "tree-sitter": [
43
+ {
44
+ "scope": "source.rake",
45
+ "file-types": [
46
+ "rk"
47
+ ],
48
+ "injection-regex": "^rake$",
49
+ "highlights": "queries/highlights.scm"
50
+ }
51
+ ],
52
+ "allowScripts": {
53
+ "tree-sitter@0.25.1": true,
54
+ "tree-sitter-cli@0.26.13": true
55
+ }
56
+ }