agency-lang 0.0.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.
Files changed (76) hide show
  1. package/README.md +7 -0
  2. package/dist/backends/baseGenerator.js +194 -0
  3. package/dist/backends/graphGenerator.integration.test.js +119 -0
  4. package/dist/backends/graphGenerator.js +308 -0
  5. package/dist/backends/index.js +3 -0
  6. package/dist/backends/typescriptGenerator/builtins.js +46 -0
  7. package/dist/backends/typescriptGenerator/typeToString.js +36 -0
  8. package/dist/backends/typescriptGenerator/typeToZodSchema.js +54 -0
  9. package/dist/backends/typescriptGenerator.integration.test.js +119 -0
  10. package/dist/backends/typescriptGenerator.js +340 -0
  11. package/dist/backends/typescriptGenerator.test.js +763 -0
  12. package/dist/backends/utils.js +6 -0
  13. package/dist/generate-graph-file.js +25 -0
  14. package/dist/generate-ts-file.js +26 -0
  15. package/dist/index.js +3 -0
  16. package/dist/parser.js +38 -0
  17. package/dist/parser.test.js +306 -0
  18. package/dist/parsers/access.js +19 -0
  19. package/dist/parsers/access.test.js +929 -0
  20. package/dist/parsers/assignment.js +8 -0
  21. package/dist/parsers/body.test.js +106 -0
  22. package/dist/parsers/comment.js +6 -0
  23. package/dist/parsers/comment.test.js +100 -0
  24. package/dist/parsers/dataStructures.js +14 -0
  25. package/dist/parsers/dataStructures.test.js +660 -0
  26. package/dist/parsers/function.js +22 -0
  27. package/dist/parsers/function.test.js +591 -0
  28. package/dist/parsers/functionCall.js +10 -0
  29. package/dist/parsers/functionCall.test.js +119 -0
  30. package/dist/parsers/importStatement.js +3 -0
  31. package/dist/parsers/importStatement.test.js +290 -0
  32. package/dist/parsers/literals.js +12 -0
  33. package/dist/parsers/literals.test.js +639 -0
  34. package/dist/parsers/matchBlock.js +24 -0
  35. package/dist/parsers/matchBlock.test.js +506 -0
  36. package/dist/parsers/parserUtils.js +2 -0
  37. package/dist/parsers/returnStatement.js +8 -0
  38. package/dist/parsers/tools.js +3 -0
  39. package/dist/parsers/tools.test.js +170 -0
  40. package/dist/parsers/typeHints.js +59 -0
  41. package/dist/parsers/typeHints.test.js +2754 -0
  42. package/dist/parsers/utils.js +5 -0
  43. package/dist/parsers/whileLoop.test.js +342 -0
  44. package/dist/templates/backends/graphGenerator/builtinTools.js +36 -0
  45. package/dist/templates/backends/graphGenerator/conditionalEdge.js +10 -0
  46. package/dist/templates/backends/graphGenerator/edge.js +10 -0
  47. package/dist/templates/backends/graphGenerator/goToNode.js +9 -0
  48. package/dist/templates/backends/graphGenerator/graphNode.js +15 -0
  49. package/dist/templates/backends/graphGenerator/imports.js +47 -0
  50. package/dist/templates/backends/graphGenerator/node.js +18 -0
  51. package/dist/templates/backends/graphGenerator/promptNode.js +16 -0
  52. package/dist/templates/backends/graphGenerator/startNode.js +10 -0
  53. package/dist/templates/backends/typescriptGenerator/builtinFunctions/fetch.js +17 -0
  54. package/dist/templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js +17 -0
  55. package/dist/templates/backends/typescriptGenerator/builtinFunctions/input.js +21 -0
  56. package/dist/templates/backends/typescriptGenerator/builtinFunctions/read.js +13 -0
  57. package/dist/templates/backends/typescriptGenerator/builtinTools.js +36 -0
  58. package/dist/templates/backends/typescriptGenerator/functionDefinition.js +11 -0
  59. package/dist/templates/backends/typescriptGenerator/imports.js +25 -0
  60. package/dist/templates/backends/typescriptGenerator/promptFunction.js +76 -0
  61. package/dist/templates/backends/typescriptGenerator/tool.js +23 -0
  62. package/dist/templates/backends/typescriptGenerator/toolCall.js +35 -0
  63. package/dist/types/access.js +1 -0
  64. package/dist/types/dataStructures.js +1 -0
  65. package/dist/types/function.js +1 -0
  66. package/dist/types/graphNode.js +1 -0
  67. package/dist/types/importStatement.js +1 -0
  68. package/dist/types/literals.js +1 -0
  69. package/dist/types/matchBlock.js +1 -0
  70. package/dist/types/returnStatement.js +1 -0
  71. package/dist/types/tools.js +1 -0
  72. package/dist/types/typeHints.js +1 -0
  73. package/dist/types/whileLoop.js +1 -0
  74. package/dist/types.js +11 -0
  75. package/dist/utils.js +18 -0
  76. package/package.json +52 -0
@@ -0,0 +1,639 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { textSegmentParser, interpolationSegmentParser, promptParser, numberParser, stringParser, variableNameParser, literalParser, } from "./literals.js";
3
+ describe("literals parsers", () => {
4
+ describe("textSegmentParser", () => {
5
+ const testCases = [
6
+ // Happy path
7
+ {
8
+ input: "hello`",
9
+ expected: { success: true, result: { type: "text", value: "hello" } },
10
+ },
11
+ {
12
+ input: "hello",
13
+ expected: { success: true, result: { type: "text", value: "hello" } },
14
+ },
15
+ {
16
+ input: "hello world`",
17
+ expected: {
18
+ success: true,
19
+ result: { type: "text", value: "hello world" },
20
+ },
21
+ },
22
+ {
23
+ input: "hello$",
24
+ expected: { success: true, result: { type: "text", value: "hello" } },
25
+ },
26
+ // Edge cases
27
+ {
28
+ input: "a`",
29
+ expected: { success: true, result: { type: "text", value: "a" } },
30
+ },
31
+ {
32
+ input: "spaces and tabs\t\t`",
33
+ expected: {
34
+ success: true,
35
+ result: { type: "text", value: "spaces and tabs\t\t" },
36
+ },
37
+ },
38
+ {
39
+ input: "123numbers`",
40
+ expected: {
41
+ success: true,
42
+ result: { type: "text", value: "123numbers" },
43
+ },
44
+ },
45
+ {
46
+ input: "special!@#%^&*()chars`",
47
+ expected: {
48
+ success: true,
49
+ result: { type: "text", value: "special!@#%^&*()chars" },
50
+ },
51
+ },
52
+ // Failure cases
53
+ { input: "`", expected: { success: false } },
54
+ { input: "$", expected: { success: false } },
55
+ { input: "", expected: { success: false } },
56
+ ];
57
+ testCases.forEach(({ input, expected }) => {
58
+ if (expected.success) {
59
+ it(`should parse "${input}" successfully`, () => {
60
+ const result = textSegmentParser(input);
61
+ expect(result.success).toBe(true);
62
+ if (result.success) {
63
+ expect(result.result).toEqual(expected.result);
64
+ }
65
+ });
66
+ }
67
+ else {
68
+ it(`should fail to parse "${input}"`, () => {
69
+ const result = textSegmentParser(input);
70
+ expect(result.success).toBe(false);
71
+ });
72
+ }
73
+ });
74
+ });
75
+ describe("interpolationSegmentParser", () => {
76
+ const testCases = [
77
+ // Happy path
78
+ {
79
+ input: "${foo}",
80
+ expected: {
81
+ success: true,
82
+ result: { type: "interpolation", variableName: "foo" },
83
+ },
84
+ },
85
+ {
86
+ input: "${bar123}",
87
+ expected: {
88
+ success: true,
89
+ result: { type: "interpolation", variableName: "bar123" },
90
+ },
91
+ },
92
+ {
93
+ input: "${x}",
94
+ expected: {
95
+ success: true,
96
+ result: { type: "interpolation", variableName: "x" },
97
+ },
98
+ },
99
+ // Edge cases
100
+ {
101
+ input: "${longVariableNameWithNumbers123}",
102
+ expected: {
103
+ success: true,
104
+ result: {
105
+ type: "interpolation",
106
+ variableName: "longVariableNameWithNumbers123",
107
+ },
108
+ },
109
+ },
110
+ // Failure cases
111
+ { input: "${", expected: { success: false } },
112
+ { input: "${foo", expected: { success: false } },
113
+ { input: "$foo}", expected: { success: false } },
114
+ { input: "{foo}", expected: { success: false } },
115
+ { input: "${}", expected: { success: false } },
116
+ { input: "", expected: { success: false } },
117
+ { input: "foo", expected: { success: false } },
118
+ ];
119
+ testCases.forEach(({ input, expected }) => {
120
+ if (expected.success) {
121
+ it(`should parse "${input}" successfully`, () => {
122
+ const result = interpolationSegmentParser(input);
123
+ expect(result.success).toBe(true);
124
+ if (result.success) {
125
+ expect(result.result).toEqual(expected.result);
126
+ }
127
+ });
128
+ }
129
+ else {
130
+ it(`should fail to parse "${input}"`, () => {
131
+ const result = interpolationSegmentParser(input);
132
+ expect(result.success).toBe(false);
133
+ });
134
+ }
135
+ });
136
+ });
137
+ describe("promptParser", () => {
138
+ const testCases = [
139
+ // Simple text prompts
140
+ {
141
+ input: "`hello`",
142
+ expected: {
143
+ success: true,
144
+ result: {
145
+ type: "prompt",
146
+ segments: [{ type: "text", value: "hello" }],
147
+ },
148
+ },
149
+ },
150
+ {
151
+ input: "`the number 1`",
152
+ expected: {
153
+ success: true,
154
+ result: {
155
+ type: "prompt",
156
+ segments: [{ type: "text", value: "the number 1" }],
157
+ },
158
+ },
159
+ },
160
+ // Empty prompt
161
+ {
162
+ input: "``",
163
+ expected: {
164
+ success: true,
165
+ result: {
166
+ type: "prompt",
167
+ segments: [],
168
+ },
169
+ },
170
+ },
171
+ // Prompts with interpolation only
172
+ {
173
+ input: "`${foo}`",
174
+ expected: {
175
+ success: true,
176
+ result: {
177
+ type: "prompt",
178
+ segments: [{ type: "interpolation", variableName: "foo" }],
179
+ },
180
+ },
181
+ },
182
+ // Mixed segments
183
+ {
184
+ input: "`hello ${name}`",
185
+ expected: {
186
+ success: true,
187
+ result: {
188
+ type: "prompt",
189
+ segments: [
190
+ { type: "text", value: "hello " },
191
+ { type: "interpolation", variableName: "name" },
192
+ ],
193
+ },
194
+ },
195
+ },
196
+ {
197
+ input: "`${greeting} world`",
198
+ expected: {
199
+ success: true,
200
+ result: {
201
+ type: "prompt",
202
+ segments: [
203
+ { type: "interpolation", variableName: "greeting" },
204
+ { type: "text", value: " world" },
205
+ ],
206
+ },
207
+ },
208
+ },
209
+ {
210
+ input: "`The value is ${x} and ${y}`",
211
+ expected: {
212
+ success: true,
213
+ result: {
214
+ type: "prompt",
215
+ segments: [
216
+ { type: "text", value: "The value is " },
217
+ { type: "interpolation", variableName: "x" },
218
+ { type: "text", value: " and " },
219
+ { type: "interpolation", variableName: "y" },
220
+ ],
221
+ },
222
+ },
223
+ },
224
+ // Multiple interpolations
225
+ {
226
+ input: "`${a}${b}${c}`",
227
+ expected: {
228
+ success: true,
229
+ result: {
230
+ type: "prompt",
231
+ segments: [
232
+ { type: "interpolation", variableName: "a" },
233
+ { type: "interpolation", variableName: "b" },
234
+ { type: "interpolation", variableName: "c" },
235
+ ],
236
+ },
237
+ },
238
+ },
239
+ // Failure cases
240
+ { input: "`hello", expected: { success: false } },
241
+ { input: "hello`", expected: { success: false } },
242
+ { input: "", expected: { success: false } },
243
+ { input: "hello", expected: { success: false } },
244
+ ];
245
+ testCases.forEach(({ input, expected }) => {
246
+ if (expected.success) {
247
+ it(`should parse "${input}" successfully`, () => {
248
+ const result = promptParser(input);
249
+ expect(result.success).toBe(true);
250
+ if (result.success) {
251
+ expect(result.result).toEqual(expected.result);
252
+ }
253
+ });
254
+ }
255
+ else {
256
+ it(`should fail to parse "${input}"`, () => {
257
+ const result = promptParser(input);
258
+ expect(result.success).toBe(false);
259
+ });
260
+ }
261
+ });
262
+ });
263
+ describe("numberParser", () => {
264
+ const testCases = [
265
+ // Integers
266
+ {
267
+ input: "42",
268
+ expected: { success: true, result: { type: "number", value: "42" } },
269
+ },
270
+ {
271
+ input: "0",
272
+ expected: { success: true, result: { type: "number", value: "0" } },
273
+ },
274
+ {
275
+ input: "999",
276
+ expected: { success: true, result: { type: "number", value: "999" } },
277
+ },
278
+ // Negative numbers
279
+ {
280
+ input: "-42",
281
+ expected: { success: true, result: { type: "number", value: "-42" } },
282
+ },
283
+ {
284
+ input: "-1",
285
+ expected: { success: true, result: { type: "number", value: "-1" } },
286
+ },
287
+ // Decimals
288
+ {
289
+ input: "3.14",
290
+ expected: { success: true, result: { type: "number", value: "3.14" } },
291
+ },
292
+ {
293
+ input: "0.5",
294
+ expected: { success: true, result: { type: "number", value: "0.5" } },
295
+ },
296
+ {
297
+ input: "100.001",
298
+ expected: {
299
+ success: true,
300
+ result: { type: "number", value: "100.001" },
301
+ },
302
+ },
303
+ // Negative decimals
304
+ {
305
+ input: "-3.14",
306
+ expected: { success: true, result: { type: "number", value: "-3.14" } },
307
+ },
308
+ {
309
+ input: "-0.5",
310
+ expected: { success: true, result: { type: "number", value: "-0.5" } },
311
+ },
312
+ // Edge cases
313
+ {
314
+ input: ".5",
315
+ expected: { success: true, result: { type: "number", value: ".5" } },
316
+ },
317
+ {
318
+ input: "-.5",
319
+ expected: { success: true, result: { type: "number", value: "-.5" } },
320
+ },
321
+ {
322
+ input: "-",
323
+ expected: { success: true, result: { type: "number", value: "-" } },
324
+ },
325
+ {
326
+ input: ".",
327
+ expected: { success: true, result: { type: "number", value: "." } },
328
+ },
329
+ // Failure cases
330
+ { input: "abc", expected: { success: false } },
331
+ { input: "", expected: { success: false } },
332
+ { input: "x123", expected: { success: false } },
333
+ ];
334
+ testCases.forEach(({ input, expected }) => {
335
+ if (expected.success) {
336
+ it(`should parse "${input}" successfully`, () => {
337
+ const result = numberParser(input);
338
+ expect(result.success).toBe(true);
339
+ if (result.success) {
340
+ expect(result.result).toEqual(expected.result);
341
+ }
342
+ });
343
+ }
344
+ else {
345
+ it(`should fail to parse "${input}"`, () => {
346
+ const result = numberParser(input);
347
+ expect(result.success).toBe(false);
348
+ });
349
+ }
350
+ });
351
+ });
352
+ describe("stringParser", () => {
353
+ const testCases = [
354
+ // Happy path
355
+ {
356
+ input: '"hello"',
357
+ expected: { success: true, result: { type: "string", value: "hello" } },
358
+ },
359
+ {
360
+ input: '"world"',
361
+ expected: { success: true, result: { type: "string", value: "world" } },
362
+ },
363
+ {
364
+ input: '"Hello, World!"',
365
+ expected: {
366
+ success: true,
367
+ result: { type: "string", value: "Hello, World!" },
368
+ },
369
+ },
370
+ // Empty string
371
+ {
372
+ input: '""',
373
+ expected: { success: true, result: { type: "string", value: "" } },
374
+ },
375
+ // Strings with special characters
376
+ {
377
+ input: '"123"',
378
+ expected: { success: true, result: { type: "string", value: "123" } },
379
+ },
380
+ {
381
+ input: '" spaces "',
382
+ expected: {
383
+ success: true,
384
+ result: { type: "string", value: " spaces " },
385
+ },
386
+ },
387
+ {
388
+ input: '"tab\there"',
389
+ expected: {
390
+ success: true,
391
+ result: { type: "string", value: "tab\there" },
392
+ },
393
+ },
394
+ {
395
+ input: '"newline\nhere"',
396
+ expected: {
397
+ success: true,
398
+ result: { type: "string", value: "newline\nhere" },
399
+ },
400
+ },
401
+ {
402
+ input: '"special!@#$%^&*()"',
403
+ expected: {
404
+ success: true,
405
+ result: { type: "string", value: "special!@#$%^&*()" },
406
+ },
407
+ },
408
+ {
409
+ input: '"single\'quote"',
410
+ expected: {
411
+ success: true,
412
+ result: { type: "string", value: "single'quote" },
413
+ },
414
+ },
415
+ {
416
+ input: '"`backtick`"',
417
+ expected: {
418
+ success: true,
419
+ result: { type: "string", value: "`backtick`" },
420
+ },
421
+ },
422
+ // Failure cases
423
+ { input: '"hello', expected: { success: false } },
424
+ { input: 'hello"', expected: { success: false } },
425
+ { input: "'hello'", expected: { success: false } },
426
+ { input: "", expected: { success: false } },
427
+ { input: "hello", expected: { success: false } },
428
+ ];
429
+ testCases.forEach(({ input, expected }) => {
430
+ if (expected.success) {
431
+ it(`should parse "${input}" successfully`, () => {
432
+ const result = stringParser(input);
433
+ expect(result.success).toBe(true);
434
+ if (result.success) {
435
+ expect(result.result).toEqual(expected.result);
436
+ }
437
+ });
438
+ }
439
+ else {
440
+ it(`should fail to parse "${input}"`, () => {
441
+ const result = stringParser(input);
442
+ expect(result.success).toBe(false);
443
+ });
444
+ }
445
+ });
446
+ });
447
+ describe("variableNameParser", () => {
448
+ const testCases = [
449
+ // Happy path
450
+ {
451
+ input: "foo",
452
+ expected: {
453
+ success: true,
454
+ result: { type: "variableName", value: "foo" },
455
+ },
456
+ },
457
+ {
458
+ input: "bar",
459
+ expected: {
460
+ success: true,
461
+ result: { type: "variableName", value: "bar" },
462
+ },
463
+ },
464
+ {
465
+ input: "x",
466
+ expected: {
467
+ success: true,
468
+ result: { type: "variableName", value: "x" },
469
+ },
470
+ },
471
+ {
472
+ input: "myVariable",
473
+ expected: {
474
+ success: true,
475
+ result: { type: "variableName", value: "myVariable" },
476
+ },
477
+ },
478
+ // With numbers
479
+ {
480
+ input: "foo123",
481
+ expected: {
482
+ success: true,
483
+ result: { type: "variableName", value: "foo123" },
484
+ },
485
+ },
486
+ {
487
+ input: "x1",
488
+ expected: {
489
+ success: true,
490
+ result: { type: "variableName", value: "x1" },
491
+ },
492
+ },
493
+ {
494
+ input: "var2test",
495
+ expected: {
496
+ success: true,
497
+ result: { type: "variableName", value: "var2test" },
498
+ },
499
+ },
500
+ {
501
+ input: "123",
502
+ expected: {
503
+ success: true,
504
+ result: { type: "variableName", value: "123" },
505
+ },
506
+ },
507
+ // Mixed case
508
+ {
509
+ input: "camelCase",
510
+ expected: {
511
+ success: true,
512
+ result: { type: "variableName", value: "camelCase" },
513
+ },
514
+ },
515
+ {
516
+ input: "PascalCase",
517
+ expected: {
518
+ success: true,
519
+ result: { type: "variableName", value: "PascalCase" },
520
+ },
521
+ },
522
+ {
523
+ input: "UPPERCASE",
524
+ expected: {
525
+ success: true,
526
+ result: { type: "variableName", value: "UPPERCASE" },
527
+ },
528
+ },
529
+ // Failure cases
530
+ { input: "", expected: { success: false } },
531
+ ];
532
+ testCases.forEach(({ input, expected }) => {
533
+ if (expected.success) {
534
+ it(`should parse "${input}" successfully`, () => {
535
+ const result = variableNameParser(input);
536
+ expect(result.success).toBe(true);
537
+ if (result.success) {
538
+ expect(result.result).toEqual(expected.result);
539
+ }
540
+ });
541
+ }
542
+ else {
543
+ it(`should fail to parse "${input}"`, () => {
544
+ const result = variableNameParser(input);
545
+ expect(result.success).toBe(false);
546
+ });
547
+ }
548
+ });
549
+ });
550
+ describe("literalParser", () => {
551
+ const testCases = [
552
+ // Prompt literals (highest precedence)
553
+ {
554
+ input: "`hello`",
555
+ expected: {
556
+ success: true,
557
+ result: {
558
+ type: "prompt",
559
+ segments: [{ type: "text", value: "hello" }],
560
+ },
561
+ },
562
+ },
563
+ {
564
+ input: "`${foo}`",
565
+ expected: {
566
+ success: true,
567
+ result: {
568
+ type: "prompt",
569
+ segments: [{ type: "interpolation", variableName: "foo" }],
570
+ },
571
+ },
572
+ },
573
+ // Number literals
574
+ {
575
+ input: "42",
576
+ expected: { success: true, result: { type: "number", value: "42" } },
577
+ },
578
+ {
579
+ input: "-3.14",
580
+ expected: { success: true, result: { type: "number", value: "-3.14" } },
581
+ },
582
+ // String literals
583
+ {
584
+ input: '"hello"',
585
+ expected: { success: true, result: { type: "string", value: "hello" } },
586
+ },
587
+ {
588
+ input: '""',
589
+ expected: { success: true, result: { type: "string", value: "" } },
590
+ },
591
+ // Variable name literals (lowest precedence)
592
+ {
593
+ input: "foo",
594
+ expected: {
595
+ success: true,
596
+ result: { type: "variableName", value: "foo" },
597
+ },
598
+ },
599
+ {
600
+ input: "bar123",
601
+ expected: {
602
+ success: true,
603
+ result: { type: "variableName", value: "bar123" },
604
+ },
605
+ },
606
+ // Precedence tests - numbers vs variable names
607
+ {
608
+ input: "123",
609
+ expected: { success: true, result: { type: "number", value: "123" } },
610
+ },
611
+ // Strings vs other types
612
+ {
613
+ input: '"123"',
614
+ expected: { success: true, result: { type: "string", value: "123" } },
615
+ },
616
+ // Failure cases
617
+ { input: "", expected: { success: false } },
618
+ { input: "`unterminated", expected: { success: false } },
619
+ { input: "'single quotes'", expected: { success: false } },
620
+ ];
621
+ testCases.forEach(({ input, expected }) => {
622
+ if (expected.success) {
623
+ it(`should parse "${input}" successfully`, () => {
624
+ const result = literalParser(input);
625
+ expect(result.success).toBe(true);
626
+ if (result.success) {
627
+ expect(result.result).toEqual(expected.result);
628
+ }
629
+ });
630
+ }
631
+ else {
632
+ it(`should fail to parse "${input}"`, () => {
633
+ const result = literalParser(input);
634
+ expect(result.success).toBe(false);
635
+ });
636
+ }
637
+ });
638
+ });
639
+ });
@@ -0,0 +1,24 @@
1
+ /*
2
+ export type MatchBlock = {
3
+ type: "matchBlock";
4
+ expression: Literal;
5
+ cases: Array<{
6
+ caseValue: Literal;
7
+ body: Assignment | Literal | FunctionCall;
8
+ }>;
9
+ };
10
+ */
11
+ import { capture, char, newline, or, sepBy, seqC, set, str, } from "tarsec";
12
+ import { optionalSpaces } from "./utils.js";
13
+ import { literalParser } from "./literals.js";
14
+ import { assignmentParser } from "./assignment.js";
15
+ import { functionCallParser } from "./functionCall.js";
16
+ import { accessExpressionParser } from "./access.js";
17
+ import { optionalSemicolon } from "./parserUtils.js";
18
+ import { agencyArrayParser, agencyObjectParser } from "./dataStructures.js";
19
+ import { commentParser } from "./comment.js";
20
+ import { returnStatementParser } from "./returnStatement.js";
21
+ export const defaultCaseParser = char("_");
22
+ export const matchBlockParserCase = seqC(set("type", "matchBlockCase"), optionalSpaces, capture(or(defaultCaseParser, accessExpressionParser, literalParser), "caseValue"), optionalSpaces, str("=>"), optionalSpaces, capture(or(returnStatementParser, agencyArrayParser, agencyObjectParser, accessExpressionParser, assignmentParser, functionCallParser, literalParser), "body"));
23
+ const semicolon = seqC(optionalSpaces, char(";"), optionalSpaces);
24
+ export const matchBlockParser = seqC(set("type", "matchBlock"), str("match"), optionalSpaces, char("("), capture(literalParser, "expression"), char(")"), optionalSpaces, char("{"), optionalSpaces, capture(sepBy(or(semicolon, newline), or(commentParser, matchBlockParserCase)), "cases"), optionalSpaces, char("}"), optionalSemicolon);