agency-lang 0.0.16 → 0.0.18

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.
@@ -66,12 +66,13 @@ export class AgencyGenerator extends BaseGenerator {
66
66
  return literal.value;
67
67
  case "string":
68
68
  // Escape backslashes and quotes
69
- const escaped = literal.value
70
- .replace(/\\/g, "\\\\")
71
- .replace(/"/g, '\\"');
69
+ const escaped = literal.value;
72
70
  return `"${escaped}"`;
73
71
  case "variableName":
74
72
  return literal.value;
73
+ case "multiLineString":
74
+ const escapedMultiLine = literal.value;
75
+ return `"""${escapedMultiLine}"""`;
75
76
  case "prompt":
76
77
  return this.generatePromptLiteral(literal);
77
78
  default:
@@ -111,8 +112,11 @@ export class AgencyGenerator extends BaseGenerator {
111
112
  }
112
113
  })
113
114
  .join(", ");
115
+ const returnTypeStr = node.returnType
116
+ ? ": " + variableTypeToString(node.returnType, this.typeAliases)
117
+ : "";
114
118
  // Start function definition
115
- let result = this.indentStr(`def ${functionName}(${params}) {\n`);
119
+ let result = this.indentStr(`def ${functionName}(${params})${returnTypeStr} {\n`);
116
120
  // Process body with increased indentation
117
121
  this.increaseIndent();
118
122
  if (node.docString) {
@@ -233,7 +237,10 @@ export class AgencyGenerator extends BaseGenerator {
233
237
  // Graph nodes use similar syntax to functions
234
238
  const { nodeName, body, parameters } = node;
235
239
  const params = parameters.join(", ");
236
- let result = this.indentStr(`node ${nodeName}(${params}) {\n`);
240
+ const returnTypeStr = node.returnType
241
+ ? ": " + variableTypeToString(node.returnType, this.typeAliases)
242
+ : "";
243
+ let result = this.indentStr(`node ${nodeName}(${params})${returnTypeStr} {\n`);
237
244
  this.increaseIndent();
238
245
  this.functionScopedVariables = [...parameters];
239
246
  const lines = [];
@@ -244,7 +251,7 @@ export class AgencyGenerator extends BaseGenerator {
244
251
  result += bodyCode;
245
252
  this.functionScopedVariables = [];
246
253
  this.decreaseIndent();
247
- result += this.indentStr(`}\n`);
254
+ result += this.indentStr(`}\n\n`);
248
255
  return result;
249
256
  }
250
257
  processTool(node) {
@@ -11,10 +11,11 @@ import { UsesTool } from "../types/tools.js";
11
11
  import { WhileLoop } from "../types/whileLoop.js";
12
12
  export declare class BaseGenerator {
13
13
  protected typeHints: TypeHintMap;
14
- protected graphNodes: string[];
14
+ protected graphNodes: GraphNodeDefinition[];
15
15
  protected generatedStatements: string[];
16
16
  protected generatedTypeAliases: string[];
17
17
  protected functionScopedVariables: string[];
18
+ protected globalScopedVariables: string[];
18
19
  protected toolsUsed: string[];
19
20
  protected typeAliases: Record<string, VariableType>;
20
21
  protected functionsUsed: Set<string>;
@@ -4,6 +4,7 @@ export class BaseGenerator {
4
4
  generatedStatements = [];
5
5
  generatedTypeAliases = [];
6
6
  functionScopedVariables = [];
7
+ globalScopedVariables = [];
7
8
  // collect tools for a prompt
8
9
  toolsUsed = [];
9
10
  typeAliases = {};
@@ -39,7 +40,13 @@ export class BaseGenerator {
39
40
  this.collectFunctionSignature(node);
40
41
  }
41
42
  }
42
- // Pass 5: Process all nodes and generate code
43
+ // Pass 5: Collect global scoped variables
44
+ for (const node of program.nodes) {
45
+ if (node.type === "assignment") {
46
+ this.globalScopedVariables.push(node.variableName);
47
+ }
48
+ }
49
+ // Pass 6: Process all nodes and generate code
43
50
  for (const node of program.nodes) {
44
51
  const result = this.processNode(node);
45
52
  this.generatedStatements.push(result);
@@ -91,6 +98,7 @@ export class BaseGenerator {
91
98
  case "matchBlock":
92
99
  return this.processMatchBlock(node);
93
100
  case "number":
101
+ case "multiLineString":
94
102
  case "string":
95
103
  case "variableName":
96
104
  case "prompt":
@@ -7,6 +7,7 @@ import * as renderStartNode from "../templates/backends/graphGenerator/startNode
7
7
  import * as renderRunNodeFunction from "../templates/backends/graphGenerator/runNodeFunction.js";
8
8
  import { TypeScriptGenerator } from "./typescriptGenerator.js";
9
9
  import { mapFunctionName } from "./typescriptGenerator/builtins.js";
10
+ import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
10
11
  export class GraphGenerator extends TypeScriptGenerator {
11
12
  typeHints = {};
12
13
  generatedStatements = [];
@@ -203,7 +204,7 @@ export class GraphGenerator extends TypeScriptGenerator {
203
204
  else {
204
205
  const returnCode = this.processNode(node.value);
205
206
  if (node.value.type === "functionCall" &&
206
- this.graphNodes.includes(node.value.functionName)) {
207
+ this.graphNodes.map((n) => n.nodeName).includes(node.value.functionName)) {
207
208
  // we're going to return a goToNode call, so just return that directly
208
209
  return `return ${returnCode}\n`;
209
210
  }
@@ -211,7 +212,7 @@ export class GraphGenerator extends TypeScriptGenerator {
211
212
  }
212
213
  }
213
214
  processGraphNodeName(node) {
214
- this.graphNodes.push(node.nodeName);
215
+ this.graphNodes.push(node);
215
216
  }
216
217
  processGraphNode(node) {
217
218
  const { nodeName, body, parameters } = node;
@@ -234,13 +235,16 @@ export class GraphGenerator extends TypeScriptGenerator {
234
235
  this.isInsideGraphNode = false;
235
236
  return graphNode.default({
236
237
  name: nodeName,
238
+ /* returnType: node.returnType
239
+ ? variableTypeToString(node.returnType, this.typeAliases)
240
+ : "any", */
237
241
  body: bodyCode.join("\n"),
238
242
  hasParam: parameters.length > 0,
239
243
  paramName: parameters[0] || "input",
240
244
  });
241
245
  }
242
246
  processFunctionCall(node) {
243
- if (this.graphNodes.includes(node.functionName)) {
247
+ if (this.graphNodes.map((n) => n.nodeName).includes(node.functionName)) {
244
248
  this.currentAdjacentNodes.push(node.functionName);
245
249
  this.functionsUsed.add(node.functionName);
246
250
  const functionCallCode = this.generateNodeCallExpression(node);
@@ -258,10 +262,11 @@ export class GraphGenerator extends TypeScriptGenerator {
258
262
  this.functionsUsed.add(arg.functionName);
259
263
  return this.generateFunctionCallExpression(arg);
260
264
  /* } else if (arg.type === "accessExpression") {
261
- return this.processAccessExpression(arg);
262
- } else if (arg.type === "indexAccess") {
263
- return this.processIndexAccess(arg);
264
- */ }
265
+ return this.processAccessExpression(arg);
266
+ } else if (arg.type === "indexAccess") {
267
+ return this.processIndexAccess(arg);
268
+ */
269
+ }
265
270
  else {
266
271
  return this.processNode(arg);
267
272
  // return this.generateLiteral(arg);
@@ -279,7 +284,9 @@ export class GraphGenerator extends TypeScriptGenerator {
279
284
  } */
280
285
  generateImports() {
281
286
  let arr = [
282
- renderImports.default({ nodes: JSON.stringify(this.graphNodes) }),
287
+ renderImports.default({
288
+ nodes: JSON.stringify(this.graphNodes.map((n) => n.nodeName)),
289
+ }),
283
290
  ];
284
291
  arr.push(builtinTools.default({}));
285
292
  return arr.join("\n");
@@ -299,14 +306,17 @@ export class GraphGenerator extends TypeScriptGenerator {
299
306
  toNodes: JSON.stringify(adjacent),
300
307
  }));
301
308
  });
302
- if (this.graphNodes.includes("main")) {
309
+ if (this.graphNodes.map((n) => n.nodeName).includes("main")) {
303
310
  lines.push(renderStartNode.default({
304
311
  startNode: "main",
305
312
  }));
306
313
  }
307
314
  for (const node of this.graphNodes) {
308
315
  lines.push(renderRunNodeFunction.default({
309
- nodeName: node,
316
+ nodeName: node.nodeName,
317
+ returnType: node.returnType
318
+ ? variableTypeToString(node.returnType, this.typeAliases)
319
+ : "any",
310
320
  }));
311
321
  }
312
322
  lines.push("export default graph;");
@@ -135,7 +135,8 @@ export class TypeScriptGenerator extends BaseGenerator {
135
135
  .filter((s) => s.type === "interpolation")
136
136
  .map((s) => s.variableName);
137
137
  for (const varName of interpolatedVars) {
138
- if (!this.functionScopedVariables.includes(varName)) {
138
+ if (!this.functionScopedVariables.includes(varName) &&
139
+ !this.globalScopedVariables.includes(varName)) {
139
140
  throw new Error(`Variable '${varName}' used in prompt interpolation but not defined. ` +
140
141
  `Referenced in assignment to '${variableName}'.`);
141
142
  }
@@ -152,7 +153,7 @@ export class TypeScriptGenerator extends BaseGenerator {
152
153
  }
153
154
  processTool(node) {
154
155
  const { functionName, body, parameters } = node;
155
- if (this.graphNodes.includes(functionName)) {
156
+ if (this.graphNodes.map((n) => n.nodeName).includes(functionName)) {
156
157
  throw new Error(`There is already a node named '${functionName}'. Functions can't have the same name as an existing node.`);
157
158
  }
158
159
  const properties = {};
@@ -193,6 +194,9 @@ export class TypeScriptGenerator extends BaseGenerator {
193
194
  return renderFunctionDefinition.default({
194
195
  functionName,
195
196
  args: "{" + args + "}",
197
+ returnType: node.returnType
198
+ ? variableTypeToString(node.returnType, this.typeAliases)
199
+ : "any",
196
200
  functionBody: bodyCode.join("\n"),
197
201
  });
198
202
  }
@@ -220,10 +224,11 @@ export class TypeScriptGenerator extends BaseGenerator {
220
224
  this.functionsUsed.add(arg.functionName);
221
225
  return this.generateFunctionCallExpression(arg);
222
226
  /* } else if (arg.type === "accessExpression") {
223
- return this.processAccessExpression(arg);
224
- } else if (arg.type === "indexAccess") {
225
- return this.processIndexAccess(arg);
226
- */ }
227
+ return this.processAccessExpression(arg);
228
+ } else if (arg.type === "indexAccess") {
229
+ return this.processIndexAccess(arg);
230
+ */
231
+ }
227
232
  else {
228
233
  // return this.generateLiteral(arg);
229
234
  return this.processNode(arg);
@@ -252,6 +257,8 @@ export class TypeScriptGenerator extends BaseGenerator {
252
257
  return literal.value;
253
258
  case "string":
254
259
  return `"${escape(literal.value)}"`;
260
+ case "multiLineString":
261
+ return `\`${escape(literal.value)}\``;
255
262
  case "variableName":
256
263
  return literal.value;
257
264
  case "prompt":
@@ -1,4 +1,4 @@
1
- import { AgencyNode, DocString, FunctionDefinition, FunctionParameter } from "../types.js";
1
+ import { AgencyNode, DocString, FunctionDefinition, FunctionParameter, VariableType } from "../types.js";
2
2
  import { Parser } from "tarsec";
3
3
  import { GraphNodeDefinition } from "../types/graphNode.js";
4
4
  import { WhileLoop } from "../types/whileLoop.js";
@@ -7,5 +7,6 @@ export declare const bodyParser: Parser<AgencyNode[]>;
7
7
  export declare const whileLoopParser: Parser<WhileLoop>;
8
8
  export declare const functionParameterParserWithTypeHint: Parser<FunctionParameter>;
9
9
  export declare const functionParameterParser: Parser<FunctionParameter>;
10
+ export declare const functionReturnTypeParser: Parser<VariableType>;
10
11
  export declare const functionParser: Parser<FunctionDefinition>;
11
12
  export declare const graphNodeParser: Parser<GraphNodeDefinition>;
@@ -1,4 +1,4 @@
1
- import { capture, char, debug, many1, many1Till, many1WithJoin, map, or, sepBy, seqC, set, space, spaces, str, succeed, trace, } from "tarsec";
1
+ import { capture, captureCaptures, char, debug, 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
3
  import { assignmentParser } from "./assignment.js";
4
4
  import { commentParser } from "./comment.js";
@@ -21,5 +21,6 @@ export const bodyParser = trace("functionBodyParser", (input) => {
21
21
  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
22
  export const functionParameterParserWithTypeHint = trace("functionParameterParserWithTypeHint", seqC(set("type", "functionParameter"), capture(many1WithJoin(varNameChar), "name"), optionalSpaces, char(":"), optionalSpaces, capture(variableTypeParser, "typeHint")));
23
23
  export const functionParameterParser = trace("functionParameterParser", seqC(set("type", "functionParameter"), capture(many1WithJoin(varNameChar), "name")));
24
- 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, char("{"), optionalSpaces, capture(or(docStringParser, succeed(undefined)), "docString"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
25
- export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(or(sepBy(comma, many1WithJoin(varNameChar)), succeed([])), "parameters"), optionalSpaces, char(")"), optionalSpaces, char("{"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
24
+ 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("{"), optionalSpaces, capture(or(docStringParser, succeed(undefined)), "docString"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));
26
+ export const graphNodeParser = trace("graphNodeParser", seqC(set("type", "graphNode"), str("node"), many1(space), capture(many1Till(char("(")), "nodeName"), char("("), optionalSpaces, capture(or(sepBy(comma, many1WithJoin(varNameChar)), succeed([])), "parameters"), optionalSpaces, char(")"), optionalSpaces, capture(optional(functionReturnTypeParser), "returnType"), optionalSpaces, char("{"), optionalSpaces, capture(bodyParser, "body"), optionalSpaces, char("}"), optionalSemicolon));