agency-lang 0.0.5 → 0.0.7
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 +1 -0
- package/dist/lib/backends/agencyGenerator.js +20 -17
- package/dist/lib/parser.d.ts +1 -1
- package/dist/lib/parser.js +10 -1
- package/dist/lib/parsers/importStatement.test.js +4 -4
- package/dist/lib/parsers/typeHints.d.ts +1 -1
- package/dist/lib/parsers/typeHints.js +3 -3
- package/dist/lib/parsers/typeHints.test.js +20 -2
- package/dist/scripts/agency.js +76 -47
- package/package.json +2 -1
|
@@ -43,5 +43,6 @@ export declare class AgencyGenerator extends BaseGenerator {
|
|
|
43
43
|
protected processGraphNode(node: GraphNodeDefinition): string;
|
|
44
44
|
protected processTool(node: FunctionDefinition): string;
|
|
45
45
|
protected processUsesTool(node: UsesTool): string;
|
|
46
|
+
private indentStr;
|
|
46
47
|
}
|
|
47
48
|
export declare function generateAgency(program: AgencyProgram): string;
|
|
@@ -32,17 +32,17 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
32
32
|
processTypeAlias(node) {
|
|
33
33
|
this.typeAliases[node.aliasName] = node.aliasedType;
|
|
34
34
|
const aliasedTypeStr = variableTypeToString(node.aliasedType, this.typeAliases);
|
|
35
|
-
return
|
|
35
|
+
return this.indentStr(`type ${node.aliasName} = ${aliasedTypeStr}\n`);
|
|
36
36
|
}
|
|
37
37
|
processTypeHint(node) {
|
|
38
38
|
this.typeHints[node.variableName] = node.variableType;
|
|
39
39
|
const typeStr = variableTypeToString(node.variableType, this.typeAliases);
|
|
40
|
-
return
|
|
40
|
+
return this.indentStr(`${node.variableName} :: ${typeStr}\n`);
|
|
41
41
|
}
|
|
42
42
|
// Assignment and literals
|
|
43
43
|
processAssignment(node) {
|
|
44
44
|
const valueCode = this.processNode(node.value).trim();
|
|
45
|
-
return
|
|
45
|
+
return this.indentStr(`${node.variableName} = ${valueCode}\n\n`);
|
|
46
46
|
}
|
|
47
47
|
generateLiteral(literal) {
|
|
48
48
|
switch (literal.type) {
|
|
@@ -86,7 +86,7 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
86
86
|
// Build parameter list
|
|
87
87
|
const params = parameters.join(", ");
|
|
88
88
|
// Start function definition
|
|
89
|
-
let result =
|
|
89
|
+
let result = this.indentStr(`def ${functionName}(${params}) {\n`);
|
|
90
90
|
// Process body with increased indentation
|
|
91
91
|
this.increaseIndent();
|
|
92
92
|
this.functionScopedVariables = [...parameters];
|
|
@@ -96,12 +96,12 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
96
96
|
this.functionScopedVariables = [];
|
|
97
97
|
this.decreaseIndent();
|
|
98
98
|
// Close function
|
|
99
|
-
result +=
|
|
99
|
+
result += this.indentStr(`}\n\n`);
|
|
100
100
|
return result;
|
|
101
101
|
}
|
|
102
102
|
processFunctionCall(node) {
|
|
103
103
|
const expr = this.generateFunctionCallExpression(node);
|
|
104
|
-
return
|
|
104
|
+
return this.indentStr(`${expr}\n`);
|
|
105
105
|
}
|
|
106
106
|
generateFunctionCallExpression(node) {
|
|
107
107
|
const args = node.arguments.map((arg) => {
|
|
@@ -151,7 +151,7 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
151
151
|
// Control flow
|
|
152
152
|
processMatchBlock(node) {
|
|
153
153
|
const exprCode = this.processNode(node.expression).trim();
|
|
154
|
-
let result =
|
|
154
|
+
let result = this.indentStr(`match(${exprCode}) {\n`);
|
|
155
155
|
this.increaseIndent();
|
|
156
156
|
for (const caseNode of node.cases) {
|
|
157
157
|
// Handle comments within cases
|
|
@@ -165,39 +165,39 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
165
165
|
: this.processNode(caseNode.caseValue).trim();
|
|
166
166
|
// Format body (action)
|
|
167
167
|
const bodyCode = this.processNode(caseNode.body).trim();
|
|
168
|
-
result +=
|
|
168
|
+
result += this.indentStr(`${pattern} => ${bodyCode}\n`);
|
|
169
169
|
}
|
|
170
170
|
this.decreaseIndent();
|
|
171
|
-
result +=
|
|
171
|
+
result += this.indentStr(`}\n`);
|
|
172
172
|
return result;
|
|
173
173
|
}
|
|
174
174
|
processWhileLoop(node) {
|
|
175
175
|
const conditionCode = this.processNode(node.condition).trim();
|
|
176
|
-
let result =
|
|
176
|
+
let result = this.indentStr(`while (${conditionCode}) {\n`);
|
|
177
177
|
this.increaseIndent();
|
|
178
178
|
for (const stmt of node.body) {
|
|
179
179
|
result += this.processNode(stmt);
|
|
180
180
|
}
|
|
181
181
|
this.decreaseIndent();
|
|
182
|
-
result +=
|
|
182
|
+
result += this.indentStr(`}\n`);
|
|
183
183
|
return result;
|
|
184
184
|
}
|
|
185
185
|
processReturnStatement(node) {
|
|
186
186
|
const valueCode = this.processNode(node.value).trim();
|
|
187
|
-
return
|
|
187
|
+
return this.indentStr(`return ${valueCode}\n`);
|
|
188
188
|
}
|
|
189
189
|
// Utility methods
|
|
190
190
|
processComment(node) {
|
|
191
|
-
return
|
|
191
|
+
return this.indentStr(`// ${node.content}\n`);
|
|
192
192
|
}
|
|
193
193
|
processImportStatement(node) {
|
|
194
|
-
return
|
|
194
|
+
return this.indentStr(`import {${node.importedNames}} from "${node.modulePath}"\n`);
|
|
195
195
|
}
|
|
196
196
|
processGraphNode(node) {
|
|
197
197
|
// Graph nodes use similar syntax to functions
|
|
198
198
|
const { nodeName, body, parameters } = node;
|
|
199
199
|
const params = parameters.join(", ");
|
|
200
|
-
let result =
|
|
200
|
+
let result = this.indentStr(`node ${nodeName}(${params}) {\n`);
|
|
201
201
|
this.increaseIndent();
|
|
202
202
|
this.functionScopedVariables = [...parameters];
|
|
203
203
|
for (const stmt of body) {
|
|
@@ -205,7 +205,7 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
205
205
|
}
|
|
206
206
|
this.functionScopedVariables = [];
|
|
207
207
|
this.decreaseIndent();
|
|
208
|
-
result +=
|
|
208
|
+
result += this.indentStr(`}\n`);
|
|
209
209
|
return result;
|
|
210
210
|
}
|
|
211
211
|
processTool(node) {
|
|
@@ -216,7 +216,10 @@ export class AgencyGenerator extends BaseGenerator {
|
|
|
216
216
|
processUsesTool(node) {
|
|
217
217
|
// Track tool usage but don't generate code
|
|
218
218
|
this.toolsUsed.push(node.toolName);
|
|
219
|
-
return
|
|
219
|
+
return this.indentStr(`+${node.toolName}\n`);
|
|
220
|
+
}
|
|
221
|
+
indentStr(str) {
|
|
222
|
+
return `${this.indent()}${str}`;
|
|
220
223
|
}
|
|
221
224
|
}
|
|
222
225
|
export function generateAgency(program) {
|
package/dist/lib/parser.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export declare const agencyNode: Parser<AgencyNode[]>;
|
|
|
4
4
|
export declare const agencyParser: Parser<AgencyProgram>;
|
|
5
5
|
export declare const _multilineCommentParser: Parser<string[]>;
|
|
6
6
|
export declare const multilineCommentParser: Parser<string[][]>;
|
|
7
|
-
export declare function parseAgency(input: string): ParserResult<AgencyProgram>;
|
|
7
|
+
export declare function parseAgency(input: string, verbose?: boolean): ParserResult<AgencyProgram>;
|
package/dist/lib/parser.js
CHANGED
|
@@ -9,6 +9,7 @@ import { importStatmentParser } from "./parsers/importStatement.js";
|
|
|
9
9
|
import { matchBlockParser } from "./parsers/matchBlock.js";
|
|
10
10
|
import { returnStatementParser } from "./parsers/returnStatement.js";
|
|
11
11
|
import { usesToolParser } from "./parsers/tools.js";
|
|
12
|
+
import { EgonLog } from "egonlog";
|
|
12
13
|
export const agencyNode = (input) => {
|
|
13
14
|
const parser = sepBy(spaces, trace("agencyParser", or(usesToolParser, importStatmentParser, graphNodeParser, typeAliasParser, whileLoopParser, typeHintParser, matchBlockParser, functionParser, returnStatementParser, accessExpressionParser, assignmentParser, functionCallParser, commentParser)));
|
|
14
15
|
return parser(input);
|
|
@@ -16,9 +17,15 @@ export const agencyNode = (input) => {
|
|
|
16
17
|
export const agencyParser = seqC(set("type", "agencyProgram"), capture(agencyNode, "nodes"), eof);
|
|
17
18
|
export const _multilineCommentParser = between(str("/*"), str("*/"), anyChar);
|
|
18
19
|
export const multilineCommentParser = search(_multilineCommentParser);
|
|
19
|
-
export function parseAgency(input) {
|
|
20
|
+
export function parseAgency(input, verbose = false) {
|
|
21
|
+
const logger = new EgonLog({ level: verbose ? "debug" : "warn" });
|
|
20
22
|
let normalized = input;
|
|
23
|
+
logger.debug("Starting to parse agency program");
|
|
24
|
+
logger.debug(`Input: ${input}`);
|
|
25
|
+
logger.debug("================================");
|
|
21
26
|
const comments = multilineCommentParser(normalized);
|
|
27
|
+
logger.debug(`Multiline comments: ${JSON.stringify(comments)}`);
|
|
28
|
+
logger.debug("================================");
|
|
22
29
|
// get rid of all multiline comments
|
|
23
30
|
normalized = comments.rest
|
|
24
31
|
.split("\n")
|
|
@@ -33,6 +40,8 @@ export function parseAgency(input) {
|
|
|
33
40
|
nodes: [],
|
|
34
41
|
}, "");
|
|
35
42
|
}
|
|
43
|
+
logger.debug(`Normalized input: ${normalized}`);
|
|
44
|
+
logger.debug("================================");
|
|
36
45
|
const result = agencyParser(normalized);
|
|
37
46
|
return result;
|
|
38
47
|
}
|
|
@@ -44,7 +44,7 @@ describe("importStatmentParser", () => {
|
|
|
44
44
|
result: {
|
|
45
45
|
type: "importStatement",
|
|
46
46
|
importedNames: "foo ",
|
|
47
|
-
modulePath: '"./local/path"',
|
|
47
|
+
modulePath: '"./local/path.js"',
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
},
|
|
@@ -55,7 +55,7 @@ describe("importStatmentParser", () => {
|
|
|
55
55
|
result: {
|
|
56
56
|
type: "importStatement",
|
|
57
57
|
importedNames: "bar ",
|
|
58
|
-
modulePath: '"
|
|
58
|
+
modulePath: '"../utils/helper.js"',
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
61
|
},
|
|
@@ -89,7 +89,7 @@ describe("importStatmentParser", () => {
|
|
|
89
89
|
result: {
|
|
90
90
|
type: "importStatement",
|
|
91
91
|
importedNames: "test ",
|
|
92
|
-
modulePath: "'./module'",
|
|
92
|
+
modulePath: "'./module.js'",
|
|
93
93
|
},
|
|
94
94
|
},
|
|
95
95
|
},
|
|
@@ -240,7 +240,7 @@ describe("importStatmentParser", () => {
|
|
|
240
240
|
result: {
|
|
241
241
|
type: "importStatement",
|
|
242
242
|
importedNames: "foo ",
|
|
243
|
-
modulePath: '"../../../utils/helpers"',
|
|
243
|
+
modulePath: '"../../../utils/helpers.js"',
|
|
244
244
|
},
|
|
245
245
|
},
|
|
246
246
|
},
|
|
@@ -7,7 +7,7 @@ export declare const angleBracketsArrayTypeParser: Parser<ArrayType>;
|
|
|
7
7
|
export declare const stringLiteralTypeParser: Parser<StringLiteralType>;
|
|
8
8
|
export declare const numberLiteralTypeParser: Parser<NumberLiteralType>;
|
|
9
9
|
export declare const booleanLiteralTypeParser: Parser<BooleanLiteralType>;
|
|
10
|
-
export declare const objectPropertyDelimiter: Parser<(string
|
|
10
|
+
export declare const objectPropertyDelimiter: Parser<"\n" | (string | string[])[]>;
|
|
11
11
|
export declare const objectPropertyParser: Parser<ObjectProperty>;
|
|
12
12
|
export declare const objectPropertyDescriptionParser: Parser<{
|
|
13
13
|
description: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { optionalSpaces, varNameChar } from "./utils.js";
|
|
2
|
-
import { capture, captureCaptures, char, count, digit, many1Till, many1WithJoin, or, sepBy, seqC, seqR, set, space, spaces, str, trace, } from "tarsec";
|
|
2
|
+
import { capture, captureCaptures, char, count, digit, many1Till, many1WithJoin, oneOf, or, sepBy, seqC, seqR, set, space, spaces, str, trace, } from "tarsec";
|
|
3
3
|
import { optionalSemicolon } from "./parserUtils.js";
|
|
4
4
|
export const primitiveTypeParser = trace("primitiveTypeParser", seqC(set("type", "primitiveType"), capture(or(str("number"), str("string"), str("boolean")), "value")));
|
|
5
5
|
export const typeAliasVariableParser = trace("typeAliasVariableParser", seqC(set("type", "typeAliasVariable"), capture(many1WithJoin(varNameChar), "aliasName")));
|
|
@@ -27,12 +27,12 @@ export const angleBracketsArrayTypeParser = trace("angleBracketsArrayTypeParser"
|
|
|
27
27
|
export const stringLiteralTypeParser = trace("stringLiteralTypeParser", seqC(set("type", "stringLiteralType"), char('"'), capture(many1Till(char('"')), "value"), char('"')));
|
|
28
28
|
export const numberLiteralTypeParser = trace("numberLiteralTypeParser", seqC(set("type", "numberLiteralType"), capture(many1WithJoin(or(char("-"), char("."), digit)), "value")));
|
|
29
29
|
export const booleanLiteralTypeParser = trace("booleanLiteralTypeParser", seqC(set("type", "booleanLiteralType"), capture(or(str("true"), str("false")), "value")));
|
|
30
|
-
export const objectPropertyDelimiter = seqR(optionalSpaces,
|
|
30
|
+
export const objectPropertyDelimiter = or(char("\n"), seqR(optionalSpaces, oneOf(",;"), optionalSpaces));
|
|
31
31
|
export const objectPropertyParser = trace("objectPropertyParser", (input) => {
|
|
32
32
|
const parser = seqC(capture(many1WithJoin(varNameChar), "key"), optionalSpaces, char(":"), optionalSpaces, capture(variableTypeParser, "value"));
|
|
33
33
|
return parser(input);
|
|
34
34
|
});
|
|
35
|
-
export const objectPropertyDescriptionParser = seqC(char("#"), optionalSpaces, capture(many1Till(
|
|
35
|
+
export const objectPropertyDescriptionParser = seqC(char("#"), optionalSpaces, capture(many1Till(oneOf(",;\n")), "description"));
|
|
36
36
|
export const objectPropertyWithDescriptionParser = trace("objectPropertyWithDescriptionParser", seqC(captureCaptures(objectPropertyParser), spaces, captureCaptures(objectPropertyDescriptionParser)));
|
|
37
37
|
export const objectTypeParser = trace("objectTypeParser", (input) => {
|
|
38
38
|
const parser = seqC(set("type", "objectType"), char("{"), optionalSpaces, capture(sepBy(objectPropertyDelimiter, or(objectPropertyWithDescriptionParser, objectPropertyParser)), "properties"), optionalSpaces, char("}"));
|
|
@@ -1012,6 +1012,24 @@ describe("objectPropertyDescriptionParser", () => {
|
|
|
1012
1012
|
},
|
|
1013
1013
|
},
|
|
1014
1014
|
},
|
|
1015
|
+
{
|
|
1016
|
+
input: "# comma,",
|
|
1017
|
+
expected: {
|
|
1018
|
+
success: true,
|
|
1019
|
+
result: {
|
|
1020
|
+
description: "comma",
|
|
1021
|
+
},
|
|
1022
|
+
},
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
input: "# newline",
|
|
1026
|
+
expected: {
|
|
1027
|
+
success: true,
|
|
1028
|
+
result: {
|
|
1029
|
+
description: "newline",
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
},
|
|
1015
1033
|
{
|
|
1016
1034
|
input: "# with extra spaces ;",
|
|
1017
1035
|
expected: {
|
|
@@ -1022,11 +1040,11 @@ describe("objectPropertyDescriptionParser", () => {
|
|
|
1022
1040
|
},
|
|
1023
1041
|
},
|
|
1024
1042
|
{
|
|
1025
|
-
input: "# description with
|
|
1043
|
+
input: "# description with punctuation!;",
|
|
1026
1044
|
expected: {
|
|
1027
1045
|
success: true,
|
|
1028
1046
|
result: {
|
|
1029
|
-
description: "description with
|
|
1047
|
+
description: "description with punctuation!",
|
|
1030
1048
|
},
|
|
1031
1049
|
},
|
|
1032
1050
|
},
|
package/dist/scripts/agency.js
CHANGED
|
@@ -12,40 +12,69 @@ Usage:
|
|
|
12
12
|
agency help Show this help message
|
|
13
13
|
agency compile <input> [output] Compile .agency file to TypeScript
|
|
14
14
|
agency run <input> [output] Compile and run .agency file
|
|
15
|
-
agency format
|
|
15
|
+
agency format [input] Format .agency file (reads from stdin if no input)
|
|
16
|
+
agency parse [input] Parse .agency file and show AST (reads from stdin if no input)
|
|
16
17
|
agency <input> Compile and run .agency file (shorthand)
|
|
17
18
|
|
|
18
19
|
Arguments:
|
|
19
|
-
input Path to .agency input file
|
|
20
|
+
input Path to .agency input file (or omit to read from stdin for format/parse)
|
|
20
21
|
output Path to output .ts file (optional)
|
|
21
22
|
Default: <input-name>.ts
|
|
22
23
|
|
|
24
|
+
Flags:
|
|
25
|
+
-v, --verbose Enable verbose logging during parsing
|
|
26
|
+
|
|
23
27
|
Examples:
|
|
24
28
|
agency help Show help
|
|
25
29
|
agency compile script.agency Compile to script.ts
|
|
26
30
|
agency compile script.agency out.ts Compile to out.ts
|
|
27
31
|
agency run script.agency Compile and run script.agency
|
|
32
|
+
agency -v parse script.agency Parse with verbose logging
|
|
33
|
+
cat script.agency | agency format Format from stdin
|
|
34
|
+
echo "x = 5" | agency parse Parse from stdin
|
|
28
35
|
agency script.agency Compile and run (shorthand)
|
|
29
36
|
`);
|
|
30
37
|
}
|
|
31
|
-
function
|
|
38
|
+
function readStdin() {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
let data = "";
|
|
41
|
+
process.stdin.setEncoding("utf-8");
|
|
42
|
+
process.stdin.on("data", (chunk) => {
|
|
43
|
+
data += chunk;
|
|
44
|
+
});
|
|
45
|
+
process.stdin.on("end", () => {
|
|
46
|
+
resolve(data);
|
|
47
|
+
});
|
|
48
|
+
process.stdin.on("error", (err) => {
|
|
49
|
+
reject(err);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function parse(contents, verbose = false) {
|
|
54
|
+
const parseResult = parseAgency(contents, verbose);
|
|
55
|
+
// Check if parsing was successful
|
|
56
|
+
if (!parseResult.success) {
|
|
57
|
+
console.error("Parse error:");
|
|
58
|
+
console.error(parseResult);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
return parseResult.result;
|
|
62
|
+
}
|
|
63
|
+
function readFile(inputFile) {
|
|
32
64
|
// Validate input file
|
|
33
65
|
if (!fs.existsSync(inputFile)) {
|
|
34
66
|
console.error(`Error: Input file '${inputFile}' not found`);
|
|
35
67
|
process.exit(1);
|
|
36
68
|
}
|
|
37
|
-
// Determine output file name
|
|
38
|
-
const output = outputFile || inputFile.replace(".agency", ".ts");
|
|
39
69
|
// Read and parse the Agency file
|
|
40
70
|
const contents = fs.readFileSync(inputFile, "utf-8");
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const parsedProgram = parseResult.result;
|
|
71
|
+
return contents;
|
|
72
|
+
}
|
|
73
|
+
function compile(inputFile, outputFile, verbose = false) {
|
|
74
|
+
// Determine output file name
|
|
75
|
+
const output = outputFile || inputFile.replace(".agency", ".ts");
|
|
76
|
+
const contents = readFile(inputFile);
|
|
77
|
+
const parsedProgram = parse(contents, verbose);
|
|
49
78
|
// Generate TypeScript code
|
|
50
79
|
const generatedCode = generateGraph(parsedProgram);
|
|
51
80
|
// Write to output file
|
|
@@ -53,9 +82,9 @@ function compile(inputFile, outputFile) {
|
|
|
53
82
|
console.log(`Generated ${output} from ${inputFile}`);
|
|
54
83
|
return output;
|
|
55
84
|
}
|
|
56
|
-
function run(inputFile, outputFile) {
|
|
85
|
+
function run(inputFile, outputFile, verbose = false) {
|
|
57
86
|
// Compile the file
|
|
58
|
-
const output = compile(inputFile, outputFile);
|
|
87
|
+
const output = compile(inputFile, outputFile, verbose);
|
|
59
88
|
// Run the generated TypeScript file with Node.js
|
|
60
89
|
console.log(`Running ${output}...`);
|
|
61
90
|
console.log("---");
|
|
@@ -73,39 +102,26 @@ function run(inputFile, outputFile) {
|
|
|
73
102
|
}
|
|
74
103
|
});
|
|
75
104
|
}
|
|
76
|
-
function format(
|
|
77
|
-
|
|
78
|
-
if (!fs.existsSync(inputFile)) {
|
|
79
|
-
console.error(`Error: Input file '${inputFile}' not found`);
|
|
80
|
-
process.exit(1);
|
|
81
|
-
}
|
|
82
|
-
// Read and parse the Agency file
|
|
83
|
-
const contents = fs.readFileSync(inputFile, "utf-8");
|
|
84
|
-
const parseResult = parseAgency(contents);
|
|
85
|
-
// Check if parsing was successful
|
|
86
|
-
if (!parseResult.success) {
|
|
87
|
-
console.error("Parse error:");
|
|
88
|
-
console.error(parseResult);
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
|
-
const parsedProgram = parseResult.result;
|
|
92
|
-
// Generate TypeScript code
|
|
105
|
+
async function format(contents, verbose = false) {
|
|
106
|
+
const parsedProgram = parse(contents, verbose);
|
|
93
107
|
const generatedCode = generateAgency(parsedProgram);
|
|
94
|
-
// Write to output file
|
|
95
|
-
//fs.writeFileSync(inputFile, generatedCode, "utf-8");
|
|
96
|
-
// console.log(`Generated ${output} from ${inputFile}`);
|
|
97
108
|
console.log(generatedCode);
|
|
98
109
|
return generatedCode;
|
|
99
110
|
}
|
|
100
111
|
// Main CLI logic
|
|
101
|
-
function main() {
|
|
112
|
+
async function main() {
|
|
102
113
|
const args = process.argv.slice(2);
|
|
103
114
|
// No arguments - show help
|
|
104
115
|
if (args.length === 0) {
|
|
105
116
|
help();
|
|
106
117
|
return;
|
|
107
118
|
}
|
|
108
|
-
|
|
119
|
+
// Extract verbose flag
|
|
120
|
+
const verboseIndex = args.findIndex((arg) => arg === "-v" || arg === "--verbose");
|
|
121
|
+
const verbose = verboseIndex !== -1;
|
|
122
|
+
// Remove verbose flag from args
|
|
123
|
+
const filteredArgs = args.filter((arg) => arg !== "-v" && arg !== "--verbose");
|
|
124
|
+
const command = filteredArgs[0];
|
|
109
125
|
switch (command) {
|
|
110
126
|
case "help":
|
|
111
127
|
case "--help":
|
|
@@ -113,34 +129,47 @@ function main() {
|
|
|
113
129
|
help();
|
|
114
130
|
break;
|
|
115
131
|
case "compile":
|
|
116
|
-
if (
|
|
132
|
+
if (filteredArgs.length < 2) {
|
|
117
133
|
console.error("Error: 'compile' command requires an input file");
|
|
118
134
|
console.error("Usage: agency compile <input> [output]");
|
|
119
135
|
process.exit(1);
|
|
120
136
|
}
|
|
121
|
-
compile(
|
|
137
|
+
compile(filteredArgs[1], filteredArgs[2], verbose);
|
|
122
138
|
break;
|
|
123
139
|
case "run":
|
|
124
|
-
if (
|
|
140
|
+
if (filteredArgs.length < 2) {
|
|
125
141
|
console.error("Error: 'run' command requires an input file");
|
|
126
142
|
console.error("Usage: agency run <input> [output]");
|
|
127
143
|
process.exit(1);
|
|
128
144
|
}
|
|
129
|
-
run(
|
|
145
|
+
run(filteredArgs[1], filteredArgs[2], verbose);
|
|
130
146
|
break;
|
|
131
147
|
case "fmt":
|
|
132
148
|
case "format":
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
149
|
+
let fmtContents;
|
|
150
|
+
if (filteredArgs.length < 2) {
|
|
151
|
+
fmtContents = await readStdin();
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
fmtContents = readFile(filteredArgs[1]);
|
|
155
|
+
}
|
|
156
|
+
format(fmtContents, verbose);
|
|
157
|
+
break;
|
|
158
|
+
case "parse":
|
|
159
|
+
let contents;
|
|
160
|
+
if (filteredArgs.length < 2) {
|
|
161
|
+
contents = await readStdin();
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
contents = readFile(filteredArgs[1]);
|
|
137
165
|
}
|
|
138
|
-
|
|
166
|
+
const result = parse(contents, verbose);
|
|
167
|
+
console.log(JSON.stringify(result, null, 2));
|
|
139
168
|
break;
|
|
140
169
|
default:
|
|
141
170
|
// If first arg is not a recognized command, treat it as a file to run
|
|
142
171
|
if (command.endsWith(".agency") || fs.existsSync(command)) {
|
|
143
|
-
run(command,
|
|
172
|
+
run(command, filteredArgs[1], verbose);
|
|
144
173
|
}
|
|
145
174
|
else {
|
|
146
175
|
console.error(`Error: Unknown command '${command}'`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agency-lang",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "The Agency language",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/egonSchiele/agency-lang#readme",
|
|
41
41
|
"dependencies": {
|
|
42
|
+
"egonlog": "^0.0.2",
|
|
42
43
|
"nanoid": "^5.1.6",
|
|
43
44
|
"openai": "^6.15.0",
|
|
44
45
|
"simplemachine": "github:egonSchiele/simplemachine",
|