tree-sitter-bynk 0.447.0 → 0.492.1
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 +330 -41
- package/package.json +2 -2
- package/queries/highlights.scm +19 -0
- package/src/grammar.json +1615 -303
- package/src/node-types.json +1246 -154
- package/src/parser.c +123995 -81148
- package/src/scanner.c +89 -2
package/grammar.js
CHANGED
|
@@ -39,7 +39,7 @@ const PREC = {
|
|
|
39
39
|
module.exports = grammar({
|
|
40
40
|
name: "bynk",
|
|
41
41
|
|
|
42
|
-
externals: ($) => [$.doc_block, $.doc_line],
|
|
42
|
+
externals: ($) => [$.doc_block, $.doc_line, $.raw_string, $._type_app_open, $._error_sentinel],
|
|
43
43
|
|
|
44
44
|
extras: ($) => [/\s+/, $.doc_line, $.line_comment, $.doc_block],
|
|
45
45
|
|
|
@@ -48,6 +48,10 @@ module.exports = grammar({
|
|
|
48
48
|
word: ($) => $.identifier,
|
|
49
49
|
|
|
50
50
|
conflicts: ($) => [
|
|
51
|
+
// #2654: `let (T { … })` is a parenthesised pattern either way; only the
|
|
52
|
+
// end of the statement (an `else` or none) says whether the record
|
|
53
|
+
// pattern stood alone.
|
|
54
|
+
[$._pattern, $._let_paren_record_pattern],
|
|
51
55
|
// `match e { … }` / `if e { … }`: after a bare identifier `e`,
|
|
52
56
|
// the `{` is ambiguous between opening the match/if body and opening a
|
|
53
57
|
// record construction/spread `e { … }`. Keep all parses alive; the body
|
|
@@ -58,6 +62,10 @@ module.exports = grammar({
|
|
|
58
62
|
// parenthesised expression (and `()` the unit literal) until the
|
|
59
63
|
// closing `)` is followed — or not — by `=>`.
|
|
60
64
|
[$.lambda_param, $._primary],
|
|
65
|
+
// #2712: `(T { f, …` opens a record construction or a record-pattern lambda
|
|
66
|
+
// parameter; the pattern's mandatory `..` (never an expression) settles it.
|
|
67
|
+
[$.field_init, $._lambda_record_field],
|
|
68
|
+
[$._primary, $._lambda_field_binding],
|
|
61
69
|
[$._primary, $.lambda_expr],
|
|
62
70
|
// v0.145: a match-arm `if`-guard is an `_expression` immediately followed by
|
|
63
71
|
// the arm's `=>`. When the guard opens with `(`, one token can't tell a unit
|
|
@@ -208,6 +216,7 @@ module.exports = grammar({
|
|
|
208
216
|
$.event_decl,
|
|
209
217
|
$.asset_decl,
|
|
210
218
|
$.embed_decl,
|
|
219
|
+
$.const_decl,
|
|
211
220
|
),
|
|
212
221
|
|
|
213
222
|
_context_body_item: ($) =>
|
|
@@ -226,6 +235,7 @@ module.exports = grammar({
|
|
|
226
235
|
$.event_decl,
|
|
227
236
|
$.asset_decl,
|
|
228
237
|
$.embed_decl,
|
|
238
|
+
$.const_decl,
|
|
229
239
|
$.removed_agent_decl,
|
|
230
240
|
),
|
|
231
241
|
|
|
@@ -251,6 +261,7 @@ module.exports = grammar({
|
|
|
251
261
|
$.event_decl,
|
|
252
262
|
$.asset_decl,
|
|
253
263
|
$.embed_decl,
|
|
264
|
+
$.const_decl,
|
|
254
265
|
),
|
|
255
266
|
|
|
256
267
|
_test_body_item: ($) =>
|
|
@@ -324,17 +335,49 @@ module.exports = grammar({
|
|
|
324
335
|
"}",
|
|
325
336
|
),
|
|
326
337
|
|
|
338
|
+
// -- Type parameters and bounds (constrained generics slice 0) --
|
|
339
|
+
|
|
340
|
+
// `T` or `T: Eq + C`. The constraint names are validated by the checker.
|
|
341
|
+
type_param: ($) =>
|
|
342
|
+
seq(
|
|
343
|
+
field("name", $.identifier),
|
|
344
|
+
optional(seq(":", sep1($.constraint, "+"))),
|
|
345
|
+
),
|
|
346
|
+
|
|
347
|
+
constraint: ($) => $.identifier,
|
|
348
|
+
|
|
349
|
+
where_clause: ($) => seq("where", sep1($.where_bound, ",")),
|
|
350
|
+
|
|
351
|
+
where_bound: ($) =>
|
|
352
|
+
seq(
|
|
353
|
+
field("param", $.identifier),
|
|
354
|
+
":",
|
|
355
|
+
sep1($.constraint, "+"),
|
|
356
|
+
),
|
|
357
|
+
|
|
327
358
|
// -- Type declarations --
|
|
328
359
|
|
|
360
|
+
// #2618: `private` before a `fn`, `type`, `messages`, `asset`, `embed` or
|
|
361
|
+
// `const` declaration makes it unit-private. The word is contextual: with
|
|
362
|
+
// `word` set to `identifier`, it lexes as a keyword only where a
|
|
363
|
+
// declaration may start, so `@cache(scope: private)` and a binding named
|
|
364
|
+
// `private` keep parsing as identifiers. Placement (a commons or context, never an
|
|
365
|
+
// adapter) is the compiler's call (`bynk.visibility.private_not_allowed`).
|
|
366
|
+
visibility_modifier: ($) => "private",
|
|
367
|
+
|
|
329
368
|
type_decl: ($) =>
|
|
330
369
|
seq(
|
|
370
|
+
optional(field("visibility", $.visibility_modifier)),
|
|
331
371
|
"type",
|
|
332
372
|
field("name", $.identifier),
|
|
333
373
|
// v0.157 (ADR 0183): optional `[A, B]` type parameters — only a record
|
|
334
374
|
// body may be generic (enforced by the checker, not the grammar).
|
|
335
|
-
optional(seq("[", sep1(field("type_param", $.
|
|
375
|
+
optional(seq("[", sep1(field("type_param", $.type_param), ","), "]")),
|
|
336
376
|
"=",
|
|
337
377
|
field("body", $._type_body),
|
|
378
|
+
// Constrained generics slice 1: a trailing `derives Ord` clause, `+`
|
|
379
|
+
// separated like a bound list. `derives` is a contextual word.
|
|
380
|
+
optional(seq("derives", sep1(field("derive", $.constraint), "+"))),
|
|
338
381
|
),
|
|
339
382
|
|
|
340
383
|
_type_body: ($) =>
|
|
@@ -404,6 +447,7 @@ module.exports = grammar({
|
|
|
404
447
|
// (`bynk.asset.outside_context_or_commons` rejects it in an adapter).
|
|
405
448
|
asset_decl: ($) =>
|
|
406
449
|
seq(
|
|
450
|
+
optional(field("visibility", $.visibility_modifier)),
|
|
407
451
|
"asset",
|
|
408
452
|
field("name", $.identifier),
|
|
409
453
|
"=",
|
|
@@ -419,12 +463,31 @@ module.exports = grammar({
|
|
|
419
463
|
// rejects it in an adapter).
|
|
420
464
|
embed_decl: ($) =>
|
|
421
465
|
seq(
|
|
466
|
+
optional(field("visibility", $.visibility_modifier)),
|
|
422
467
|
"embed",
|
|
423
468
|
field("name", $.identifier),
|
|
424
469
|
"=",
|
|
425
470
|
field("path", $.string_literal),
|
|
426
471
|
),
|
|
427
472
|
|
|
473
|
+
// #2617 (named constants): `const Name: Type = <static expression>` — a
|
|
474
|
+
// named value. Admitted in every body like `embed`; placement
|
|
475
|
+
// (`bynk.resolve.const_outside_context_or_commons`), the name's case
|
|
476
|
+
// (`bynk.resolve.const_name_case`, upper-camel like `constant_name`) and
|
|
477
|
+
// the initialiser's static-ness are checker concerns. The name is an
|
|
478
|
+
// `identifier` because `word` unifies every word-shaped lexeme to it.
|
|
479
|
+
// A leading `private` makes it unit-private, as on `embed`.
|
|
480
|
+
const_decl: ($) =>
|
|
481
|
+
seq(
|
|
482
|
+
optional(field("visibility", $.visibility_modifier)),
|
|
483
|
+
"const",
|
|
484
|
+
field("name", $.identifier),
|
|
485
|
+
":",
|
|
486
|
+
field("type", $._type_ref),
|
|
487
|
+
"=",
|
|
488
|
+
field("value", $._expression),
|
|
489
|
+
),
|
|
490
|
+
|
|
428
491
|
// v0.154 (ADR 0178): a sum body may carry a trailing `embeds E as V, …`
|
|
429
492
|
// clause declaring error embeddings the `?` operator auto-converts.
|
|
430
493
|
// `embeds`/`as` are contextual — matched only in this position.
|
|
@@ -507,12 +570,22 @@ module.exports = grammar({
|
|
|
507
570
|
choice(
|
|
508
571
|
seq(optional("-"), $.number_literal),
|
|
509
572
|
seq(optional("-"), $.float_literal),
|
|
573
|
+
seq(optional("-"), $.decimal_literal),
|
|
510
574
|
$.string_literal,
|
|
511
575
|
),
|
|
512
576
|
|
|
513
577
|
_base_type: ($) => $.base_type,
|
|
514
578
|
base_type: () =>
|
|
515
|
-
choice(
|
|
579
|
+
choice(
|
|
580
|
+
"Int",
|
|
581
|
+
"String",
|
|
582
|
+
"Bool",
|
|
583
|
+
"Float",
|
|
584
|
+
"Duration",
|
|
585
|
+
"Instant",
|
|
586
|
+
"Bytes",
|
|
587
|
+
"Decimal",
|
|
588
|
+
),
|
|
516
589
|
|
|
517
590
|
_type_ref: ($) =>
|
|
518
591
|
choice(
|
|
@@ -617,15 +690,19 @@ module.exports = grammar({
|
|
|
617
690
|
|
|
618
691
|
fn_decl: ($) =>
|
|
619
692
|
seq(
|
|
693
|
+
optional(field("visibility", $.visibility_modifier)),
|
|
620
694
|
"fn",
|
|
621
695
|
field("name", choice($.method_name, $.identifier)),
|
|
622
696
|
// v0.20a: optional `[A, B]` type parameters (functions only).
|
|
623
|
-
optional(seq("[", sep1(field("type_param", $.
|
|
697
|
+
optional(seq("[", sep1(field("type_param", $.type_param), ","), "]")),
|
|
624
698
|
"(",
|
|
625
699
|
optional($._params),
|
|
626
700
|
")",
|
|
627
701
|
"->",
|
|
628
702
|
field("return_type", $._type_ref),
|
|
703
|
+
// Constrained generics slice 0: a method's `where A: Eq` clause bounds
|
|
704
|
+
// a receiver type's parameter.
|
|
705
|
+
optional($.where_clause),
|
|
629
706
|
// v0.115: contract clauses between the return type and the body.
|
|
630
707
|
repeat($.requires_clause),
|
|
631
708
|
repeat($.ensures_clause),
|
|
@@ -681,7 +758,7 @@ module.exports = grammar({
|
|
|
681
758
|
// #926: optional `[T, …]` type parameters on the op itself — resolved
|
|
682
759
|
// only from an explicit type argument at the call site (mirroring
|
|
683
760
|
// `fn_decl`'s own `[A, B]` slot, `grammar.js:525`).
|
|
684
|
-
optional(seq("[", sep1(field("type_param", $.
|
|
761
|
+
optional(seq("[", sep1(field("type_param", $.type_param), ","), "]")),
|
|
685
762
|
"(",
|
|
686
763
|
optional(sep1($.param, ",")),
|
|
687
764
|
optional(","),
|
|
@@ -701,6 +778,7 @@ module.exports = grammar({
|
|
|
701
778
|
// mirroring `service_decl`/`agent_decl`'s existing permissive placement.
|
|
702
779
|
messages_decl: ($) =>
|
|
703
780
|
seq(
|
|
781
|
+
optional(field("visibility", $.visibility_modifier)),
|
|
704
782
|
"messages",
|
|
705
783
|
field("tag", $.string_literal),
|
|
706
784
|
repeat(field("annotation", $.store_annotation)),
|
|
@@ -865,14 +943,21 @@ module.exports = grammar({
|
|
|
865
943
|
// than nested inside it. Nested inside the `Events` choice arm, not a
|
|
866
944
|
// free-standing clause any protocol could carry — `via` on `http`/
|
|
867
945
|
// `cron`/`queue`/`websocket` is a syntax error, not a checker
|
|
868
|
-
// diagnostic.
|
|
869
|
-
//
|
|
946
|
+
// diagnostic. A literal, an integer range (`via schema(2..)`, #990 —
|
|
947
|
+
// the same `int_range` a match pattern uses, #2699) or `_`.
|
|
870
948
|
schema_dispatch_clause: ($) =>
|
|
871
949
|
seq(
|
|
872
950
|
"via",
|
|
873
951
|
"schema",
|
|
874
952
|
"(",
|
|
875
|
-
field(
|
|
953
|
+
field(
|
|
954
|
+
"version",
|
|
955
|
+
choice(
|
|
956
|
+
$.int_range,
|
|
957
|
+
seq(optional("-"), $.number_literal),
|
|
958
|
+
$.wildcard_pattern,
|
|
959
|
+
),
|
|
960
|
+
),
|
|
876
961
|
")",
|
|
877
962
|
),
|
|
878
963
|
event_pattern_field: ($) =>
|
|
@@ -1239,8 +1324,9 @@ module.exports = grammar({
|
|
|
1239
1324
|
// v0.118 (testing track slice 6): a test-scope stub for one capability
|
|
1240
1325
|
// operation — `stub Cap.op(<arg pattern>, …) <rhs>`. Only admitted inside a
|
|
1241
1326
|
// suite/case body. An arg pattern is `_` (any) or a value expression; the
|
|
1242
|
-
// right-hand side is `returns <expr
|
|
1243
|
-
// scripted sequence, where an outcome is `fails` or an expr),
|
|
1327
|
+
// right-hand side is `returns <expr> [after <expr>]`, `returns each [ <outcome>, … ]`
|
|
1328
|
+
// (a scripted sequence, where an outcome is `fails` or an expr), `fails`, or
|
|
1329
|
+
// `never`.
|
|
1244
1330
|
// `returns`/`each`/`fails` are contextual words. Keyword `stub` since the
|
|
1245
1331
|
// keyword-hygiene batch (#548); formerly a pun on `provides`.
|
|
1246
1332
|
stub_clause: ($) =>
|
|
@@ -1270,8 +1356,16 @@ module.exports = grammar({
|
|
|
1270
1356
|
),
|
|
1271
1357
|
"]",
|
|
1272
1358
|
),
|
|
1273
|
-
|
|
1359
|
+
// #2683: `returns <v> after <d>` completes on the test clock once
|
|
1360
|
+
// `d` has passed; `never` does not complete. `after` and `never` are
|
|
1361
|
+
// contextual words.
|
|
1362
|
+
seq(
|
|
1363
|
+
"returns",
|
|
1364
|
+
field("value", $._expression),
|
|
1365
|
+
optional(seq("after", field("after", $._expression))),
|
|
1366
|
+
),
|
|
1274
1367
|
"fails",
|
|
1368
|
+
"never",
|
|
1275
1369
|
),
|
|
1276
1370
|
),
|
|
1277
1371
|
// #2134: a suite- or case-scoped `env { NAME = "value" … }` clause — the
|
|
@@ -1343,6 +1437,7 @@ module.exports = grammar({
|
|
|
1343
1437
|
$.do_stmt,
|
|
1344
1438
|
$.assign_stmt,
|
|
1345
1439
|
$.advance_stmt,
|
|
1440
|
+
$.par_stmt,
|
|
1346
1441
|
prec(1, $.expect_expr),
|
|
1347
1442
|
),
|
|
1348
1443
|
|
|
@@ -1374,28 +1469,50 @@ module.exports = grammar({
|
|
|
1374
1469
|
// lenient (a bare-name `variant_pattern` is admitted) because the compiler,
|
|
1375
1470
|
// not the highlighter, reports `bynk.parse.let_else_on_binding`.
|
|
1376
1471
|
let_else_stmt: ($) =>
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1472
|
+
choice(
|
|
1473
|
+
seq(
|
|
1474
|
+
"let",
|
|
1475
|
+
field("pattern", choice($._let_pattern, alias($._let_or_pattern, $.or_pattern))),
|
|
1476
|
+
field("bind", choice("=", "<-")),
|
|
1477
|
+
field("value", $._expression),
|
|
1478
|
+
optional(field("principal", $.call_site_actor)),
|
|
1479
|
+
"else",
|
|
1480
|
+
field("else", choice($.block, $.let_else_match)),
|
|
1481
|
+
),
|
|
1482
|
+
// #2654 (patterns track, slice 2): `let Item { sku, .. } = item` — the
|
|
1483
|
+
// `else` is optional when the pattern is a record pattern (the compiler further
|
|
1484
|
+
// requires it to be irrefutable, `let_pattern_without_else`; whether a
|
|
1485
|
+
// field's sub-pattern is a binding or a variant is a matter of
|
|
1486
|
+
// capitalisation, which this grammar cannot see). Parentheses around
|
|
1487
|
+
// the pattern are transparent.
|
|
1488
|
+
seq(
|
|
1489
|
+
"let",
|
|
1490
|
+
field("pattern", choice($.record_pattern, alias($._let_paren_record_pattern, $.paren_pattern))),
|
|
1491
|
+
field("bind", choice("=", "<-")),
|
|
1492
|
+
field("value", $._expression),
|
|
1493
|
+
optional(field("principal", $.call_site_actor)),
|
|
1494
|
+
optional(seq("else", field("else", choice($.block, $.let_else_match)))),
|
|
1495
|
+
),
|
|
1385
1496
|
),
|
|
1497
|
+
_let_paren_record_pattern: ($) => seq("(", $.record_pattern, ")"),
|
|
1386
1498
|
// #2010: the patterns that may open a `let … else`, mirroring the Rust
|
|
1387
1499
|
// parser's `let_pattern_ahead`: a literal, a parenthesised pattern, or a
|
|
1388
1500
|
// variant with a payload or a qualifier. A bare name stays a binding (and
|
|
1389
1501
|
// a bare `_` a discard), so `let x = …` is never ambiguous here.
|
|
1390
1502
|
_let_pattern: ($) =>
|
|
1391
1503
|
choice(
|
|
1504
|
+
$.int_range,
|
|
1392
1505
|
$.literal_pattern,
|
|
1393
1506
|
$.paren_pattern,
|
|
1507
|
+
$.list_pattern,
|
|
1394
1508
|
alias($._let_variant_pattern, $.variant_pattern),
|
|
1395
1509
|
),
|
|
1396
1510
|
// `let Ok(x) | Err(x) = …`: an or-chain whose first alternative opens a
|
|
1397
1511
|
// pattern; the rest are any patterns.
|
|
1398
|
-
|
|
1512
|
+
// #2654: a record pattern may open the chain too (`let Item { .. } | …`),
|
|
1513
|
+
// though on its own it is the `else`-less alternative of `let_else_stmt`.
|
|
1514
|
+
_let_or_pattern: ($) =>
|
|
1515
|
+
prec.left(1, seq(choice($._let_pattern, $.record_pattern), "|", $._pattern)),
|
|
1399
1516
|
_let_variant_pattern: ($) => {
|
|
1400
1517
|
const payload = seq("(", optional(sep1($._pattern_binding, ",")), optional(","), ")");
|
|
1401
1518
|
return prec.right(
|
|
@@ -1456,6 +1573,28 @@ module.exports = grammar({
|
|
|
1456
1573
|
field("amount", $._expression),
|
|
1457
1574
|
),
|
|
1458
1575
|
|
|
1576
|
+
// #2640 (concurrent effects, slice 0): `par { let a <- e1 let b <- e2 }` —
|
|
1577
|
+
// issue every effect, then wait for them all. `par` is contextual: it opens
|
|
1578
|
+
// a statement only before `{`. The grammar stays permissive about the
|
|
1579
|
+
// block's contents (any statement parses); the compiler admits only
|
|
1580
|
+
// `let x <- e` and `do e` (`bynk.par.invalid_statement`).
|
|
1581
|
+
par_stmt: ($) => seq("par", "{", repeat($._par_statement), "}"),
|
|
1582
|
+
|
|
1583
|
+
// Any statement but `let … else`, which would take the rest of the block as
|
|
1584
|
+
// its arm and so has no room inside a `par` (the compiler's parser refuses
|
|
1585
|
+
// it with `bynk.par.invalid_statement`).
|
|
1586
|
+
_par_statement: ($) =>
|
|
1587
|
+
choice(
|
|
1588
|
+
$.let_stmt,
|
|
1589
|
+
$.effect_let_stmt,
|
|
1590
|
+
$.effect_send_stmt,
|
|
1591
|
+
$.do_stmt,
|
|
1592
|
+
$.assign_stmt,
|
|
1593
|
+
$.advance_stmt,
|
|
1594
|
+
$.par_stmt,
|
|
1595
|
+
prec(1, $.expect_expr),
|
|
1596
|
+
),
|
|
1597
|
+
|
|
1459
1598
|
// A let/effect-let may bind the discard name `_`.
|
|
1460
1599
|
_binding_name: ($) => choice($.identifier, alias("_", $.wildcard)),
|
|
1461
1600
|
|
|
@@ -1601,11 +1740,62 @@ module.exports = grammar({
|
|
|
1601
1740
|
_pattern: ($) =>
|
|
1602
1741
|
choice(
|
|
1603
1742
|
$.wildcard_pattern,
|
|
1743
|
+
$.int_range,
|
|
1604
1744
|
$.literal_pattern,
|
|
1605
1745
|
$.variant_pattern,
|
|
1746
|
+
$.record_pattern,
|
|
1747
|
+
$.list_pattern,
|
|
1606
1748
|
$.or_pattern,
|
|
1607
1749
|
$.paren_pattern,
|
|
1608
1750
|
),
|
|
1751
|
+
// #2641 (patterns track, slice 1): `Order { status: Paid, total, .. }`. Always
|
|
1752
|
+
// open, with the trailing `..` mandatory so that adding a field to the record
|
|
1753
|
+
// never breaks a pattern — the rule `event_pattern` already applies to
|
|
1754
|
+
// events. A field is a bare name (binding it to a local of the same name) or
|
|
1755
|
+
// `name: pattern`. After `is` a record pattern must be parenthesised (see
|
|
1756
|
+
// `_is_pattern`), because there the `{` would also open the `if`'s block.
|
|
1757
|
+
record_pattern: ($) =>
|
|
1758
|
+
seq(
|
|
1759
|
+
field("type", $.identifier),
|
|
1760
|
+
"{",
|
|
1761
|
+
repeat(seq($.record_pattern_field, ",")),
|
|
1762
|
+
"..",
|
|
1763
|
+
"}",
|
|
1764
|
+
),
|
|
1765
|
+
// #2680 (patterns track, slice 4): `[]`, `[p, …]`, `[p, …, ..]`,
|
|
1766
|
+
// `[p, …, ..rest]`. The rest marker is last and at most once; `..` takes a
|
|
1767
|
+
// name or nothing (a literal after it is reserved for range patterns, and
|
|
1768
|
+
// the compiler reports it). It needs no parentheses after `is`, where the
|
|
1769
|
+
// pattern closes at `]`.
|
|
1770
|
+
list_pattern: ($) =>
|
|
1771
|
+
seq(
|
|
1772
|
+
"[",
|
|
1773
|
+
repeat(seq($._pattern, ",")),
|
|
1774
|
+
optional(choice($._pattern, seq($.list_rest, optional(",")))),
|
|
1775
|
+
"]",
|
|
1776
|
+
),
|
|
1777
|
+
list_rest: ($) => seq("..", optional(field("name", $.identifier))),
|
|
1778
|
+
record_pattern_field: ($) =>
|
|
1779
|
+
choice(
|
|
1780
|
+
seq(field("name", $.identifier), ":", field("pattern", $._pattern)),
|
|
1781
|
+
field("name", $.identifier),
|
|
1782
|
+
),
|
|
1783
|
+
// #2641: the patterns an `is` accepts without parentheses — `_pattern`
|
|
1784
|
+
// without a record pattern at its tail, at the top level or as an
|
|
1785
|
+
// or-alternative. Parenthesised, a record pattern is allowed anywhere (the
|
|
1786
|
+
// hand-written parser's `is_pattern_tail` restriction).
|
|
1787
|
+
_is_base_pattern: ($) =>
|
|
1788
|
+
choice(
|
|
1789
|
+
$.wildcard_pattern,
|
|
1790
|
+
$.literal_pattern,
|
|
1791
|
+
$.variant_pattern,
|
|
1792
|
+
$.list_pattern,
|
|
1793
|
+
$.paren_pattern,
|
|
1794
|
+
),
|
|
1795
|
+
_is_pattern: ($) =>
|
|
1796
|
+
choice($._is_base_pattern, alias($._is_or_pattern, $.or_pattern)),
|
|
1797
|
+
_is_or_pattern: ($) =>
|
|
1798
|
+
prec.left(1, seq($._is_pattern, "|", $._is_base_pattern)),
|
|
1609
1799
|
// #474 §2.3.4: `p₁ | p₂ | … | pₙ` — an or-pattern, left-associative;
|
|
1610
1800
|
// matches if any alternative matches. `|` is a pattern-position operator
|
|
1611
1801
|
// only — not a valid expression operator, and lexically distinct from
|
|
@@ -1621,6 +1811,29 @@ module.exports = grammar({
|
|
|
1621
1811
|
// never nested, parenthesized, or one alternative of an outer `|`-chain).
|
|
1622
1812
|
paren_pattern: ($) => seq("(", $._pattern, ")"),
|
|
1623
1813
|
wildcard_pattern: () => "_",
|
|
1814
|
+
// #2699 (patterns track, slice 5; events slice 4b, #990): an inclusive
|
|
1815
|
+
// integer range — `lo..hi`, `lo..` or `..hi`, each bound an optionally
|
|
1816
|
+
// negative `Int` literal. One production shared by match patterns and
|
|
1817
|
+
// `via schema(...)`. A bare `..` is never a range (it is `list_rest`), and
|
|
1818
|
+
// `0..9` lexes as `number_literal ".." number_literal` since a float needs
|
|
1819
|
+
// a digit on both sides of its `.`.
|
|
1820
|
+
int_range: ($) => {
|
|
1821
|
+
// Spelled out in each position (not a shared rule), so the parser does
|
|
1822
|
+
// not have to reduce a bound before it can tell a range from a literal.
|
|
1823
|
+
const bound = seq(optional("-"), $.number_literal);
|
|
1824
|
+
return choice(
|
|
1825
|
+
// Right-associative: after `x is 5..` a `-` is the high bound's sign
|
|
1826
|
+
// (the hand-written parser reads it greedily), never a subtraction.
|
|
1827
|
+
prec.right(
|
|
1828
|
+
seq(
|
|
1829
|
+
field("lo", bound),
|
|
1830
|
+
"..",
|
|
1831
|
+
optional(field("hi", bound)),
|
|
1832
|
+
),
|
|
1833
|
+
),
|
|
1834
|
+
seq("..", field("hi", bound)),
|
|
1835
|
+
);
|
|
1836
|
+
},
|
|
1624
1837
|
// v0.130 §2.3.4: a literal pattern — an integer (optionally negated), a
|
|
1625
1838
|
// string, or a boolean. A closed set (ADR 0001); no `Float`, no `()`.
|
|
1626
1839
|
literal_pattern: ($) =>
|
|
@@ -1666,7 +1879,7 @@ module.exports = grammar({
|
|
|
1666
1879
|
is_expr: ($) =>
|
|
1667
1880
|
prec.left(
|
|
1668
1881
|
PREC.is,
|
|
1669
|
-
seq(field("value", $._expression), "is", field("pattern", $.
|
|
1882
|
+
seq(field("value", $._expression), "is", field("pattern", $._is_pattern)),
|
|
1670
1883
|
),
|
|
1671
1884
|
|
|
1672
1885
|
binary_expr: ($) =>
|
|
@@ -1709,6 +1922,7 @@ module.exports = grammar({
|
|
|
1709
1922
|
$.block,
|
|
1710
1923
|
$.number_literal,
|
|
1711
1924
|
$.float_literal,
|
|
1925
|
+
$.decimal_literal,
|
|
1712
1926
|
$.string_literal,
|
|
1713
1927
|
$.boolean_literal,
|
|
1714
1928
|
$.unit_literal,
|
|
@@ -1717,7 +1931,7 @@ module.exports = grammar({
|
|
|
1717
1931
|
$._contextual_identifier,
|
|
1718
1932
|
),
|
|
1719
1933
|
|
|
1720
|
-
// `trace` and `
|
|
1934
|
+
// `trace`, `advance` and `par` are contextual in the compiler — ordinary
|
|
1721
1935
|
// identifiers outside `trace(Cap.op)` / `advance Clock by …`. Here, as
|
|
1722
1936
|
// `word`-shaped literals, they are extracted as keyword tokens, and where an
|
|
1723
1937
|
// identifier and the keyword are both valid (an expression or statement
|
|
@@ -1725,7 +1939,8 @@ module.exports = grammar({
|
|
|
1725
1939
|
// `identifier` in exactly those positions. The next tokens decide: `advance`
|
|
1726
1940
|
// followed by an identifier can only open an `advance_stmt`, and `trace (`
|
|
1727
1941
|
// is a declared conflict that `trace_expr`'s dynamic precedence settles.
|
|
1728
|
-
_contextual_identifier: ($) =>
|
|
1942
|
+
_contextual_identifier: ($) =>
|
|
1943
|
+
alias(choice("trace", "advance", "par"), $.identifier),
|
|
1729
1944
|
|
|
1730
1945
|
// v0.20a: a lambda — `(params) => expr | block`. Conflicts with
|
|
1731
1946
|
// paren_expr/unit_literal until the `=>` disambiguates (GLR conflict
|
|
@@ -1739,11 +1954,44 @@ module.exports = grammar({
|
|
|
1739
1954
|
field("body", choice($._expression, $.block)),
|
|
1740
1955
|
),
|
|
1741
1956
|
|
|
1957
|
+
// #2712 (patterns track, slice 6): a parameter is a name with an optional
|
|
1958
|
+
// annotation, or an unannotated record pattern whose fields are bindings.
|
|
1742
1959
|
lambda_param: ($) =>
|
|
1960
|
+
choice(
|
|
1961
|
+
seq(
|
|
1962
|
+
field("name", choice($.identifier, $._contextual_identifier)),
|
|
1963
|
+
optional(seq(":", field("type", $._type_ref))),
|
|
1964
|
+
),
|
|
1965
|
+
field("pattern", alias($._lambda_record_pattern, $.record_pattern)),
|
|
1966
|
+
),
|
|
1967
|
+
// The irrefutable subset a lambda parameter admits: each field is a bare
|
|
1968
|
+
// name, `name: binding`, `name: _`, or a nested such pattern. (A bare
|
|
1969
|
+
// capitalised name is a variant, a refutable pattern the compiler reports.)
|
|
1970
|
+
_lambda_record_pattern: ($) =>
|
|
1743
1971
|
seq(
|
|
1744
|
-
field("
|
|
1745
|
-
|
|
1972
|
+
field("type", $.identifier),
|
|
1973
|
+
"{",
|
|
1974
|
+
repeat(seq(alias($._lambda_record_field, $.record_pattern_field), ",")),
|
|
1975
|
+
"..",
|
|
1976
|
+
"}",
|
|
1746
1977
|
),
|
|
1978
|
+
_lambda_record_field: ($) =>
|
|
1979
|
+
choice(
|
|
1980
|
+
seq(
|
|
1981
|
+
field("name", $.identifier),
|
|
1982
|
+
":",
|
|
1983
|
+
field(
|
|
1984
|
+
"pattern",
|
|
1985
|
+
choice(
|
|
1986
|
+
$._lambda_field_binding,
|
|
1987
|
+
$.wildcard_pattern,
|
|
1988
|
+
alias($._lambda_record_pattern, $.record_pattern),
|
|
1989
|
+
),
|
|
1990
|
+
),
|
|
1991
|
+
),
|
|
1992
|
+
field("name", $.identifier),
|
|
1993
|
+
),
|
|
1994
|
+
_lambda_field_binding: ($) => $.identifier,
|
|
1747
1995
|
|
|
1748
1996
|
paren_expr: ($) => seq("(", $._expression, ")"),
|
|
1749
1997
|
|
|
@@ -1760,7 +2008,7 @@ module.exports = grammar({
|
|
|
1760
2008
|
field("method", $.identifier),
|
|
1761
2009
|
// v0.22b: optional explicit type arguments on a qualified static —
|
|
1762
2010
|
// `Json.decode[T](…)` (same-line rule as `call` type application).
|
|
1763
|
-
optional(seq("[", sep1(field("type_arg", $._type_ref), ","), "]")),
|
|
2011
|
+
optional(seq(alias($._type_app_open, "["), sep1(field("type_arg", $._type_ref), ","), "]")),
|
|
1764
2012
|
"(",
|
|
1765
2013
|
optional(sep1(field("arg", $._expression), ",")),
|
|
1766
2014
|
optional(","),
|
|
@@ -1775,12 +2023,25 @@ module.exports = grammar({
|
|
|
1775
2023
|
),
|
|
1776
2024
|
|
|
1777
2025
|
call: ($) =>
|
|
1778
|
-
|
|
1779
|
-
|
|
2026
|
+
choice(
|
|
2027
|
+
prec.left(
|
|
2028
|
+
PREC.postfix,
|
|
2029
|
+
seq(
|
|
2030
|
+
field("name", choice($.identifier, $._contextual_identifier)),
|
|
2031
|
+
"(",
|
|
2032
|
+
optional(sep1(field("arg", $._expression), ",")),
|
|
2033
|
+
optional(","),
|
|
2034
|
+
")",
|
|
2035
|
+
),
|
|
2036
|
+
),
|
|
2037
|
+
// v0.20a: explicit type arguments — `name[T, U](…)`. The `[` is the
|
|
2038
|
+
// same-line external token (#2700), so a list-pattern arm on the next
|
|
2039
|
+
// line is never read as a type application.
|
|
1780
2040
|
seq(
|
|
1781
2041
|
field("name", choice($.identifier, $._contextual_identifier)),
|
|
1782
|
-
|
|
1783
|
-
|
|
2042
|
+
alias($._type_app_open, "["),
|
|
2043
|
+
sep1(field("type_arg", $._type_ref), ","),
|
|
2044
|
+
"]",
|
|
1784
2045
|
"(",
|
|
1785
2046
|
optional(sep1(field("arg", $._expression), ",")),
|
|
1786
2047
|
optional(","),
|
|
@@ -1888,20 +2149,48 @@ module.exports = grammar({
|
|
|
1888
2149
|
// as a method call on an integer literal.
|
|
1889
2150
|
float_literal: () =>
|
|
1890
2151
|
/[0-9]+(_[0-9]+)*\.[0-9]+(_[0-9]+)*([eE][+-]?[0-9]+(_[0-9]+)*)?|[0-9]+(_[0-9]+)*[eE][+-]?[0-9]+(_[0-9]+)*/,
|
|
2152
|
+
// #2622: a decimal literal - digits, an optional fraction, a trailing `d`.
|
|
2153
|
+
decimal_literal: () => /[0-9]+(_[0-9]+)*(\.[0-9]+(_[0-9]+)*)?d/,
|
|
1891
2154
|
string_literal: ($) =>
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
2155
|
+
choice(
|
|
2156
|
+
seq(
|
|
2157
|
+
'"',
|
|
2158
|
+
// #2203: string text is one high-precedence immediate token, so a
|
|
2159
|
+
// `//` inside a string (a URL) is text, not a line comment.
|
|
2160
|
+
repeat(
|
|
2161
|
+
choice(
|
|
2162
|
+
token.immediate(prec(1, /[^"\\\n]+/)),
|
|
2163
|
+
$.escape_sequence,
|
|
2164
|
+
$.string_interpolation,
|
|
2165
|
+
),
|
|
1901
2166
|
),
|
|
2167
|
+
'"',
|
|
1902
2168
|
),
|
|
1903
|
-
|
|
1904
|
-
|
|
2169
|
+
// #2619: a multi-line string. The opening `"""` is followed by a
|
|
2170
|
+
// newline; the body may hold lone or doubled quotes; escapes and
|
|
2171
|
+
// interpolation are those of an ordinary string. (Indentation stripping
|
|
2172
|
+
// is a value rule, not a shape: the compiler checks it.)
|
|
2173
|
+
seq(
|
|
2174
|
+
token(/"""\r?\n/),
|
|
2175
|
+
repeat(
|
|
2176
|
+
choice(
|
|
2177
|
+
token.immediate(prec(1, /[^"\\]+/)),
|
|
2178
|
+
token.immediate(prec(1, /"{1,2}[^"\\]/)),
|
|
2179
|
+
$.escape_sequence,
|
|
2180
|
+
$.string_interpolation,
|
|
2181
|
+
),
|
|
2182
|
+
),
|
|
2183
|
+
'"""',
|
|
2184
|
+
),
|
|
2185
|
+
// #2619: a raw string (`r"…"`, `r#"…"#`, `r"""…"""`): no escapes, no
|
|
2186
|
+
// interpolation. An external token — the `#` count is not regular.
|
|
2187
|
+
$.raw_string,
|
|
2188
|
+
),
|
|
2189
|
+
// `\n \t \r \0 \" \\` and `\u{1–6 hex digits}` (#2619). Whether a `\u{…}`
|
|
2190
|
+
// names a scalar value (not a surrogate, at most 10FFFF) is the compiler's
|
|
2191
|
+
// check.
|
|
2192
|
+
escape_sequence: () =>
|
|
2193
|
+
token.immediate(choice(/\\[ntr0"\\]/, /\\u\{[0-9a-fA-F]{1,6}\}/)),
|
|
1905
2194
|
// v0.43: an interpolation hole `\(expr)`. A bare `\(` was an invalid
|
|
1906
2195
|
// escape, so this is backward-compatible; `\\(` is an escaped backslash
|
|
1907
2196
|
// followed by a literal `(`, so it is not a hole.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tree-sitter-bynk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.492.1",
|
|
4
4
|
"description": "Tree-sitter grammar for the Bynk language.",
|
|
5
5
|
"main": "bindings/node",
|
|
6
6
|
"types": "bindings/node",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"node-gyp-build": "^4.8.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"tree-sitter": "^0.
|
|
33
|
+
"tree-sitter": "^0.25.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"tree-sitter": {
|