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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SpecialVar } from "../types/specialVar.js";
|
|
2
|
-
import { AgencyComment, AgencyProgram, Assignment, Literal, PromptLiteral, TypeAlias, TypeHint, VariableType } from "../types.js";
|
|
2
|
+
import { AgencyComment, AgencyProgram, Assignment, Literal, NewLine, PromptLiteral, TypeAlias, TypeHint, VariableType } from "../types.js";
|
|
3
3
|
import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
|
|
4
4
|
import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
|
|
5
5
|
import { FunctionCall, FunctionDefinition } from "../types/function.js";
|
|
@@ -9,7 +9,10 @@ import { MatchBlock } from "../types/matchBlock.js";
|
|
|
9
9
|
import { ReturnStatement } from "../types/returnStatement.js";
|
|
10
10
|
import { UsesTool } from "../types/tools.js";
|
|
11
11
|
import { WhileLoop } from "../types/whileLoop.js";
|
|
12
|
+
import { IfElse } from "../types/ifElse.js";
|
|
12
13
|
import { BaseGenerator } from "./baseGenerator.js";
|
|
14
|
+
import { TimeBlock } from "../types/timeBlock.js";
|
|
15
|
+
import { AwaitStatement } from "../types/await.js";
|
|
13
16
|
export declare class AgencyGenerator extends BaseGenerator {
|
|
14
17
|
private indentLevel;
|
|
15
18
|
private indentSize;
|
|
@@ -25,9 +28,11 @@ export declare class AgencyGenerator extends BaseGenerator {
|
|
|
25
28
|
protected processTypeAlias(node: TypeAlias): string;
|
|
26
29
|
protected processTypeHint(node: TypeHint): string;
|
|
27
30
|
protected processAssignment(node: Assignment): string;
|
|
31
|
+
protected processTimeBlock(node: TimeBlock): string;
|
|
28
32
|
protected generateLiteral(literal: Literal): string;
|
|
29
33
|
private generatePromptLiteral;
|
|
30
|
-
|
|
34
|
+
private generateStringLiteral;
|
|
35
|
+
protected processPromptLiteral(variableName: string, variableType: VariableType | undefined, node: PromptLiteral): string;
|
|
31
36
|
protected processFunctionDefinition(node: FunctionDefinition): string;
|
|
32
37
|
protected processFunctionCall(node: FunctionCall): string;
|
|
33
38
|
protected generateFunctionCallExpression(node: FunctionCall): string;
|
|
@@ -39,6 +44,7 @@ export declare class AgencyGenerator extends BaseGenerator {
|
|
|
39
44
|
protected processDotFunctionCall(node: DotFunctionCall): string;
|
|
40
45
|
protected processMatchBlock(node: MatchBlock): string;
|
|
41
46
|
protected processWhileLoop(node: WhileLoop): string;
|
|
47
|
+
protected processIfElse(node: IfElse): string;
|
|
42
48
|
protected processReturnStatement(node: ReturnStatement): string;
|
|
43
49
|
protected processComment(node: AgencyComment): string;
|
|
44
50
|
protected processImportStatement(node: ImportStatement): string;
|
|
@@ -47,5 +53,7 @@ export declare class AgencyGenerator extends BaseGenerator {
|
|
|
47
53
|
protected processUsesTool(node: UsesTool): string;
|
|
48
54
|
protected processSpecialVar(node: SpecialVar): string;
|
|
49
55
|
private indentStr;
|
|
56
|
+
protected processAwaitStatement(node: AwaitStatement): string;
|
|
57
|
+
protected processNewLine(_node: NewLine): string;
|
|
50
58
|
}
|
|
51
59
|
export declare function generateAgency(program: AgencyProgram): string;
|
|
@@ -48,26 +48,41 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
48
48
|
processTypeAlias(node) {
|
|
49
49
|
this.typeAliases[node.aliasName] = node.aliasedType;
|
|
50
50
|
const aliasedTypeStr = this.aliasedTypeToString(node.aliasedType);
|
|
51
|
-
return this.indentStr(`type ${node.aliasName} = ${aliasedTypeStr}
|
|
51
|
+
return this.indentStr(`type ${node.aliasName} = ${aliasedTypeStr}`);
|
|
52
52
|
}
|
|
53
53
|
processTypeHint(node) {
|
|
54
54
|
this.typeHints[node.variableName] = node.variableType;
|
|
55
55
|
const typeStr = variableTypeToString(node.variableType, this.typeAliases);
|
|
56
|
-
return this.indentStr(`${node.variableName} :: ${typeStr}
|
|
56
|
+
return this.indentStr(`${node.variableName} :: ${typeStr}`);
|
|
57
57
|
}
|
|
58
58
|
// Assignment and literals
|
|
59
59
|
processAssignment(node) {
|
|
60
|
-
const
|
|
61
|
-
|
|
60
|
+
const varName = node.typeHint
|
|
61
|
+
? `${node.variableName}: ${variableTypeToString(node.typeHint, this.typeAliases)}`
|
|
62
|
+
: node.variableName;
|
|
63
|
+
if (node.value.type === "timeBlock") {
|
|
64
|
+
const code = this.processTimeBlock(node.value);
|
|
65
|
+
return this.indentStr(`${varName} = ${code.trim()}\n`);
|
|
66
|
+
}
|
|
67
|
+
let valueCode = this.processNode(node.value).trim();
|
|
68
|
+
return this.indentStr(`${varName} = ${valueCode}`);
|
|
69
|
+
}
|
|
70
|
+
processTimeBlock(node) {
|
|
71
|
+
this.increaseIndent();
|
|
72
|
+
const bodyCodes = [];
|
|
73
|
+
for (const stmt of node.body) {
|
|
74
|
+
bodyCodes.push(this.processNode(stmt));
|
|
75
|
+
}
|
|
76
|
+
this.decreaseIndent();
|
|
77
|
+
const bodyCodeStr = bodyCodes.join("");
|
|
78
|
+
return `time {\n${bodyCodeStr}${this.indentStr("}")}\n`;
|
|
62
79
|
}
|
|
63
80
|
generateLiteral(literal) {
|
|
64
81
|
switch (literal.type) {
|
|
65
82
|
case "number":
|
|
66
83
|
return literal.value;
|
|
67
84
|
case "string":
|
|
68
|
-
|
|
69
|
-
const escaped = literal.value;
|
|
70
|
-
return `"${escaped}"`;
|
|
85
|
+
return this.generateStringLiteral(literal);
|
|
71
86
|
case "variableName":
|
|
72
87
|
return literal.value;
|
|
73
88
|
case "multiLineString":
|
|
@@ -92,7 +107,20 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
92
107
|
result += "`";
|
|
93
108
|
return result;
|
|
94
109
|
}
|
|
95
|
-
|
|
110
|
+
generateStringLiteral(node) {
|
|
111
|
+
let result = '"';
|
|
112
|
+
for (const segment of node.segments) {
|
|
113
|
+
if (segment.type === "text") {
|
|
114
|
+
result += segment.value;
|
|
115
|
+
}
|
|
116
|
+
else if (segment.type === "interpolation") {
|
|
117
|
+
result += `\${${segment.variableName}}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
result += '"';
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
processPromptLiteral(variableName, variableType, node) {
|
|
96
124
|
// For agency code, prompts are just part of assignments
|
|
97
125
|
// This shouldn't be called directly, but return empty string
|
|
98
126
|
return "";
|
|
@@ -135,12 +163,12 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
135
163
|
this.functionScopedVariables = [];
|
|
136
164
|
this.decreaseIndent();
|
|
137
165
|
// Close function
|
|
138
|
-
result += this.indentStr(`}
|
|
166
|
+
result += this.indentStr(`}`);
|
|
139
167
|
return result;
|
|
140
168
|
}
|
|
141
169
|
processFunctionCall(node) {
|
|
142
170
|
const expr = this.generateFunctionCallExpression(node);
|
|
143
|
-
return this.indentStr(`${expr}
|
|
171
|
+
return this.indentStr(`${expr}`);
|
|
144
172
|
}
|
|
145
173
|
generateFunctionCallExpression(node) {
|
|
146
174
|
const args = node.arguments.map((arg) => {
|
|
@@ -160,7 +188,10 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
160
188
|
const valueCode = this.processNode(entry.value).trim();
|
|
161
189
|
return `${entry.key}: ${valueCode}`;
|
|
162
190
|
});
|
|
163
|
-
|
|
191
|
+
if (entries.length === 0) {
|
|
192
|
+
return `{}`;
|
|
193
|
+
}
|
|
194
|
+
return `{ ${entries.join(", ")} }`;
|
|
164
195
|
}
|
|
165
196
|
// Access expressions
|
|
166
197
|
processAccessExpression(node) {
|
|
@@ -176,17 +207,17 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
176
207
|
processDotProperty(node) {
|
|
177
208
|
let objectCode = this.processNode(node.object);
|
|
178
209
|
objectCode = objectCode.trim();
|
|
179
|
-
return `${objectCode}.${node.propertyName}
|
|
210
|
+
return this.indentStr(`${objectCode}.${node.propertyName}`);
|
|
180
211
|
}
|
|
181
212
|
processIndexAccess(node) {
|
|
182
213
|
const arrayCode = this.processNode(node.array).trim();
|
|
183
214
|
const indexCode = this.processNode(node.index).trim();
|
|
184
|
-
return `${arrayCode}[${indexCode}]
|
|
215
|
+
return this.indentStr(`${arrayCode}[${indexCode}]`);
|
|
185
216
|
}
|
|
186
217
|
processDotFunctionCall(node) {
|
|
187
218
|
const objectCode = this.processNode(node.object).trim();
|
|
188
219
|
const functionCallCode = this.generateFunctionCallExpression(node.functionCall);
|
|
189
|
-
return `${objectCode}.${functionCallCode}
|
|
220
|
+
return this.indentStr(`${objectCode}.${functionCallCode}`);
|
|
190
221
|
}
|
|
191
222
|
// Control flow
|
|
192
223
|
processMatchBlock(node) {
|
|
@@ -222,27 +253,56 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
222
253
|
result += this.indentStr(`}\n`);
|
|
223
254
|
return result;
|
|
224
255
|
}
|
|
256
|
+
processIfElse(node) {
|
|
257
|
+
const conditionCode = this.processNode(node.condition).trim();
|
|
258
|
+
const lines = [];
|
|
259
|
+
lines.push(this.indentStr(`if (${conditionCode}) {\n`));
|
|
260
|
+
const bodyLines = [];
|
|
261
|
+
this.increaseIndent();
|
|
262
|
+
for (const stmt of node.thenBody) {
|
|
263
|
+
bodyLines.push(this.processNode(stmt));
|
|
264
|
+
}
|
|
265
|
+
this.decreaseIndent();
|
|
266
|
+
lines.push(bodyLines.join("").trimEnd() + "\n");
|
|
267
|
+
const elseBodyLines = [];
|
|
268
|
+
if (node.elseBody && node.elseBody.length > 0) {
|
|
269
|
+
lines.push(this.indentStr(`} else {\n`));
|
|
270
|
+
this.increaseIndent();
|
|
271
|
+
for (const stmt of node.elseBody) {
|
|
272
|
+
elseBodyLines.push(this.processNode(stmt));
|
|
273
|
+
}
|
|
274
|
+
this.decreaseIndent();
|
|
275
|
+
lines.push(elseBodyLines.join("").trimEnd() + "\n");
|
|
276
|
+
}
|
|
277
|
+
lines.push(this.indentStr(`}\n\n`));
|
|
278
|
+
return lines.join("");
|
|
279
|
+
}
|
|
225
280
|
processReturnStatement(node) {
|
|
226
281
|
const valueCode = this.processNode(node.value).trim();
|
|
227
282
|
return this.indentStr(`return ${valueCode}\n`);
|
|
228
283
|
}
|
|
229
284
|
// Utility methods
|
|
230
285
|
processComment(node) {
|
|
231
|
-
return this.indentStr(`//${node.content}
|
|
286
|
+
return this.indentStr(`//${node.content}`);
|
|
232
287
|
}
|
|
233
288
|
processImportStatement(node) {
|
|
234
|
-
|
|
289
|
+
const str = this.indentStr(`import ${node.importedNames}from ${node.modulePath}`);
|
|
290
|
+
return str;
|
|
235
291
|
}
|
|
236
292
|
processGraphNode(node) {
|
|
237
293
|
// Graph nodes use similar syntax to functions
|
|
238
294
|
const { nodeName, body, parameters } = node;
|
|
239
|
-
const params = parameters
|
|
295
|
+
const params = parameters
|
|
296
|
+
.map((p) => p.typeHint
|
|
297
|
+
? `${p.name}: ${variableTypeToString(p.typeHint, this.typeAliases)}`
|
|
298
|
+
: p.name)
|
|
299
|
+
.join(", ");
|
|
240
300
|
const returnTypeStr = node.returnType
|
|
241
301
|
? ": " + variableTypeToString(node.returnType, this.typeAliases)
|
|
242
302
|
: "";
|
|
243
303
|
let result = this.indentStr(`node ${nodeName}(${params})${returnTypeStr} {\n`);
|
|
244
304
|
this.increaseIndent();
|
|
245
|
-
this.functionScopedVariables =
|
|
305
|
+
this.functionScopedVariables = parameters.map((p) => p.name);
|
|
246
306
|
const lines = [];
|
|
247
307
|
for (const stmt of body) {
|
|
248
308
|
lines.push(this.processNode(stmt));
|
|
@@ -251,7 +311,7 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
251
311
|
result += bodyCode;
|
|
252
312
|
this.functionScopedVariables = [];
|
|
253
313
|
this.decreaseIndent();
|
|
254
|
-
result += this.indentStr(`}
|
|
314
|
+
result += this.indentStr(`}`);
|
|
255
315
|
return result;
|
|
256
316
|
}
|
|
257
317
|
processTool(node) {
|
|
@@ -262,7 +322,7 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
262
322
|
processUsesTool(node) {
|
|
263
323
|
// Track tool usage but don't generate code
|
|
264
324
|
this.toolsUsed.push(node.toolName);
|
|
265
|
-
return this.indentStr(`+${node.toolName}
|
|
325
|
+
return this.indentStr(`+${node.toolName}`);
|
|
266
326
|
}
|
|
267
327
|
processSpecialVar(node) {
|
|
268
328
|
return this.indentStr(`@${node.name} = ${this.processNode(node.value).trim()}\n`);
|
|
@@ -270,6 +330,13 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
270
330
|
indentStr(str) {
|
|
271
331
|
return `${this.indent()}${str}`;
|
|
272
332
|
}
|
|
333
|
+
processAwaitStatement(node) {
|
|
334
|
+
const code = this.processNode(node.expression);
|
|
335
|
+
return this.indentStr(`await ${code.trim()}`);
|
|
336
|
+
}
|
|
337
|
+
processNewLine(_node) {
|
|
338
|
+
return "\n";
|
|
339
|
+
}
|
|
273
340
|
}
|
|
274
341
|
export function generateAgency(program) {
|
|
275
342
|
const generator = new AgencyGenerator();
|
|
@@ -70,54 +70,6 @@ describe("AgencyGenerator - Function Parameter Type Hints", () => {
|
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
-
describe("Round-trip parsing", () => {
|
|
74
|
-
const testCases = [
|
|
75
|
-
{
|
|
76
|
-
description: "function with typed parameters",
|
|
77
|
-
input: "def add(x: number, y: number) { x }",
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
description: "function with mixed parameters",
|
|
81
|
-
input: "def mixed(a: string, b) { a }",
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
description: "function with array type",
|
|
85
|
-
input: "def process(items: number[]) { items }",
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
description: "function with union type",
|
|
89
|
-
input: "def flex(val: string | number) { val }",
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
description: "function with complex types",
|
|
93
|
-
input: "def complex(arr: string[], count: number, flag: boolean) { arr }",
|
|
94
|
-
},
|
|
95
|
-
];
|
|
96
|
-
testCases.forEach(({ description, input }) => {
|
|
97
|
-
it(`should preserve ${description} in round-trip`, () => {
|
|
98
|
-
// First parse
|
|
99
|
-
const firstParse = parseAgency(input);
|
|
100
|
-
expect(firstParse.success).toBe(true);
|
|
101
|
-
if (!firstParse.success)
|
|
102
|
-
return;
|
|
103
|
-
// Generate agency code
|
|
104
|
-
const generator = new AgencyGenerator();
|
|
105
|
-
const generated = generator.generate(firstParse.result);
|
|
106
|
-
// Second parse
|
|
107
|
-
const secondParse = parseAgency(generated.output);
|
|
108
|
-
expect(secondParse.success).toBe(true);
|
|
109
|
-
if (!secondParse.success)
|
|
110
|
-
return;
|
|
111
|
-
// Compare the function nodes - they should be identical
|
|
112
|
-
const firstFunc = firstParse.result.nodes[0];
|
|
113
|
-
const secondFunc = secondParse.result.nodes[0];
|
|
114
|
-
expect(secondFunc.type).toBe("function");
|
|
115
|
-
expect(secondFunc.functionName).toBe(firstFunc.functionName);
|
|
116
|
-
expect(secondFunc.parameters).toEqual(firstFunc.parameters);
|
|
117
|
-
expect(secondFunc.body).toEqual(firstFunc.body);
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
73
|
describe("Type preservation", () => {
|
|
122
74
|
it("should preserve primitive types", () => {
|
|
123
75
|
const input = "def test(n: number, s: string, b: boolean) { n }";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SpecialVar } from "../types/specialVar.js";
|
|
2
|
-
import { AgencyComment, AgencyNode, AgencyProgram, Assignment, Literal, PromptLiteral, TypeAlias, TypeHint, TypeHintMap, VariableType } from "../types.js";
|
|
2
|
+
import { AgencyComment, AgencyNode, AgencyProgram, Assignment, Literal, NewLine, PromptLiteral, TypeAlias, TypeHint, TypeHintMap, VariableType } from "../types.js";
|
|
3
3
|
import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
|
|
4
4
|
import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
|
|
5
5
|
import { FunctionCall, FunctionDefinition } from "../types/function.js";
|
|
@@ -9,6 +9,9 @@ import { MatchBlock } from "../types/matchBlock.js";
|
|
|
9
9
|
import { ReturnStatement } from "../types/returnStatement.js";
|
|
10
10
|
import { UsesTool } from "../types/tools.js";
|
|
11
11
|
import { WhileLoop } from "../types/whileLoop.js";
|
|
12
|
+
import { IfElse } from "../types/ifElse.js";
|
|
13
|
+
import { TimeBlock } from "../types/timeBlock.js";
|
|
14
|
+
import { AwaitStatement } from "../types/await.js";
|
|
12
15
|
export declare class BaseGenerator {
|
|
13
16
|
protected typeHints: TypeHintMap;
|
|
14
17
|
protected graphNodes: GraphNodeDefinition[];
|
|
@@ -20,19 +23,23 @@ export declare class BaseGenerator {
|
|
|
20
23
|
protected typeAliases: Record<string, VariableType>;
|
|
21
24
|
protected functionsUsed: Set<string>;
|
|
22
25
|
protected importStatements: string[];
|
|
23
|
-
protected
|
|
24
|
-
constructor();
|
|
26
|
+
protected functionDefinitions: Record<string, FunctionDefinition>;
|
|
25
27
|
generate(program: AgencyProgram): {
|
|
26
28
|
output: string;
|
|
27
29
|
};
|
|
30
|
+
addIfNonEmpty(str: string, lines: string[]): void;
|
|
28
31
|
protected generateBuiltins(): string;
|
|
29
32
|
protected processTypeAlias(node: TypeAlias): string;
|
|
30
33
|
protected processTypeHint(node: TypeHint): string;
|
|
31
34
|
protected collectFunctionSignature(node: FunctionDefinition): void;
|
|
32
35
|
protected processGraphNodeName(node: GraphNodeDefinition): void;
|
|
33
36
|
protected processNode(node: AgencyNode): string;
|
|
37
|
+
protected processNewLine(_node: NewLine): string;
|
|
38
|
+
protected processAwaitStatement(node: AwaitStatement): string;
|
|
39
|
+
protected processTimeBlock(node: TimeBlock, timingVarName: string): string;
|
|
34
40
|
protected processSpecialVar(node: SpecialVar): string;
|
|
35
41
|
protected processWhileLoop(node: WhileLoop): string;
|
|
42
|
+
protected processIfElse(node: IfElse): string;
|
|
36
43
|
protected processImportStatement(node: ImportStatement): string;
|
|
37
44
|
protected processTool(node: FunctionDefinition): string;
|
|
38
45
|
protected processUsesTool(node: UsesTool): string;
|
|
@@ -47,7 +54,7 @@ export declare class BaseGenerator {
|
|
|
47
54
|
protected processDotFunctionCall(node: DotFunctionCall): string;
|
|
48
55
|
protected processIndexAccess(node: IndexAccess): string;
|
|
49
56
|
protected processAssignment(node: Assignment): string;
|
|
50
|
-
protected processPromptLiteral(variableName: string, node: PromptLiteral): string;
|
|
57
|
+
protected processPromptLiteral(variableName: string, typeHint: VariableType | undefined, node: PromptLiteral): string;
|
|
51
58
|
protected processFunctionDefinition(node: FunctionDefinition): string;
|
|
52
59
|
protected processFunctionCall(node: FunctionCall): string;
|
|
53
60
|
protected generateFunctionCallExpression(node: FunctionCall): string;
|
|
@@ -12,8 +12,8 @@ export class BaseGenerator {
|
|
|
12
12
|
functionsUsed = new Set();
|
|
13
13
|
importStatements = [];
|
|
14
14
|
// collect function signatures so we can implement named args
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// TODO also save return types, check if used as a tool, return type cannot be null/void/undefined
|
|
16
|
+
functionDefinitions = {};
|
|
17
17
|
generate(program) {
|
|
18
18
|
// Pass 1: Collect all type aliases
|
|
19
19
|
for (const node of program.nodes) {
|
|
@@ -52,18 +52,22 @@ export class BaseGenerator {
|
|
|
52
52
|
this.generatedStatements.push(result);
|
|
53
53
|
}
|
|
54
54
|
const output = [];
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
output.push("\n");
|
|
55
|
+
this.addIfNonEmpty(this.preprocess(), output);
|
|
56
|
+
this.addIfNonEmpty(this.importStatements.join("\n"), output);
|
|
57
|
+
this.addIfNonEmpty(this.generateImports(), output);
|
|
58
|
+
this.addIfNonEmpty(this.generateBuiltins(), output);
|
|
60
59
|
output.push(...this.generatedTypeAliases);
|
|
61
60
|
output.push(this.generatedStatements.join(""));
|
|
62
|
-
|
|
61
|
+
this.addIfNonEmpty(this.postprocess(), output);
|
|
63
62
|
return {
|
|
64
|
-
output: output.filter((line) => line.trim() !== "").join("\n"),
|
|
63
|
+
output: output.join("\n"), //filter((line) => line.trim() !== "").join("\n"),
|
|
65
64
|
};
|
|
66
65
|
}
|
|
66
|
+
addIfNonEmpty(str, lines) {
|
|
67
|
+
if (str.trim() !== "") {
|
|
68
|
+
lines.push(str);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
67
71
|
generateBuiltins() {
|
|
68
72
|
return "";
|
|
69
73
|
}
|
|
@@ -76,7 +80,7 @@ export class BaseGenerator {
|
|
|
76
80
|
return "";
|
|
77
81
|
}
|
|
78
82
|
collectFunctionSignature(node) {
|
|
79
|
-
this.
|
|
83
|
+
this.functionDefinitions[node.functionName] = node;
|
|
80
84
|
}
|
|
81
85
|
processGraphNodeName(node) { }
|
|
82
86
|
processNode(node) {
|
|
@@ -119,20 +123,40 @@ export class BaseGenerator {
|
|
|
119
123
|
return "";
|
|
120
124
|
case "whileLoop":
|
|
121
125
|
return this.processWhileLoop(node);
|
|
126
|
+
case "ifElse":
|
|
127
|
+
return this.processIfElse(node);
|
|
122
128
|
case "specialVar":
|
|
123
129
|
return this.processSpecialVar(node);
|
|
124
130
|
case "indexAccess":
|
|
125
131
|
return this.processIndexAccess(node);
|
|
132
|
+
case "timeBlock":
|
|
133
|
+
throw new Error(`Time block needs to be assigned to a variable: ${JSON.stringify(node)}`);
|
|
134
|
+
case "awaitStatement":
|
|
135
|
+
return this.processAwaitStatement(node);
|
|
136
|
+
case "newLine":
|
|
137
|
+
return this.processNewLine(node);
|
|
126
138
|
default:
|
|
127
139
|
throw new Error(`Unhandled Agency node type: ${node.type}`);
|
|
128
140
|
}
|
|
129
141
|
}
|
|
142
|
+
processNewLine(_node) {
|
|
143
|
+
return "";
|
|
144
|
+
}
|
|
145
|
+
processAwaitStatement(node) {
|
|
146
|
+
return "processAwaitStatement not implemented";
|
|
147
|
+
}
|
|
148
|
+
processTimeBlock(node, timingVarName) {
|
|
149
|
+
return "processTimeBlock not implemented";
|
|
150
|
+
}
|
|
130
151
|
processSpecialVar(node) {
|
|
131
152
|
return "processSpecialVar not implemented";
|
|
132
153
|
}
|
|
133
154
|
processWhileLoop(node) {
|
|
134
155
|
return "processWhileLoop not implemented";
|
|
135
156
|
}
|
|
157
|
+
processIfElse(node) {
|
|
158
|
+
return "processIfElse not implemented";
|
|
159
|
+
}
|
|
136
160
|
processImportStatement(node) {
|
|
137
161
|
return "processImportStatement not implemented";
|
|
138
162
|
}
|
|
@@ -182,7 +206,7 @@ export class BaseGenerator {
|
|
|
182
206
|
processAssignment(node) {
|
|
183
207
|
return "processAssignment not implemented";
|
|
184
208
|
}
|
|
185
|
-
processPromptLiteral(variableName, node) {
|
|
209
|
+
processPromptLiteral(variableName, typeHint, node) {
|
|
186
210
|
return "processPromptLiteral not implemented";
|
|
187
211
|
}
|
|
188
212
|
processFunctionDefinition(node) {
|