tree-sitter-bynk 0.233.2 → 0.239.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/grammar.js CHANGED
@@ -184,12 +184,16 @@ module.exports = grammar({
184
184
  $.fn_decl,
185
185
  $.messages_decl,
186
186
  // Permissive: capability/service/etc. can syntactically appear
187
- // anywhere — the LSP reports semantic placement errors.
187
+ // anywhere — the LSP reports semantic placement errors. Events
188
+ // track slice 0 (spine #936): `event` follows the same permissive
189
+ // precedent (`bynk.event.outside_context` rejects it here, at the
190
+ // checker, not the grammar).
188
191
  $.capability_decl,
189
192
  $.provider_decl,
190
193
  $.service_decl,
191
194
  $.agent_decl,
192
195
  $.actor_decl,
196
+ $.event_decl,
193
197
  ),
194
198
 
195
199
  _context_body_item: ($) =>
@@ -205,6 +209,7 @@ module.exports = grammar({
205
209
  $.agent_decl,
206
210
  $.actor_decl,
207
211
  $.messages_decl,
212
+ $.event_decl,
208
213
  ),
209
214
 
210
215
  // v0.17: adapter items — a binding clause, capabilities, boundary types,
@@ -226,6 +231,7 @@ module.exports = grammar({
226
231
  $.agent_decl,
227
232
  $.actor_decl,
228
233
  $.messages_decl,
234
+ $.event_decl,
229
235
  ),
230
236
 
231
237
  _test_body_item: ($) =>
@@ -338,6 +344,18 @@ module.exports = grammar({
338
344
  optional(seq("=", field("init", $._expression))),
339
345
  ),
340
346
 
347
+ // Events track, slice 0 (spine #936): `event Name = { fields }` — a
348
+ // typed fact a context may emit and other contexts' subscriber services
349
+ // may receive. Record body only (mirrors `record_type`, not the full
350
+ // `_type_body` choice — no sum/opaque/refined event shapes).
351
+ event_decl: ($) =>
352
+ seq(
353
+ "event",
354
+ field("name", $.identifier),
355
+ "=",
356
+ field("body", $.record_type),
357
+ ),
358
+
341
359
  // v0.154 (ADR 0178): a sum body may carry a trailing `embeds E as V, …`
342
360
  // clause declaring error embeddings the `?` operator auto-converts.
343
361
  // `embeds`/`as` are contextual — matched only in this position.
@@ -573,6 +591,10 @@ module.exports = grammar({
573
591
  seq(
574
592
  "fn",
575
593
  field("name", $.identifier),
594
+ // #926: optional `[T, …]` type parameters on the op itself — resolved
595
+ // only from an explicit type argument at the call site (mirroring
596
+ // `fn_decl`'s own `[A, B]` slot, `grammar.js:525`).
597
+ optional(seq("[", sep1(field("type_param", $.identifier), ","), "]")),
576
598
  "(",
577
599
  optional(sep1($.param, ",")),
578
600
  optional(","),
@@ -698,6 +720,12 @@ module.exports = grammar({
698
720
  // types. `websocket`, `in`, and `out` are contextual (resolved by `word`).
699
721
  // #548: `websocket` lowercased to match the other protocol sources (was
700
722
  // `WebSocket`).
723
+ // Events track, slice 0 (spine #936): `from Events(E)`, optionally
724
+ // filtered by a slice-1 structural pattern, `from Events(E { field:
725
+ // value, .. })`. `Events`, capitalised, is matched as plain `identifier`
726
+ // text the same way `websocket` is matched lowercase — it names the
727
+ // `Events` capability directly, not a built-in type name, so no lexer
728
+ // reservation.
701
729
  service_protocol: ($) =>
702
730
  seq(
703
731
  "from",
@@ -718,6 +746,47 @@ module.exports = grammar({
718
746
  optional(","),
719
747
  ")",
720
748
  ),
749
+ seq(
750
+ "Events",
751
+ "(",
752
+ field("event_type", $._type_ref),
753
+ optional(field("pattern", $.event_pattern)),
754
+ ")",
755
+ ),
756
+ ),
757
+ ),
758
+ // Events track, slice 1 (spine #936): the structural delivery filter on
759
+ // a subscription header. A trailing `..` is mandatory whenever any field
760
+ // is listed — mirrors the hand-written parser's `bynk.parse.
761
+ // event_pattern_empty` rejection of `Events(E { })`. `..` is one literal
762
+ // token here (not two `.`s), keeping this grammar in agreement with the
763
+ // Rust lexer's dedicated `DotDot` token.
764
+ event_pattern: ($) =>
765
+ seq(
766
+ "{",
767
+ repeat(seq(field("field", $.event_pattern_field), ",")),
768
+ "..",
769
+ "}",
770
+ ),
771
+ event_pattern_field: ($) =>
772
+ seq(
773
+ field("name", $.identifier),
774
+ ":",
775
+ field("value", $.event_pattern_value),
776
+ ),
777
+ // A closed set, mirroring `literal_pattern` plus a nullary-variant
778
+ // reference (`variant_pattern` without a payload list — no nested
779
+ // sub-patterns in v1). The checker separately rejects a payload-carrying
780
+ // variant (`bynk.event.pattern_variant_payload`) since the grammar has
781
+ // no payload-list position here to reject it structurally.
782
+ event_pattern_value: ($) =>
783
+ choice(
784
+ seq(optional("-"), $.number_literal),
785
+ $.string_literal,
786
+ $.boolean_literal,
787
+ seq(
788
+ optional(seq(field("type", $.identifier), ".")),
789
+ field("variant", $.identifier),
721
790
  ),
722
791
  ),
723
792
 
@@ -803,6 +872,27 @@ module.exports = grammar({
803
872
  // queue-handler shape (the protocol on the service header disambiguates).
804
873
  $.ws_open_handler,
805
874
  $.ws_close_handler,
875
+ // Events track, slice 0 (spine #936): a `from Events(E)` service's
876
+ // one handler.
877
+ $.event_handler,
878
+ ),
879
+ // Events track, slice 0 (spine #936): `on event(e: E) -> Effect[()] { … }`
880
+ // — a `from Events(E)` subscriber's one handler. Same generic shape as
881
+ // every other handler form (params/by/given/body all uniform); the
882
+ // checker verifies the param count/type against the service header.
883
+ event_handler: ($) =>
884
+ seq(
885
+ "on",
886
+ "event",
887
+ "(",
888
+ optional(sep1($.param, ",")),
889
+ optional(","),
890
+ ")",
891
+ "->",
892
+ field("return_type", $._type_ref),
893
+ optional(field("by", $.by_clause)),
894
+ optional(field("given", $.given_clause)),
895
+ field("body", $.block),
806
896
  ),
807
897
  call_handler: ($) =>
808
898
  seq(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-bynk",
3
- "version": "0.233.2",
3
+ "version": "0.239.0",
4
4
  "description": "Tree-sitter grammar for the Bynk DSL (v0–v0.16).",
5
5
  "main": "bindings/node",
6
6
  "types": "bindings/node",
@@ -23,6 +23,7 @@
23
23
  "websocket"
24
24
  "schedule"
25
25
  "message"
26
+ "Events"
26
27
  ] @keyword
27
28
 
28
29
  [
@@ -55,6 +56,7 @@
55
56
  "requires"
56
57
  "ensures"
57
58
  "messages"
59
+ "event"
58
60
  ] @keyword.declaration
59
61
 
60
62
  [
@@ -111,6 +113,12 @@
111
113
 
112
114
  ; User-defined type names appear in type positions.
113
115
  (type_decl name: (identifier) @type)
116
+ ; Events track slice 0/1 (spine #936): an `event` declaration names a type,
117
+ ; like `type_decl`; the header's `event_type` and a pattern field's
118
+ ; qualifier both reference one.
119
+ (event_decl name: (identifier) @type)
120
+ (service_protocol event_type: (identifier) @type)
121
+ (event_pattern_value type: (identifier) @type)
114
122
  (opaque_type) @type
115
123
  (generic_type_ref arg: (identifier) @type)
116
124
  ; v0.157 (ADR 0183): a user generic-type application — the head name and each
@@ -159,6 +167,8 @@
159
167
  (field_init name: (identifier) @field)
160
168
  (field_init shorthand: (identifier) @field)
161
169
  (named_binding field: (identifier) @field)
170
+ ; Events track slice 1 (spine #936): a subscription pattern's field name.
171
+ (event_pattern_field name: (identifier) @field)
162
172
 
163
173
  ; -- Variants & constants --
164
174
 
@@ -174,6 +184,13 @@
174
184
  ; `positional_binding` capture now that the payload position is a full pattern.
175
185
  ((variant_pattern variant: (identifier) @variable)
176
186
  (#match? @variable "^[a-z_]"))
187
+ ; Events track slice 1 (spine #936): a subscription pattern's variant value
188
+ ; (`region: Region.Domestic` / bare `Domestic`) — always a nullary reference
189
+ ; (the checker rejects a payload-carrying variant), so unlike
190
+ ; `variant_pattern` there is no binding-vs-tag ambiguity; still keyed on
191
+ ; capitalisation for consistency with every other variant reference.
192
+ ((event_pattern_value variant: (identifier) @constant)
193
+ (#match? @constant "^[A-Z]"))
177
194
  (boolean_literal) @constant.builtin
178
195
 
179
196
  ; -- Literals --
package/src/grammar.json CHANGED
@@ -406,6 +406,10 @@
406
406
  {
407
407
  "type": "SYMBOL",
408
408
  "name": "actor_decl"
409
+ },
410
+ {
411
+ "type": "SYMBOL",
412
+ "name": "event_decl"
409
413
  }
410
414
  ]
411
415
  },
@@ -455,6 +459,10 @@
455
459
  {
456
460
  "type": "SYMBOL",
457
461
  "name": "messages_decl"
462
+ },
463
+ {
464
+ "type": "SYMBOL",
465
+ "name": "event_decl"
458
466
  }
459
467
  ]
460
468
  },
@@ -508,6 +516,10 @@
508
516
  {
509
517
  "type": "SYMBOL",
510
518
  "name": "messages_decl"
519
+ },
520
+ {
521
+ "type": "SYMBOL",
522
+ "name": "event_decl"
511
523
  }
512
524
  ]
513
525
  },
@@ -1194,6 +1206,35 @@
1194
1206
  }
1195
1207
  ]
1196
1208
  },
1209
+ "event_decl": {
1210
+ "type": "SEQ",
1211
+ "members": [
1212
+ {
1213
+ "type": "STRING",
1214
+ "value": "event"
1215
+ },
1216
+ {
1217
+ "type": "FIELD",
1218
+ "name": "name",
1219
+ "content": {
1220
+ "type": "SYMBOL",
1221
+ "name": "identifier"
1222
+ }
1223
+ },
1224
+ {
1225
+ "type": "STRING",
1226
+ "value": "="
1227
+ },
1228
+ {
1229
+ "type": "FIELD",
1230
+ "name": "body",
1231
+ "content": {
1232
+ "type": "SYMBOL",
1233
+ "name": "record_type"
1234
+ }
1235
+ }
1236
+ ]
1237
+ },
1197
1238
  "sum_type": {
1198
1239
  "type": "PREC_RIGHT",
1199
1240
  "value": 0,
@@ -2373,6 +2414,60 @@
2373
2414
  "name": "identifier"
2374
2415
  }
2375
2416
  },
2417
+ {
2418
+ "type": "CHOICE",
2419
+ "members": [
2420
+ {
2421
+ "type": "SEQ",
2422
+ "members": [
2423
+ {
2424
+ "type": "STRING",
2425
+ "value": "["
2426
+ },
2427
+ {
2428
+ "type": "SEQ",
2429
+ "members": [
2430
+ {
2431
+ "type": "FIELD",
2432
+ "name": "type_param",
2433
+ "content": {
2434
+ "type": "SYMBOL",
2435
+ "name": "identifier"
2436
+ }
2437
+ },
2438
+ {
2439
+ "type": "REPEAT",
2440
+ "content": {
2441
+ "type": "SEQ",
2442
+ "members": [
2443
+ {
2444
+ "type": "STRING",
2445
+ "value": ","
2446
+ },
2447
+ {
2448
+ "type": "FIELD",
2449
+ "name": "type_param",
2450
+ "content": {
2451
+ "type": "SYMBOL",
2452
+ "name": "identifier"
2453
+ }
2454
+ }
2455
+ ]
2456
+ }
2457
+ }
2458
+ ]
2459
+ },
2460
+ {
2461
+ "type": "STRING",
2462
+ "value": "]"
2463
+ }
2464
+ ]
2465
+ },
2466
+ {
2467
+ "type": "BLANK"
2468
+ }
2469
+ ]
2470
+ },
2376
2471
  {
2377
2472
  "type": "STRING",
2378
2473
  "value": "("
@@ -3116,6 +3211,181 @@
3116
3211
  "value": ")"
3117
3212
  }
3118
3213
  ]
3214
+ },
3215
+ {
3216
+ "type": "SEQ",
3217
+ "members": [
3218
+ {
3219
+ "type": "STRING",
3220
+ "value": "Events"
3221
+ },
3222
+ {
3223
+ "type": "STRING",
3224
+ "value": "("
3225
+ },
3226
+ {
3227
+ "type": "FIELD",
3228
+ "name": "event_type",
3229
+ "content": {
3230
+ "type": "SYMBOL",
3231
+ "name": "_type_ref"
3232
+ }
3233
+ },
3234
+ {
3235
+ "type": "CHOICE",
3236
+ "members": [
3237
+ {
3238
+ "type": "FIELD",
3239
+ "name": "pattern",
3240
+ "content": {
3241
+ "type": "SYMBOL",
3242
+ "name": "event_pattern"
3243
+ }
3244
+ },
3245
+ {
3246
+ "type": "BLANK"
3247
+ }
3248
+ ]
3249
+ },
3250
+ {
3251
+ "type": "STRING",
3252
+ "value": ")"
3253
+ }
3254
+ ]
3255
+ }
3256
+ ]
3257
+ }
3258
+ ]
3259
+ },
3260
+ "event_pattern": {
3261
+ "type": "SEQ",
3262
+ "members": [
3263
+ {
3264
+ "type": "STRING",
3265
+ "value": "{"
3266
+ },
3267
+ {
3268
+ "type": "REPEAT",
3269
+ "content": {
3270
+ "type": "SEQ",
3271
+ "members": [
3272
+ {
3273
+ "type": "FIELD",
3274
+ "name": "field",
3275
+ "content": {
3276
+ "type": "SYMBOL",
3277
+ "name": "event_pattern_field"
3278
+ }
3279
+ },
3280
+ {
3281
+ "type": "STRING",
3282
+ "value": ","
3283
+ }
3284
+ ]
3285
+ }
3286
+ },
3287
+ {
3288
+ "type": "STRING",
3289
+ "value": ".."
3290
+ },
3291
+ {
3292
+ "type": "STRING",
3293
+ "value": "}"
3294
+ }
3295
+ ]
3296
+ },
3297
+ "event_pattern_field": {
3298
+ "type": "SEQ",
3299
+ "members": [
3300
+ {
3301
+ "type": "FIELD",
3302
+ "name": "name",
3303
+ "content": {
3304
+ "type": "SYMBOL",
3305
+ "name": "identifier"
3306
+ }
3307
+ },
3308
+ {
3309
+ "type": "STRING",
3310
+ "value": ":"
3311
+ },
3312
+ {
3313
+ "type": "FIELD",
3314
+ "name": "value",
3315
+ "content": {
3316
+ "type": "SYMBOL",
3317
+ "name": "event_pattern_value"
3318
+ }
3319
+ }
3320
+ ]
3321
+ },
3322
+ "event_pattern_value": {
3323
+ "type": "CHOICE",
3324
+ "members": [
3325
+ {
3326
+ "type": "SEQ",
3327
+ "members": [
3328
+ {
3329
+ "type": "CHOICE",
3330
+ "members": [
3331
+ {
3332
+ "type": "STRING",
3333
+ "value": "-"
3334
+ },
3335
+ {
3336
+ "type": "BLANK"
3337
+ }
3338
+ ]
3339
+ },
3340
+ {
3341
+ "type": "SYMBOL",
3342
+ "name": "number_literal"
3343
+ }
3344
+ ]
3345
+ },
3346
+ {
3347
+ "type": "SYMBOL",
3348
+ "name": "string_literal"
3349
+ },
3350
+ {
3351
+ "type": "SYMBOL",
3352
+ "name": "boolean_literal"
3353
+ },
3354
+ {
3355
+ "type": "SEQ",
3356
+ "members": [
3357
+ {
3358
+ "type": "CHOICE",
3359
+ "members": [
3360
+ {
3361
+ "type": "SEQ",
3362
+ "members": [
3363
+ {
3364
+ "type": "FIELD",
3365
+ "name": "type",
3366
+ "content": {
3367
+ "type": "SYMBOL",
3368
+ "name": "identifier"
3369
+ }
3370
+ },
3371
+ {
3372
+ "type": "STRING",
3373
+ "value": "."
3374
+ }
3375
+ ]
3376
+ },
3377
+ {
3378
+ "type": "BLANK"
3379
+ }
3380
+ ]
3381
+ },
3382
+ {
3383
+ "type": "FIELD",
3384
+ "name": "variant",
3385
+ "content": {
3386
+ "type": "SYMBOL",
3387
+ "name": "identifier"
3388
+ }
3119
3389
  }
3120
3390
  ]
3121
3391
  }
@@ -3542,6 +3812,128 @@
3542
3812
  {
3543
3813
  "type": "SYMBOL",
3544
3814
  "name": "ws_close_handler"
3815
+ },
3816
+ {
3817
+ "type": "SYMBOL",
3818
+ "name": "event_handler"
3819
+ }
3820
+ ]
3821
+ },
3822
+ "event_handler": {
3823
+ "type": "SEQ",
3824
+ "members": [
3825
+ {
3826
+ "type": "STRING",
3827
+ "value": "on"
3828
+ },
3829
+ {
3830
+ "type": "STRING",
3831
+ "value": "event"
3832
+ },
3833
+ {
3834
+ "type": "STRING",
3835
+ "value": "("
3836
+ },
3837
+ {
3838
+ "type": "CHOICE",
3839
+ "members": [
3840
+ {
3841
+ "type": "SEQ",
3842
+ "members": [
3843
+ {
3844
+ "type": "SYMBOL",
3845
+ "name": "param"
3846
+ },
3847
+ {
3848
+ "type": "REPEAT",
3849
+ "content": {
3850
+ "type": "SEQ",
3851
+ "members": [
3852
+ {
3853
+ "type": "STRING",
3854
+ "value": ","
3855
+ },
3856
+ {
3857
+ "type": "SYMBOL",
3858
+ "name": "param"
3859
+ }
3860
+ ]
3861
+ }
3862
+ }
3863
+ ]
3864
+ },
3865
+ {
3866
+ "type": "BLANK"
3867
+ }
3868
+ ]
3869
+ },
3870
+ {
3871
+ "type": "CHOICE",
3872
+ "members": [
3873
+ {
3874
+ "type": "STRING",
3875
+ "value": ","
3876
+ },
3877
+ {
3878
+ "type": "BLANK"
3879
+ }
3880
+ ]
3881
+ },
3882
+ {
3883
+ "type": "STRING",
3884
+ "value": ")"
3885
+ },
3886
+ {
3887
+ "type": "STRING",
3888
+ "value": "->"
3889
+ },
3890
+ {
3891
+ "type": "FIELD",
3892
+ "name": "return_type",
3893
+ "content": {
3894
+ "type": "SYMBOL",
3895
+ "name": "_type_ref"
3896
+ }
3897
+ },
3898
+ {
3899
+ "type": "CHOICE",
3900
+ "members": [
3901
+ {
3902
+ "type": "FIELD",
3903
+ "name": "by",
3904
+ "content": {
3905
+ "type": "SYMBOL",
3906
+ "name": "by_clause"
3907
+ }
3908
+ },
3909
+ {
3910
+ "type": "BLANK"
3911
+ }
3912
+ ]
3913
+ },
3914
+ {
3915
+ "type": "CHOICE",
3916
+ "members": [
3917
+ {
3918
+ "type": "FIELD",
3919
+ "name": "given",
3920
+ "content": {
3921
+ "type": "SYMBOL",
3922
+ "name": "given_clause"
3923
+ }
3924
+ },
3925
+ {
3926
+ "type": "BLANK"
3927
+ }
3928
+ ]
3929
+ },
3930
+ {
3931
+ "type": "FIELD",
3932
+ "name": "body",
3933
+ "content": {
3934
+ "type": "SYMBOL",
3935
+ "name": "block"
3936
+ }
3545
3937
  }
3546
3938
  ]
3547
3939
  },