agency-lang 0.0.21 → 0.0.23
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/dist/lib/backends/agencyGenerator.d.ts +10 -2
- package/dist/lib/backends/agencyGenerator.js +87 -20
- package/dist/lib/backends/agencyGenerator.test.js +0 -48
- package/dist/lib/backends/baseGenerator.d.ts +11 -4
- package/dist/lib/backends/baseGenerator.js +35 -11
- package/dist/lib/backends/graphGenerator.js +19 -186
- package/dist/lib/backends/typescriptGenerator/builtins.js +6 -0
- package/dist/lib/backends/typescriptGenerator.d.ts +11 -3
- package/dist/lib/backends/typescriptGenerator.js +98 -26
- package/dist/lib/backends/utils.d.ts +1 -1
- package/dist/lib/parser.js +5 -5
- package/dist/lib/parser.test.js +15 -38
- package/dist/lib/parsers/access.test.js +14 -3
- package/dist/lib/parsers/assignment.test.js +159 -4
- package/dist/lib/parsers/await.d.ts +3 -0
- package/dist/lib/parsers/await.js +18 -0
- package/dist/lib/parsers/body.test.js +10 -1
- package/dist/lib/parsers/dataStructures.js +2 -2
- package/dist/lib/parsers/dataStructures.test.js +11 -11
- package/dist/lib/parsers/function.d.ts +8 -3
- package/dist/lib/parsers/function.js +64 -12
- package/dist/lib/parsers/function.test.js +284 -52
- package/dist/lib/parsers/functionCall.test.js +6 -6
- package/dist/lib/parsers/ifElse.test.d.ts +1 -0
- package/dist/lib/parsers/ifElse.test.js +376 -0
- package/dist/lib/parsers/importStatement.js +2 -2
- package/dist/lib/parsers/literals.d.ts +1 -0
- package/dist/lib/parsers/literals.js +6 -2
- package/dist/lib/parsers/literals.test.js +110 -21
- package/dist/lib/parsers/matchBlock.js +7 -4
- package/dist/lib/parsers/matchBlock.test.js +16 -16
- package/dist/lib/parsers/newline.d.ts +3 -0
- package/dist/lib/parsers/newline.js +2 -0
- package/dist/lib/parsers/parserUtils.d.ts +3 -1
- package/dist/lib/parsers/parserUtils.js +4 -1
- package/dist/lib/parsers/returnStatement.js +2 -1
- package/dist/lib/parsers/returnStatement.test.js +2 -2
- package/dist/lib/parsers/specialVar.test.js +7 -7
- package/dist/lib/parsers/typeHints.d.ts +1 -1
- package/dist/lib/parsers/typeHints.js +4 -4
- package/dist/lib/parsers/typeHints.test.js +0 -8
- package/dist/lib/parsers/utils.d.ts +1 -0
- package/dist/lib/parsers/utils.js +2 -1
- package/dist/lib/parsers/whileLoop.test.js +46 -1
- package/dist/lib/templates/backends/graphGenerator/goToNode.d.ts +2 -1
- package/dist/lib/templates/backends/graphGenerator/goToNode.js +11 -1
- package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +2 -2
- package/dist/lib/templates/backends/graphGenerator/graphNode.js +2 -1
- package/dist/lib/templates/backends/graphGenerator/imports.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/imports.js +14 -1
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.d.ts +4 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/sleep.js +13 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.d.ts +7 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/time.js +12 -0
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -0
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/promptFunction.js +3 -2
- package/dist/lib/templates/backends/typescriptGenerator/tool.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/tool.js +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/toolCall.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/toolCall.js +2 -2
- package/dist/lib/types/await.d.ts +7 -0
- package/dist/lib/types/await.js +1 -0
- package/dist/lib/types/graphNode.d.ts +2 -1
- package/dist/lib/types/ifElse.d.ts +7 -0
- package/dist/lib/types/ifElse.js +1 -0
- package/dist/lib/types/literals.d.ts +1 -1
- package/dist/lib/types/returnStatement.d.ts +2 -1
- package/dist/lib/types/timeBlock.d.ts +5 -0
- package/dist/lib/types/timeBlock.js +1 -0
- package/dist/lib/types.d.ts +16 -8
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +3 -0
- package/package.json +2 -1
- package/dist/lib/parsers/assignment.d.ts +0 -3
- package/dist/lib/parsers/assignment.js +0 -8
- package/dist/lib/templates/backends/graphGenerator/node.d.ts +0 -7
- package/dist/lib/templates/backends/graphGenerator/node.js +0 -18
- package/dist/lib/templates/backends/graphGenerator/promptNode.d.ts +0 -8
- package/dist/lib/templates/backends/graphGenerator/promptNode.js +0 -16
package/dist/lib/parser.test.js
CHANGED
|
@@ -35,7 +35,7 @@ describe("agencyNode", () => {
|
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
input: "// this is a comment
|
|
38
|
+
input: "// this is a comment",
|
|
39
39
|
expected: {
|
|
40
40
|
success: true,
|
|
41
41
|
nodeCount: 1,
|
|
@@ -46,7 +46,7 @@ describe("agencyNode", () => {
|
|
|
46
46
|
input: "bar :: number\nx = 5",
|
|
47
47
|
expected: {
|
|
48
48
|
success: true,
|
|
49
|
-
nodeCount:
|
|
49
|
+
nodeCount: 3,
|
|
50
50
|
firstNodeType: "typeHint",
|
|
51
51
|
},
|
|
52
52
|
},
|
|
@@ -54,7 +54,7 @@ describe("agencyNode", () => {
|
|
|
54
54
|
input: "foo :: string\nfoo = `hello`",
|
|
55
55
|
expected: {
|
|
56
56
|
success: true,
|
|
57
|
-
nodeCount:
|
|
57
|
+
nodeCount: 3,
|
|
58
58
|
firstNodeType: "typeHint",
|
|
59
59
|
},
|
|
60
60
|
},
|
|
@@ -62,7 +62,7 @@ describe("agencyNode", () => {
|
|
|
62
62
|
input: "def test() { foo = 1 }\ntest()",
|
|
63
63
|
expected: {
|
|
64
64
|
success: true,
|
|
65
|
-
nodeCount:
|
|
65
|
+
nodeCount: 3,
|
|
66
66
|
firstNodeType: "function",
|
|
67
67
|
},
|
|
68
68
|
},
|
|
@@ -108,14 +108,14 @@ describe("agencyParser", () => {
|
|
|
108
108
|
input: "bar :: number\nbar = 5",
|
|
109
109
|
expected: {
|
|
110
110
|
success: true,
|
|
111
|
-
nodeCount:
|
|
111
|
+
nodeCount: 3,
|
|
112
112
|
},
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
input: "x = 5\ny = 10\nz = 15",
|
|
116
116
|
expected: {
|
|
117
117
|
success: true,
|
|
118
|
-
nodeCount:
|
|
118
|
+
nodeCount: 5,
|
|
119
119
|
},
|
|
120
120
|
},
|
|
121
121
|
{
|
|
@@ -129,14 +129,14 @@ describe("agencyParser", () => {
|
|
|
129
129
|
input: "def add() { x = 5\ny = 10 }\nadd()",
|
|
130
130
|
expected: {
|
|
131
131
|
success: true,
|
|
132
|
-
nodeCount:
|
|
132
|
+
nodeCount: 3,
|
|
133
133
|
},
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
input: "result :: number\nresult = `the number 42`",
|
|
137
137
|
expected: {
|
|
138
138
|
success: true,
|
|
139
|
-
nodeCount:
|
|
139
|
+
nodeCount: 3,
|
|
140
140
|
},
|
|
141
141
|
},
|
|
142
142
|
{
|
|
@@ -181,7 +181,7 @@ describe("parseAgency", () => {
|
|
|
181
181
|
expected: {
|
|
182
182
|
success: true,
|
|
183
183
|
programType: "agencyProgram",
|
|
184
|
-
nodeCount:
|
|
184
|
+
nodeCount: 3,
|
|
185
185
|
},
|
|
186
186
|
},
|
|
187
187
|
{
|
|
@@ -205,7 +205,7 @@ describe("parseAgency", () => {
|
|
|
205
205
|
expected: {
|
|
206
206
|
success: true,
|
|
207
207
|
programType: "agencyProgram",
|
|
208
|
-
nodeCount:
|
|
208
|
+
nodeCount: 5,
|
|
209
209
|
},
|
|
210
210
|
},
|
|
211
211
|
{
|
|
@@ -243,46 +243,23 @@ describe("parseAgency", () => {
|
|
|
243
243
|
});
|
|
244
244
|
}
|
|
245
245
|
});
|
|
246
|
-
it("should handle complex multi-statement programs", () => {
|
|
247
|
-
const input = `count :: number
|
|
248
|
-
count = \`the number 5\`
|
|
249
|
-
items :: string[]
|
|
250
|
-
items = \`list of fruits\`
|
|
251
|
-
def process() {
|
|
252
|
-
result = count
|
|
253
|
-
result
|
|
254
|
-
}
|
|
255
|
-
process()`;
|
|
256
|
-
const result = parseAgency(input);
|
|
257
|
-
expect(result.success).toBe(true);
|
|
258
|
-
if (result.success) {
|
|
259
|
-
expect(result.result.type).toBe("agencyProgram");
|
|
260
|
-
expect(result.result.nodes.length).toBe(6);
|
|
261
|
-
expect(result.result.nodes[0].type).toBe("typeHint");
|
|
262
|
-
expect(result.result.nodes[1].type).toBe("assignment");
|
|
263
|
-
expect(result.result.nodes[2].type).toBe("typeHint");
|
|
264
|
-
expect(result.result.nodes[3].type).toBe("assignment");
|
|
265
|
-
expect(result.result.nodes[4].type).toBe("function");
|
|
266
|
-
expect(result.result.nodes[5].type).toBe("functionCall");
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
246
|
it("should parse real-world example from tests/assignment.agency pattern", () => {
|
|
270
247
|
const input = `bar :: number
|
|
271
|
-
test :: string
|
|
272
248
|
bar = \`the number 1\``;
|
|
273
249
|
const result = parseAgency(input);
|
|
274
250
|
expect(result.success).toBe(true);
|
|
275
251
|
if (result.success) {
|
|
276
|
-
expect(result.result.nodes.length).toBe(3);
|
|
277
252
|
expect(result.result.nodes[0]).toMatchObject({
|
|
278
253
|
type: "typeHint",
|
|
279
254
|
variableName: "bar",
|
|
280
255
|
variableType: { type: "primitiveType", value: "number" },
|
|
281
256
|
});
|
|
282
257
|
expect(result.result.nodes[1]).toMatchObject({
|
|
283
|
-
type: "
|
|
284
|
-
|
|
285
|
-
|
|
258
|
+
type: "newLine",
|
|
259
|
+
});
|
|
260
|
+
expect(result.result.nodes[2]).toMatchObject({
|
|
261
|
+
type: "assignment",
|
|
262
|
+
variableName: "bar",
|
|
286
263
|
});
|
|
287
264
|
}
|
|
288
265
|
});
|
|
@@ -68,7 +68,10 @@ describe("access expression parsers", () => {
|
|
|
68
68
|
result: {
|
|
69
69
|
type: "indexAccess",
|
|
70
70
|
array: { type: "variableName", value: "obj" },
|
|
71
|
-
index: {
|
|
71
|
+
index: {
|
|
72
|
+
type: "string",
|
|
73
|
+
segments: [{ type: "text", value: "key" }],
|
|
74
|
+
},
|
|
72
75
|
},
|
|
73
76
|
},
|
|
74
77
|
},
|
|
@@ -79,7 +82,10 @@ describe("access expression parsers", () => {
|
|
|
79
82
|
result: {
|
|
80
83
|
type: "indexAccess",
|
|
81
84
|
array: { type: "variableName", value: "data" },
|
|
82
|
-
index: {
|
|
85
|
+
index: {
|
|
86
|
+
type: "string",
|
|
87
|
+
segments: [{ type: "text", value: "field" }],
|
|
88
|
+
},
|
|
83
89
|
},
|
|
84
90
|
},
|
|
85
91
|
},
|
|
@@ -155,7 +161,12 @@ describe("access expression parsers", () => {
|
|
|
155
161
|
array: {
|
|
156
162
|
type: "functionCall",
|
|
157
163
|
functionName: "getUsers",
|
|
158
|
-
arguments: [
|
|
164
|
+
arguments: [
|
|
165
|
+
{
|
|
166
|
+
type: "string",
|
|
167
|
+
segments: [{ type: "text", value: "active" }],
|
|
168
|
+
},
|
|
169
|
+
],
|
|
159
170
|
},
|
|
160
171
|
index: { type: "number", value: "0" },
|
|
161
172
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { assignmentParser } from "./
|
|
2
|
+
import { assignmentParser } from "./function.js";
|
|
3
3
|
describe("assignmentParser", () => {
|
|
4
4
|
const testCases = [
|
|
5
5
|
// Happy path - simple literal assignments
|
|
@@ -21,7 +21,10 @@ describe("assignmentParser", () => {
|
|
|
21
21
|
result: {
|
|
22
22
|
type: "assignment",
|
|
23
23
|
variableName: "name",
|
|
24
|
-
value: {
|
|
24
|
+
value: {
|
|
25
|
+
type: "string",
|
|
26
|
+
segments: [{ type: "text", value: "Alice" }],
|
|
27
|
+
},
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
},
|
|
@@ -136,7 +139,10 @@ describe("assignmentParser", () => {
|
|
|
136
139
|
functionName: "calculate",
|
|
137
140
|
arguments: [
|
|
138
141
|
{ type: "number", value: "1" },
|
|
139
|
-
{
|
|
142
|
+
{
|
|
143
|
+
type: "string",
|
|
144
|
+
segments: [{ type: "text", value: "test" }],
|
|
145
|
+
},
|
|
140
146
|
],
|
|
141
147
|
},
|
|
142
148
|
},
|
|
@@ -188,7 +194,10 @@ describe("assignmentParser", () => {
|
|
|
188
194
|
entries: [
|
|
189
195
|
{
|
|
190
196
|
key: "key",
|
|
191
|
-
value: {
|
|
197
|
+
value: {
|
|
198
|
+
type: "string",
|
|
199
|
+
segments: [{ type: "text", value: "value" }],
|
|
200
|
+
},
|
|
192
201
|
},
|
|
193
202
|
],
|
|
194
203
|
},
|
|
@@ -252,6 +261,152 @@ describe("assignmentParser", () => {
|
|
|
252
261
|
},
|
|
253
262
|
},
|
|
254
263
|
},
|
|
264
|
+
// Typed assignments - primitive types
|
|
265
|
+
{
|
|
266
|
+
input: "foo: number = 1",
|
|
267
|
+
expected: {
|
|
268
|
+
success: true,
|
|
269
|
+
result: {
|
|
270
|
+
type: "assignment",
|
|
271
|
+
variableName: "foo",
|
|
272
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
273
|
+
value: { type: "number", value: "1" },
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
input: "bar: number = `the number 1`",
|
|
279
|
+
expected: {
|
|
280
|
+
success: true,
|
|
281
|
+
result: {
|
|
282
|
+
type: "assignment",
|
|
283
|
+
variableName: "bar",
|
|
284
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
285
|
+
value: {
|
|
286
|
+
type: "prompt",
|
|
287
|
+
segments: [{ type: "text", value: "the number 1" }],
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
input: 'name: string = "Alice"',
|
|
294
|
+
expected: {
|
|
295
|
+
success: true,
|
|
296
|
+
result: {
|
|
297
|
+
type: "assignment",
|
|
298
|
+
variableName: "name",
|
|
299
|
+
typeHint: { type: "primitiveType", value: "string" },
|
|
300
|
+
value: {
|
|
301
|
+
type: "string",
|
|
302
|
+
segments: [{ type: "text", value: "Alice" }],
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
input: "isActive: boolean = true",
|
|
309
|
+
expected: {
|
|
310
|
+
success: true,
|
|
311
|
+
result: {
|
|
312
|
+
type: "assignment",
|
|
313
|
+
variableName: "isActive",
|
|
314
|
+
typeHint: { type: "primitiveType", value: "boolean" },
|
|
315
|
+
value: { type: "variableName", value: "true" },
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
// Typed assignments - array types
|
|
320
|
+
{
|
|
321
|
+
input: "items: number[] = [1, 2, 3]",
|
|
322
|
+
expected: {
|
|
323
|
+
success: true,
|
|
324
|
+
result: {
|
|
325
|
+
type: "assignment",
|
|
326
|
+
variableName: "items",
|
|
327
|
+
typeHint: {
|
|
328
|
+
type: "arrayType",
|
|
329
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
330
|
+
},
|
|
331
|
+
value: {
|
|
332
|
+
type: "agencyArray",
|
|
333
|
+
items: [
|
|
334
|
+
{ type: "number", value: "1" },
|
|
335
|
+
{ type: "number", value: "2" },
|
|
336
|
+
{ type: "number", value: "3" },
|
|
337
|
+
],
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
input: 'names: string[] = ["Alice", "Bob"]',
|
|
344
|
+
expected: {
|
|
345
|
+
success: true,
|
|
346
|
+
result: {
|
|
347
|
+
type: "assignment",
|
|
348
|
+
variableName: "names",
|
|
349
|
+
typeHint: {
|
|
350
|
+
type: "arrayType",
|
|
351
|
+
elementType: { type: "primitiveType", value: "string" },
|
|
352
|
+
},
|
|
353
|
+
value: {
|
|
354
|
+
type: "agencyArray",
|
|
355
|
+
items: [
|
|
356
|
+
{
|
|
357
|
+
type: "string",
|
|
358
|
+
segments: [{ type: "text", value: "Alice" }],
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
type: "string",
|
|
362
|
+
segments: [{ type: "text", value: "Bob" }],
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
// Typed assignments - with whitespace variations
|
|
370
|
+
{
|
|
371
|
+
input: "x:number=5",
|
|
372
|
+
expected: {
|
|
373
|
+
success: true,
|
|
374
|
+
result: {
|
|
375
|
+
type: "assignment",
|
|
376
|
+
variableName: "x",
|
|
377
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
378
|
+
value: { type: "number", value: "5" },
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
input: " y : string = `hello` ",
|
|
384
|
+
expected: {
|
|
385
|
+
success: true,
|
|
386
|
+
result: {
|
|
387
|
+
type: "assignment",
|
|
388
|
+
variableName: "y",
|
|
389
|
+
typeHint: { type: "primitiveType", value: "string" },
|
|
390
|
+
value: {
|
|
391
|
+
type: "prompt",
|
|
392
|
+
segments: [{ type: "text", value: "hello" }],
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
// Typed assignments - with semicolons
|
|
398
|
+
{
|
|
399
|
+
input: "count: number = 42;",
|
|
400
|
+
expected: {
|
|
401
|
+
success: true,
|
|
402
|
+
result: {
|
|
403
|
+
type: "assignment",
|
|
404
|
+
variableName: "count",
|
|
405
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
406
|
+
value: { type: "number", value: "42" },
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
},
|
|
255
410
|
// Failure cases
|
|
256
411
|
{ input: "=5", expected: { success: false } },
|
|
257
412
|
{ input: "x =", expected: { success: false } },
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* import { UsesTool } from "../types/tools.js";
|
|
2
|
+
import { capture, char, many1WithJoin, Parser, seqC, set } from "tarsec";
|
|
3
|
+
import { varNameChar } from "./utils.js";
|
|
4
|
+
|
|
5
|
+
export const usesToolParser: Parser<UsesTool> = seqC(
|
|
6
|
+
set("type", "usesTool"),
|
|
7
|
+
char("+"),
|
|
8
|
+
capture(many1WithJoin(varNameChar), "toolName")
|
|
9
|
+
);
|
|
10
|
+
*/
|
|
11
|
+
import { capture, or, seqC, set, spaces, str } from "tarsec";
|
|
12
|
+
import { accessExpressionParser } from "./access.js";
|
|
13
|
+
import { functionCallParser } from "./functionCall.js";
|
|
14
|
+
import { literalParser } from "./literals.js";
|
|
15
|
+
export const awaitParser = (input) => {
|
|
16
|
+
const parser = seqC(set("type", "awaitStatement"), str("await"), spaces, capture(or(accessExpressionParser, functionCallParser, literalParser), "expression"));
|
|
17
|
+
return parser(input);
|
|
18
|
+
};
|
|
@@ -23,7 +23,10 @@ describe("functionBodyParser", () => {
|
|
|
23
23
|
{
|
|
24
24
|
type: "assignment",
|
|
25
25
|
variableName: "bar",
|
|
26
|
-
value: {
|
|
26
|
+
value: {
|
|
27
|
+
type: "string",
|
|
28
|
+
segments: [{ type: "text", value: "hello" }],
|
|
29
|
+
},
|
|
27
30
|
},
|
|
28
31
|
],
|
|
29
32
|
},
|
|
@@ -41,6 +44,9 @@ describe("functionBodyParser", () => {
|
|
|
41
44
|
segments: [{ type: "text", value: "hello" }],
|
|
42
45
|
},
|
|
43
46
|
},
|
|
47
|
+
{
|
|
48
|
+
type: "newLine",
|
|
49
|
+
},
|
|
44
50
|
{
|
|
45
51
|
type: "variableName",
|
|
46
52
|
value: "foo",
|
|
@@ -58,6 +64,9 @@ describe("functionBodyParser", () => {
|
|
|
58
64
|
variableName: "x",
|
|
59
65
|
value: { type: "number", value: "5" },
|
|
60
66
|
},
|
|
67
|
+
{
|
|
68
|
+
type: "newLine",
|
|
69
|
+
},
|
|
61
70
|
{
|
|
62
71
|
type: "assignment",
|
|
63
72
|
variableName: "y",
|
|
@@ -2,7 +2,7 @@ import { capture, char, manyWithJoin, noneOf, optional, or, sepBy, seqC, set, su
|
|
|
2
2
|
import { accessExpressionParser, indexAccessParser } from "./access.js";
|
|
3
3
|
import { functionCallParser } from "./functionCall.js";
|
|
4
4
|
import { literalParser } from "./literals.js";
|
|
5
|
-
import { comma, optionalSpaces } from "./utils.js";
|
|
5
|
+
import { comma, optionalSpaces, optionalSpacesOrNewline } from "./utils.js";
|
|
6
6
|
export const agencyArrayParser = (input) => {
|
|
7
7
|
const parser = trace("agencyArrayParser", seqC(set("type", "agencyArray"), char("["), capture(sepBy(comma, or(indexAccessParser, accessExpressionParser, functionCallParser, literalParser, agencyObjectParser, agencyArrayParser)), "items"), char("]")));
|
|
8
8
|
return parser(input);
|
|
@@ -11,4 +11,4 @@ export const agencyObjectKVParser = (input) => {
|
|
|
11
11
|
const parser = trace("agencyObjectKVParser", seqC(optionalSpaces, optional(char('"')), capture(manyWithJoin(noneOf('":\n\t ')), "key"), optional(char('"')), optionalSpaces, char(":"), optionalSpaces, capture(or(indexAccessParser, accessExpressionParser, functionCallParser, literalParser, agencyObjectParser, agencyArrayParser), "value")));
|
|
12
12
|
return parser(input);
|
|
13
13
|
};
|
|
14
|
-
export const agencyObjectParser = seqC(set("type", "agencyObject"), char("{"),
|
|
14
|
+
export const agencyObjectParser = seqC(set("type", "agencyObject"), char("{"), optionalSpacesOrNewline, capture(or(sepBy(comma, agencyObjectKVParser), succeed([])), "entries"), optional(char(",")), optionalSpacesOrNewline, char("}"));
|
|
@@ -46,8 +46,8 @@ describe("dataStructures parsers", () => {
|
|
|
46
46
|
result: {
|
|
47
47
|
type: "agencyArray",
|
|
48
48
|
items: [
|
|
49
|
-
{ type: "string", value: "hello" },
|
|
50
|
-
{ type: "string", value: "world" },
|
|
49
|
+
{ type: "string", segments: [{ type: "text", value: "hello" }] },
|
|
50
|
+
{ type: "string", segments: [{ type: "text", value: "world" }] },
|
|
51
51
|
],
|
|
52
52
|
},
|
|
53
53
|
},
|
|
@@ -76,7 +76,7 @@ describe("dataStructures parsers", () => {
|
|
|
76
76
|
type: "agencyArray",
|
|
77
77
|
items: [
|
|
78
78
|
{ type: "number", value: "1" },
|
|
79
|
-
{ type: "string", value: "hello" },
|
|
79
|
+
{ type: "string", segments: [{ type: "text", value: "hello" }] },
|
|
80
80
|
{ type: "variableName", value: "foo" },
|
|
81
81
|
],
|
|
82
82
|
},
|
|
@@ -212,7 +212,7 @@ describe("dataStructures parsers", () => {
|
|
|
212
212
|
success: true,
|
|
213
213
|
result: {
|
|
214
214
|
key: "name",
|
|
215
|
-
value: { type: "string", value: "Alice" },
|
|
215
|
+
value: { type: "string", segments: [{ type: "text", value: "Alice" }] },
|
|
216
216
|
},
|
|
217
217
|
},
|
|
218
218
|
},
|
|
@@ -233,7 +233,7 @@ describe("dataStructures parsers", () => {
|
|
|
233
233
|
success: true,
|
|
234
234
|
result: {
|
|
235
235
|
key: "name",
|
|
236
|
-
value: { type: "string", value: "Alice" },
|
|
236
|
+
value: { type: "string", segments: [{ type: "text", value: "Alice" }] },
|
|
237
237
|
},
|
|
238
238
|
},
|
|
239
239
|
},
|
|
@@ -377,7 +377,7 @@ describe("dataStructures parsers", () => {
|
|
|
377
377
|
entries: [
|
|
378
378
|
{
|
|
379
379
|
key: "name",
|
|
380
|
-
value: { type: "string", value: "Alice" },
|
|
380
|
+
value: { type: "string", segments: [{ type: "text", value: "Alice" }] },
|
|
381
381
|
},
|
|
382
382
|
],
|
|
383
383
|
},
|
|
@@ -412,7 +412,7 @@ describe("dataStructures parsers", () => {
|
|
|
412
412
|
entries: [
|
|
413
413
|
{
|
|
414
414
|
key: "name",
|
|
415
|
-
value: { type: "string", value: "Alice" },
|
|
415
|
+
value: { type: "string", segments: [{ type: "text", value: "Alice" }] },
|
|
416
416
|
},
|
|
417
417
|
{
|
|
418
418
|
key: "age",
|
|
@@ -420,7 +420,7 @@ describe("dataStructures parsers", () => {
|
|
|
420
420
|
},
|
|
421
421
|
{
|
|
422
422
|
key: "city",
|
|
423
|
-
value: { type: "string", value: "NYC" },
|
|
423
|
+
value: { type: "string", segments: [{ type: "text", value: "NYC" }] },
|
|
424
424
|
},
|
|
425
425
|
],
|
|
426
426
|
},
|
|
@@ -608,7 +608,7 @@ describe("dataStructures parsers", () => {
|
|
|
608
608
|
entries: [
|
|
609
609
|
{
|
|
610
610
|
key: "name",
|
|
611
|
-
value: { type: "string", value: "Alice" },
|
|
611
|
+
value: { type: "string", segments: [{ type: "text", value: "Alice" }] },
|
|
612
612
|
},
|
|
613
613
|
{
|
|
614
614
|
key: "age",
|
|
@@ -623,8 +623,8 @@ describe("dataStructures parsers", () => {
|
|
|
623
623
|
value: {
|
|
624
624
|
type: "agencyArray",
|
|
625
625
|
items: [
|
|
626
|
-
{ type: "string", value: "a" },
|
|
627
|
-
{ type: "string", value: "b" },
|
|
626
|
+
{ type: "string", segments: [{ type: "text", value: "a" }] },
|
|
627
|
+
{ type: "string", segments: [{ type: "text", value: "b" }] },
|
|
628
628
|
],
|
|
629
629
|
},
|
|
630
630
|
},
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Parser } from "tarsec";
|
|
1
|
+
import { TimeBlock } from "../types/timeBlock.js";
|
|
2
|
+
import { Parser, ParserResult } from "tarsec";
|
|
3
|
+
import { AgencyNode, Assignment, DocString, FunctionDefinition, FunctionParameter, VariableType } from "../types.js";
|
|
3
4
|
import { GraphNodeDefinition } from "../types/graphNode.js";
|
|
4
5
|
import { WhileLoop } from "../types/whileLoop.js";
|
|
6
|
+
import { IfElse } from "../types/ifElse.js";
|
|
7
|
+
export declare const assignmentParser: Parser<Assignment>;
|
|
5
8
|
export declare const docStringParser: Parser<DocString>;
|
|
6
|
-
export declare const bodyParser:
|
|
9
|
+
export declare const bodyParser: (input: string) => ParserResult<AgencyNode[]>;
|
|
10
|
+
export declare const timeBlockParser: Parser<TimeBlock>;
|
|
11
|
+
export declare const ifParser: Parser<IfElse>;
|
|
7
12
|
export declare const whileLoopParser: Parser<WhileLoop>;
|
|
8
13
|
export declare const functionParameterParserWithTypeHint: Parser<FunctionParameter>;
|
|
9
14
|
export declare const functionParameterParser: Parser<FunctionParameter>;
|
|
@@ -1,26 +1,78 @@
|
|
|
1
|
-
import { capture, captureCaptures, char, debug, many1, many1Till, many1WithJoin, map, optional, or, sepBy, seqC, set, space, spaces, str, succeed, trace, } from "tarsec";
|
|
1
|
+
import { capture, captureCaptures, char, debug, many, many1, many1Till, many1WithJoin, map, optional, or, sepBy, seqC, set, space, spaces, str, succeed, trace, } from "tarsec";
|
|
2
2
|
import { accessExpressionParser, indexAccessParser } from "./access.js";
|
|
3
|
-
import { assignmentParser } from "./assignment.js";
|
|
4
3
|
import { commentParser } from "./comment.js";
|
|
5
4
|
import { functionCallParser } from "./functionCall.js";
|
|
6
5
|
import { literalParser } from "./literals.js";
|
|
7
6
|
import { matchBlockParser } from "./matchBlock.js";
|
|
8
7
|
import { optionalSemicolon } from "./parserUtils.js";
|
|
9
|
-
import { typeAliasParser, typeHintParser, variableTypeParser, } from "./typeHints.js";
|
|
10
|
-
import { comma, optionalSpaces, varNameChar } from "./utils.js";
|
|
11
8
|
import { returnStatementParser } from "./returnStatement.js";
|
|
12
|
-
import { usesToolParser } from "./tools.js";
|
|
13
9
|
import { specialVarParser } from "./specialVar.js";
|
|
10
|
+
import { usesToolParser } from "./tools.js";
|
|
11
|
+
import { typeAliasParser, typeHintParser, variableTypeParser, } from "./typeHints.js";
|
|
12
|
+
import { comma, optionalSpaces, optionalSpacesOrNewline, varNameChar, } from "./utils.js";
|
|
13
|
+
import { agencyArrayParser, agencyObjectParser } from "./dataStructures.js";
|
|
14
|
+
import { awaitParser } from "./await.js";
|
|
15
|
+
import { newLineParser } from "./newline.js";
|
|
16
|
+
export const assignmentParser = (input) => {
|
|
17
|
+
const parser = trace("assignmentParser", seqC(set("type", "assignment"), optionalSpaces, capture(many1WithJoin(varNameChar), "variableName"), optionalSpaces, optional(captureCaptures(seqC(char(":"), optionalSpaces, capture(variableTypeParser, "typeHint")))), optionalSpaces, char("="), optionalSpaces, capture(or(timeBlockParser, awaitParser, functionCallParser, indexAccessParser, accessExpressionParser, agencyArrayParser, agencyObjectParser, literalParser), "value"), optionalSemicolon));
|
|
18
|
+
return parser(input);
|
|
19
|
+
};
|
|
14
20
|
const trim = (s) => s.trim();
|
|
15
21
|
export const docStringParser = trace("docStringParser", seqC(set("type", "docString"), str('"""'), capture(map(many1Till(str('"""')), trim), "value"), str('"""')));
|
|
16
|
-
export const bodyParser =
|
|
17
|
-
const parser =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
22
|
+
export const bodyParser = (input) => {
|
|
23
|
+
const parser = trace("functionBodyParser", many(or(usesToolParser, debug(typeAliasParser, "error in typeAliasParser"), debug(typeHintParser, "error in typeHintParser"), specialVarParser, returnStatementParser, whileLoopParser, matchBlockParser, awaitParser, ifParser, functionParser, accessExpressionParser, assignmentParser, functionCallParser, literalParser, commentParser, newLineParser)));
|
|
24
|
+
return parser(input);
|
|
25
|
+
};
|
|
26
|
+
export const timeBlockParser = trace("timeBlockParser", seqC(set("type", "timeBlock"), str("time"), optionalSpaces, char("{"), spaces, capture(bodyParser, "body"), optionalSpaces, char("}")));
|
|
27
|
+
/* const elseClauseParser: Parser<AgencyNode[]> = seqC(
|
|
28
|
+
str("else"),
|
|
29
|
+
optionalSpaces,
|
|
30
|
+
char("{"),
|
|
31
|
+
spaces,
|
|
32
|
+
captureCaptures(bodyParser),
|
|
33
|
+
optionalSpaces,
|
|
34
|
+
char("}"),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const ifElseParser: Parser<IfElse> = (input: string) => {
|
|
38
|
+
const parser = trace(
|
|
39
|
+
"ifElseParser",
|
|
40
|
+
seqC(
|
|
41
|
+
set("type", "ifElse"),
|
|
42
|
+
str("if"),
|
|
43
|
+
optionalSpaces,
|
|
44
|
+
char("("),
|
|
45
|
+
optionalSpaces,
|
|
46
|
+
capture(
|
|
47
|
+
or(
|
|
48
|
+
indexAccessParser,
|
|
49
|
+
functionCallParser,
|
|
50
|
+
accessExpressionParser,
|
|
51
|
+
literalParser,
|
|
52
|
+
),
|
|
53
|
+
"condition",
|
|
54
|
+
),
|
|
55
|
+
optionalSpaces,
|
|
56
|
+
char(")"),
|
|
57
|
+
optionalSpaces,
|
|
58
|
+
char("{"),
|
|
59
|
+
spaces,
|
|
60
|
+
capture(bodyParser, "thenBody"),
|
|
61
|
+
optionalSpaces,
|
|
62
|
+
char("}"),
|
|
63
|
+
optionalSpaces,
|
|
64
|
+
capture(optional(elseClauseParser), "elseBody"),
|
|
65
|
+
),
|
|
66
|
+
);
|
|
67
|
+
return parser(input);
|
|
68
|
+
}; */
|
|
69
|
+
export const ifParser = (input) => {
|
|
70
|
+
const parser = trace("ifParser", seqC(set("type", "ifElse"), str("if"), optionalSpaces, char("("), optionalSpaces, capture(or(accessExpressionParser, functionCallParser, literalParser), "condition"), optionalSpaces, char(")"), optionalSpaces, char("{"), spaces, capture(bodyParser, "thenBody"), optionalSpaces, char("}")));
|
|
71
|
+
return parser(input);
|
|
72
|
+
};
|
|
21
73
|
export const whileLoopParser = trace("whileLoopParser", seqC(set("type", "whileLoop"), str("while"), optionalSpaces, char("("), optionalSpaces, capture(or(indexAccessParser, functionCallParser, accessExpressionParser, literalParser), "condition"), optionalSpaces, char(")"), optionalSpaces, char("{"), spaces, capture(bodyParser, "body"), optionalSpaces, char("}")));
|
|
22
74
|
export const functionParameterParserWithTypeHint = trace("functionParameterParserWithTypeHint", seqC(set("type", "functionParameter"), capture(many1WithJoin(varNameChar), "name"), optionalSpaces, char(":"), optionalSpaces, capture(variableTypeParser, "typeHint")));
|
|
23
75
|
export const functionParameterParser = trace("functionParameterParser", seqC(set("type", "functionParameter"), capture(many1WithJoin(varNameChar), "name")));
|
|
24
76
|
export const functionReturnTypeParser = trace("functionReturnTypeParser", seqC(char(":"), optionalSpaces, captureCaptures(variableTypeParser)));
|
|
25
|
-
export const functionParser = trace("functionParser", seqC(set("type", "function"), str("def"), many1(space), capture(many1Till(char("(")), "functionName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"),
|
|
26
|
-
export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(
|
|
77
|
+
export const functionParser = trace("functionParser", seqC(set("type", "function"), str("def"), many1(space), capture(many1Till(char("(")), "functionName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpacesOrNewline, capture(or(docStringParser, succeed(undefined)), "docString"), optionalSpacesOrNewline, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
|
|
78
|
+
export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(sepBy(comma, or(functionParameterParserWithTypeHint, functionParameterParser)), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpacesOrNewline, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
|