tree-sitter-bynk 0.245.0 → 0.290.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/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # tree-sitter-bynk
2
+
3
+ [![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](#license)
4
+
5
+ The [tree-sitter](https://tree-sitter.github.io/tree-sitter/) grammar for the
6
+ [Bynk](https://github.com/accuser/bynk) DSL — the source of truth for editor
7
+ syntax highlighting (`queries/highlights.scm`, `injections.scm`) and the
8
+ structural shape [`vscode-bynk`](https://github.com/accuser/bynk/tree/main/vscode-bynk)
9
+ builds on.
10
+
11
+ This directory is **two things**:
12
+
13
+ - **The grammar** (`grammar.js`), published to npm as
14
+ [`tree-sitter-bynk`](https://www.npmjs.com/package/tree-sitter-bynk), with
15
+ generated Node and Rust bindings (`bindings/`). This is what editors and
16
+ `vscode-bynk` actually consume.
17
+ - **A Rust crate** (this `Cargo.toml`, wrapping `bindings/rust/`) that exists
18
+ for exactly one purpose: the cross-parser conformance test
19
+ (`tests/conformance.rs`), which parses Bynk source with this grammar and
20
+ diffs the accept/reject decision against the hand-written
21
+ [`bynk-syntax`](https://crates.io/crates/bynk-syntax) recursive-descent
22
+ parser — the only guard tying the editor grammar to the compiler's own.
23
+
24
+ > **Not a published Rust crate.** The Rust binding is `publish = false` and
25
+ > kept off the release workflows' crate list; only the grammar itself ships
26
+ > to npm.
27
+
28
+ The grammar deliberately stays **permissive** in the places where Bynk's type
29
+ checker would reject a program — semantic rules (type checking,
30
+ exhaustiveness, effect propagation, `given` matching) are left entirely to
31
+ the LSP (`bynk-lsp`), not encoded here.
32
+
33
+ ## Building
34
+
35
+ ```sh
36
+ npm install
37
+ npx tree-sitter generate
38
+ npx tree-sitter test
39
+ ```
40
+
41
+ The Rust binding builds as an ordinary workspace member (`cargo build -p
42
+ tree-sitter-bynk`); `bynk-syntax` does not depend on it, so the conformance
43
+ test's dev-dependency edge is cycle-free.
44
+
45
+ ## License
46
+
47
+ Licensed under either of [Apache-2.0](https://github.com/accuser/bynk/blob/main/LICENSE-APACHE) or
48
+ [MIT](https://github.com/accuser/bynk/blob/main/LICENSE-MIT) at your option.
package/grammar.js CHANGED
@@ -74,6 +74,13 @@ module.exports = grammar({
74
74
  // whether a matcher (`called`/`never`/`before`) or an ordinary continuation
75
75
  // (`(`, an operator, …) follows.
76
76
  [$.observation_expr, $._primary],
77
+ // v0.140: inside `agent_decl`, a `store` field's own trailing
78
+ // `@annotation`s are the same rule as the handler-position annotation
79
+ // prefix that can immediately follow the last store field — one token of
80
+ // `@` lookahead can't tell which one a run of annotations belongs to.
81
+ // Both parses are equivalent once the next `on`/`store`/handler-body
82
+ // token is seen, so GLR resolves it rather than the grammar needing to.
83
+ [$.store_field],
77
84
  ],
78
85
 
79
86
  rules: {
@@ -435,7 +442,16 @@ module.exports = grammar({
435
442
  "Positive",
436
443
  "NonEmpty",
437
444
  ),
438
- _pred_arg: ($) => choice($.number_literal, $.float_literal, $.string_literal),
445
+ // v0.21/v0.142 (ADR 0166): a refinement-bound number may be negated —
446
+ // `InRange(-1_000, 1_000_000)` — mirroring `parse_signed_num_literal`'s
447
+ // optional leading `-` (a string argument, `Matches`'s only shape, is
448
+ // never signed).
449
+ _pred_arg: ($) =>
450
+ choice(
451
+ seq(optional("-"), $.number_literal),
452
+ seq(optional("-"), $.float_literal),
453
+ $.string_literal,
454
+ ),
439
455
 
440
456
  _base_type: ($) => $.base_type,
441
457
  base_type: () =>
@@ -681,7 +697,10 @@ module.exports = grammar({
681
697
  // v0.142 (ADR 0166): the optional `limits { }` policy, likewise a
682
698
  // header-position `from http` concern restricted by the checker.
683
699
  optional(field("limits", $.limits_policy)),
684
- repeat($.handler),
700
+ // v0.140 (ADR 0163): a handler may carry one or more `@name(args)`
701
+ // annotations (`@cache(maxAge: 5.minutes)`, `@limit(maxBody: …)`) —
702
+ // the same shape `store_annotation` already gives store fields.
703
+ repeat(seq(repeat(field("annotation", $.store_annotation)), $.handler)),
685
704
  "}",
686
705
  ),
687
706
  // v0.131: `cors { <name>: <value>, … }`. `cors` is a contextual keyword (like
@@ -821,7 +840,13 @@ module.exports = grammar({
821
840
  // v0.81 (storage track): the agent's `store` fields (ADR 0108).
822
841
  repeat($.store_field),
823
842
  repeat(choice($.invariant_decl, $.transition_decl)),
824
- repeat($.handler),
843
+ // v0.140 (ADR 0163): handler-position annotations parse uniformly on
844
+ // agent handlers too; the checker (not the grammar) restricts which
845
+ // annotations apply to a non-HTTP handler. Only `on call` is a valid
846
+ // agent handler (`bynk.parse.handler_in_agent` rejects the rest) —
847
+ // protocol handlers (HTTP routes, cron, queue, WebSocket, events)
848
+ // belong on a `service`.
849
+ repeat(seq(repeat(field("annotation", $.store_annotation)), $.call_handler)),
825
850
  "}",
826
851
  ),
827
852
  // v0.80: an agent invariant — `invariant <name>: <predicate>`. Sits between
@@ -1350,8 +1375,12 @@ module.exports = grammar({
1350
1375
  optional(","),
1351
1376
  ),
1352
1377
  ),
1378
+ // v1 (#472) admits only a wildcard `_` as the refined inner form —
1379
+ // `parse_pattern_where_suffix` rejects anything else with
1380
+ // `bynk.parse.refined_pattern_inner` ("a refined pattern's inner form
1381
+ // must be `_` in this version"); binding a refined value is unbuilt.
1353
1382
  refined_pattern: ($) =>
1354
- seq(field("inner", $._pattern), "where", field("predicate", $.refinement)),
1383
+ seq(field("inner", $.wildcard_pattern), "where", field("predicate", $.refinement)),
1355
1384
 
1356
1385
  _pattern: ($) =>
1357
1386
  choice(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-bynk",
3
- "version": "0.245.0",
3
+ "version": "0.290.0",
4
4
  "description": "Tree-sitter grammar for the Bynk DSL (v0–v0.16).",
5
5
  "main": "bindings/node",
6
6
  "types": "bindings/node",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "prebuildify": "^6.0.0",
42
- "tree-sitter-cli": "^0.26.9"
42
+ "tree-sitter-cli": "^0.27.0"
43
43
  },
44
44
  "tree-sitter": [
45
45
  {
package/src/grammar.json CHANGED
@@ -1661,12 +1661,46 @@
1661
1661
  "type": "CHOICE",
1662
1662
  "members": [
1663
1663
  {
1664
- "type": "SYMBOL",
1665
- "name": "number_literal"
1664
+ "type": "SEQ",
1665
+ "members": [
1666
+ {
1667
+ "type": "CHOICE",
1668
+ "members": [
1669
+ {
1670
+ "type": "STRING",
1671
+ "value": "-"
1672
+ },
1673
+ {
1674
+ "type": "BLANK"
1675
+ }
1676
+ ]
1677
+ },
1678
+ {
1679
+ "type": "SYMBOL",
1680
+ "name": "number_literal"
1681
+ }
1682
+ ]
1666
1683
  },
1667
1684
  {
1668
- "type": "SYMBOL",
1669
- "name": "float_literal"
1685
+ "type": "SEQ",
1686
+ "members": [
1687
+ {
1688
+ "type": "CHOICE",
1689
+ "members": [
1690
+ {
1691
+ "type": "STRING",
1692
+ "value": "-"
1693
+ },
1694
+ {
1695
+ "type": "BLANK"
1696
+ }
1697
+ ]
1698
+ },
1699
+ {
1700
+ "type": "SYMBOL",
1701
+ "name": "float_literal"
1702
+ }
1703
+ ]
1670
1704
  },
1671
1705
  {
1672
1706
  "type": "SYMBOL",
@@ -2907,8 +2941,24 @@
2907
2941
  {
2908
2942
  "type": "REPEAT",
2909
2943
  "content": {
2910
- "type": "SYMBOL",
2911
- "name": "handler"
2944
+ "type": "SEQ",
2945
+ "members": [
2946
+ {
2947
+ "type": "REPEAT",
2948
+ "content": {
2949
+ "type": "FIELD",
2950
+ "name": "annotation",
2951
+ "content": {
2952
+ "type": "SYMBOL",
2953
+ "name": "store_annotation"
2954
+ }
2955
+ }
2956
+ },
2957
+ {
2958
+ "type": "SYMBOL",
2959
+ "name": "handler"
2960
+ }
2961
+ ]
2912
2962
  }
2913
2963
  },
2914
2964
  {
@@ -3517,8 +3567,24 @@
3517
3567
  {
3518
3568
  "type": "REPEAT",
3519
3569
  "content": {
3520
- "type": "SYMBOL",
3521
- "name": "handler"
3570
+ "type": "SEQ",
3571
+ "members": [
3572
+ {
3573
+ "type": "REPEAT",
3574
+ "content": {
3575
+ "type": "FIELD",
3576
+ "name": "annotation",
3577
+ "content": {
3578
+ "type": "SYMBOL",
3579
+ "name": "store_annotation"
3580
+ }
3581
+ }
3582
+ },
3583
+ {
3584
+ "type": "SYMBOL",
3585
+ "name": "call_handler"
3586
+ }
3587
+ ]
3522
3588
  }
3523
3589
  },
3524
3590
  {
@@ -6326,7 +6392,7 @@
6326
6392
  "name": "inner",
6327
6393
  "content": {
6328
6394
  "type": "SYMBOL",
6329
- "name": "_pattern"
6395
+ "name": "wildcard_pattern"
6330
6396
  }
6331
6397
  },
6332
6398
  {
@@ -8126,6 +8192,9 @@
8126
8192
  [
8127
8193
  "observation_expr",
8128
8194
  "_primary"
8195
+ ],
8196
+ [
8197
+ "store_field"
8129
8198
  ]
8130
8199
  ],
8131
8200
  "precedences": [],
@@ -287,6 +287,16 @@
287
287
  "type": "agent_decl",
288
288
  "named": true,
289
289
  "fields": {
290
+ "annotation": {
291
+ "multiple": true,
292
+ "required": false,
293
+ "types": [
294
+ {
295
+ "type": "store_annotation",
296
+ "named": true
297
+ }
298
+ ]
299
+ },
290
300
  "key": {
291
301
  "multiple": false,
292
302
  "required": true,
@@ -313,7 +323,7 @@
313
323
  "required": false,
314
324
  "types": [
315
325
  {
316
- "type": "handler",
326
+ "type": "call_handler",
317
327
  "named": true
318
328
  },
319
329
  {
@@ -7837,22 +7847,6 @@
7837
7847
  "multiple": false,
7838
7848
  "required": true,
7839
7849
  "types": [
7840
- {
7841
- "type": "literal_pattern",
7842
- "named": true
7843
- },
7844
- {
7845
- "type": "or_pattern",
7846
- "named": true
7847
- },
7848
- {
7849
- "type": "paren_pattern",
7850
- "named": true
7851
- },
7852
- {
7853
- "type": "variant_pattern",
7854
- "named": true
7855
- },
7856
7850
  {
7857
7851
  "type": "wildcard_pattern",
7858
7852
  "named": true
@@ -8307,6 +8301,16 @@
8307
8301
  "type": "service_decl",
8308
8302
  "named": true,
8309
8303
  "fields": {
8304
+ "annotation": {
8305
+ "multiple": true,
8306
+ "required": false,
8307
+ "types": [
8308
+ {
8309
+ "type": "store_annotation",
8310
+ "named": true
8311
+ }
8312
+ ]
8313
+ },
8310
8314
  "cors": {
8311
8315
  "multiple": false,
8312
8316
  "required": false,