dirac-lang 0.1.18 → 0.1.20
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/{chunk-VZEKPMWN.js → chunk-UXTK2GC2.js} +44 -21
- package/dist/{chunk-E2MR7FMI.js → chunk-VA7VOLNV.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{interpreter-MCDR5L7R.js → interpreter-X7EARER5.js} +1 -1
- package/dist/test-runner.js +1 -1
- package/examples/scope-test.di +3 -3
- package/package.json +1 -1
- package/src/tags/defvar.ts +6 -4
- package/src/tags/output.ts +33 -3
- package/tests/generate-dirac.test.di +22 -0
- package/tests/output-file.test.di +19 -0
- package/tests/subroutine-nested-calls.test.di +3 -3
- package/tests/subroutine-sequential-calls.test.di +3 -3
- package/tests/tag-check.test.di +1 -1
- package/test-eval.di +0 -4
|
@@ -85,7 +85,8 @@ async function executeDefvar(session, element) {
|
|
|
85
85
|
const valueAttr = element.attributes.value;
|
|
86
86
|
const visibleAttr = element.attributes.visible || "false";
|
|
87
87
|
const literal = "literal" in element.attributes;
|
|
88
|
-
const
|
|
88
|
+
const trimAttr = element.attributes.trim;
|
|
89
|
+
const trim = trimAttr !== "false";
|
|
89
90
|
if (!name) {
|
|
90
91
|
throw new Error("<defvar> requires name attribute");
|
|
91
92
|
}
|
|
@@ -137,7 +138,7 @@ function serializeToXml(children) {
|
|
|
137
138
|
xml += " />";
|
|
138
139
|
} else {
|
|
139
140
|
xml += ">";
|
|
140
|
-
if (child.text) {
|
|
141
|
+
if (child.text && child.children.length === 0) {
|
|
141
142
|
xml += escapeXml(child.text);
|
|
142
143
|
}
|
|
143
144
|
if (child.children.length > 0) {
|
|
@@ -195,7 +196,29 @@ function executeAssign(session, element) {
|
|
|
195
196
|
}
|
|
196
197
|
|
|
197
198
|
// src/tags/output.ts
|
|
199
|
+
import * as fs from "fs";
|
|
200
|
+
import * as path from "path";
|
|
198
201
|
async function executeOutput(session, element) {
|
|
202
|
+
const fileAttr = element.attributes?.file;
|
|
203
|
+
const filePath = fileAttr ? substituteAttribute(session, fileAttr) : null;
|
|
204
|
+
if (filePath) {
|
|
205
|
+
let content = "";
|
|
206
|
+
if (element.children && element.children.length > 0) {
|
|
207
|
+
const prevOutput = session.output;
|
|
208
|
+
session.output = [];
|
|
209
|
+
await integrateChildren(session, element);
|
|
210
|
+
content = session.output.join("");
|
|
211
|
+
session.output = prevOutput;
|
|
212
|
+
} else if (element.text) {
|
|
213
|
+
content = substituteVariables(session, element.text);
|
|
214
|
+
}
|
|
215
|
+
const dir = path.dirname(filePath);
|
|
216
|
+
if (dir !== "." && !fs.existsSync(dir)) {
|
|
217
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
218
|
+
}
|
|
219
|
+
fs.appendFileSync(filePath, content + "\n", "utf8");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
199
222
|
if (element.children && element.children.length > 0) {
|
|
200
223
|
await integrateChildren(session, element);
|
|
201
224
|
return;
|
|
@@ -396,12 +419,12 @@ async function executeIf(session, element) {
|
|
|
396
419
|
const condition = await evaluatePredicate(session, conditionElement);
|
|
397
420
|
if (condition) {
|
|
398
421
|
if (thenElement) {
|
|
399
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
422
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
400
423
|
await integrateChildren2(session, thenElement);
|
|
401
424
|
}
|
|
402
425
|
} else {
|
|
403
426
|
if (elseElement) {
|
|
404
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
427
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
405
428
|
await integrateChildren2(session, elseElement);
|
|
406
429
|
}
|
|
407
430
|
}
|
|
@@ -414,7 +437,7 @@ async function evaluatePredicate(session, predicateElement) {
|
|
|
414
437
|
return await evaluateCondition(session, predicateElement);
|
|
415
438
|
}
|
|
416
439
|
const outputLengthBefore = session.output.length;
|
|
417
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
440
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
418
441
|
await integrate2(session, predicateElement);
|
|
419
442
|
const newOutputChunks = session.output.slice(outputLengthBefore);
|
|
420
443
|
const result = newOutputChunks.join("").trim();
|
|
@@ -437,11 +460,11 @@ async function evaluateCondition(session, condElement) {
|
|
|
437
460
|
}
|
|
438
461
|
const outputLengthBefore = session.output.length;
|
|
439
462
|
const args = [];
|
|
440
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
463
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
441
464
|
for (const child of condElement.children) {
|
|
442
465
|
if (child.tag.toLowerCase() === "arg") {
|
|
443
466
|
const argOutputStart = session.output.length;
|
|
444
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
467
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
445
468
|
await integrateChildren2(session, child);
|
|
446
469
|
const newChunks = session.output.slice(argOutputStart);
|
|
447
470
|
const argValue = newChunks.join("");
|
|
@@ -856,11 +879,11 @@ ${expr}
|
|
|
856
879
|
for (const v of session.variables) {
|
|
857
880
|
context[v.name] = v.value;
|
|
858
881
|
}
|
|
859
|
-
const { default:
|
|
860
|
-
const { default:
|
|
882
|
+
const { default: fs3 } = await import("fs");
|
|
883
|
+
const { default: path2 } = await import("path");
|
|
861
884
|
const { fileURLToPath } = await import("url");
|
|
862
|
-
context.fs =
|
|
863
|
-
context.path =
|
|
885
|
+
context.fs = fs3;
|
|
886
|
+
context.path = path2;
|
|
864
887
|
context.__dirname = process.cwd();
|
|
865
888
|
context.getParams = () => {
|
|
866
889
|
const params = session.parameterStack[session.parameterStack.length - 1];
|
|
@@ -914,13 +937,13 @@ ${diracCode}
|
|
|
914
937
|
|
|
915
938
|
// src/tags/import.ts
|
|
916
939
|
import { readFileSync } from "fs";
|
|
917
|
-
import { resolve, dirname } from "path";
|
|
940
|
+
import { resolve, dirname as dirname2 } from "path";
|
|
918
941
|
async function executeImport(session, element) {
|
|
919
942
|
const src = element.attributes.src;
|
|
920
943
|
if (!src) {
|
|
921
944
|
throw new Error("<import> requires src attribute");
|
|
922
945
|
}
|
|
923
|
-
const currentDir = session.currentFile ?
|
|
946
|
+
const currentDir = session.currentFile ? dirname2(session.currentFile) : process.cwd();
|
|
924
947
|
const importPath = resolve(currentDir, src);
|
|
925
948
|
if (session.debug) {
|
|
926
949
|
console.error(`[IMPORT] Loading: ${importPath}`);
|
|
@@ -1102,13 +1125,13 @@ async function executeRequireModule(session, element) {
|
|
|
1102
1125
|
}
|
|
1103
1126
|
|
|
1104
1127
|
// src/tags/tag-check.ts
|
|
1105
|
-
import
|
|
1128
|
+
import fs2 from "fs";
|
|
1106
1129
|
import yaml from "js-yaml";
|
|
1107
1130
|
var SIMILARITY_CUTOFF = 0.75;
|
|
1108
1131
|
function getEmbeddingServerConfig() {
|
|
1109
1132
|
try {
|
|
1110
1133
|
const configPath = process.env.DIRAC_CONFIG || "config.yml";
|
|
1111
|
-
const config = yaml.load(
|
|
1134
|
+
const config = yaml.load(fs2.readFileSync(configPath, "utf8"));
|
|
1112
1135
|
const host = config.embeddingServer?.host || "localhost";
|
|
1113
1136
|
const port = config.embeddingServer?.port || 11434;
|
|
1114
1137
|
const model = config.embeddingServer?.model || "embeddinggemma";
|
|
@@ -1244,7 +1267,7 @@ async function executeTagCheck(session, element) {
|
|
|
1244
1267
|
const executeTag = correctedTag || tagName;
|
|
1245
1268
|
console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
|
|
1246
1269
|
const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
|
|
1247
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1270
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
1248
1271
|
await integrate2(session, elementToExecute);
|
|
1249
1272
|
}
|
|
1250
1273
|
}
|
|
@@ -1253,7 +1276,7 @@ async function executeTagCheck(session, element) {
|
|
|
1253
1276
|
// src/tags/throw.ts
|
|
1254
1277
|
async function executeThrow(session, element) {
|
|
1255
1278
|
const exceptionName = element.attributes?.name || "exception";
|
|
1256
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1279
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1257
1280
|
const exceptionDom = {
|
|
1258
1281
|
tag: "exception-content",
|
|
1259
1282
|
attributes: { name: exceptionName },
|
|
@@ -1266,7 +1289,7 @@ async function executeThrow(session, element) {
|
|
|
1266
1289
|
// src/tags/try.ts
|
|
1267
1290
|
async function executeTry(session, element) {
|
|
1268
1291
|
setExceptionBoundary(session);
|
|
1269
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1292
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1270
1293
|
await integrateChildren2(session, element);
|
|
1271
1294
|
unsetExceptionBoundary(session);
|
|
1272
1295
|
}
|
|
@@ -1276,7 +1299,7 @@ async function executeCatch(session, element) {
|
|
|
1276
1299
|
const exceptionName = element.attributes?.name || "exception";
|
|
1277
1300
|
const caughtCount = lookupException(session, exceptionName);
|
|
1278
1301
|
if (caughtCount > 0) {
|
|
1279
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1302
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1280
1303
|
await integrateChildren2(session, element);
|
|
1281
1304
|
}
|
|
1282
1305
|
flushCurrentException(session);
|
|
@@ -1285,7 +1308,7 @@ async function executeCatch(session, element) {
|
|
|
1285
1308
|
// src/tags/exception.ts
|
|
1286
1309
|
async function executeException(session, element) {
|
|
1287
1310
|
const exceptions = getCurrentExceptions(session);
|
|
1288
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1311
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-X7EARER5.js");
|
|
1289
1312
|
for (const exceptionDom of exceptions) {
|
|
1290
1313
|
await integrateChildren2(session, exceptionDom);
|
|
1291
1314
|
}
|
|
@@ -1425,7 +1448,7 @@ async function executeForeach(session, element) {
|
|
|
1425
1448
|
const parser2 = new DiracParser2();
|
|
1426
1449
|
try {
|
|
1427
1450
|
const fromElement = parser2.parse(fromAttr);
|
|
1428
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1451
|
+
const { integrate: integrate2 } = await import("./interpreter-X7EARER5.js");
|
|
1429
1452
|
await integrate2(session, fromElement);
|
|
1430
1453
|
} catch (e) {
|
|
1431
1454
|
session.output = savedOutput;
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
execute
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-VA7VOLNV.js";
|
|
5
|
+
import "./chunk-UXTK2GC2.js";
|
|
6
6
|
import "./chunk-HRHAMPOB.js";
|
|
7
7
|
import "./chunk-E7PWEMZA.js";
|
|
8
8
|
import "./chunk-52ED23DR.js";
|
|
@@ -13,7 +13,7 @@ import "dotenv/config";
|
|
|
13
13
|
// package.json
|
|
14
14
|
var package_default = {
|
|
15
15
|
name: "dirac-lang",
|
|
16
|
-
version: "0.1.
|
|
16
|
+
version: "0.1.20",
|
|
17
17
|
description: "LLM-Augmented Declarative Execution",
|
|
18
18
|
type: "module",
|
|
19
19
|
main: "dist/index.js",
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
createLLMAdapter,
|
|
3
3
|
execute,
|
|
4
4
|
executeUserCommand
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VA7VOLNV.js";
|
|
6
6
|
import {
|
|
7
7
|
integrate
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UXTK2GC2.js";
|
|
9
9
|
import {
|
|
10
10
|
DiracParser
|
|
11
11
|
} from "./chunk-HRHAMPOB.js";
|
package/dist/test-runner.js
CHANGED
package/examples/scope-test.di
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
<output></output>
|
|
19
19
|
|
|
20
20
|
<!-- Define variables in main scope -->
|
|
21
|
-
<defvar name="x"
|
|
22
|
-
<defvar name="y"
|
|
23
|
-
<defvar name="z"
|
|
21
|
+
<defvar name="x">value-x</defvar>
|
|
22
|
+
<defvar name="y">value-y</defvar>
|
|
23
|
+
<defvar name="z">value-z</defvar>
|
|
24
24
|
|
|
25
25
|
<output>Variables defined in main scope:</output>
|
|
26
26
|
<output> x = <variable name="x" /></output>
|
package/package.json
CHANGED
package/src/tags/defvar.ts
CHANGED
|
@@ -14,7 +14,8 @@ export async function executeDefvar(session: DiracSession, element: DiracElement
|
|
|
14
14
|
const valueAttr = element.attributes.value;
|
|
15
15
|
const visibleAttr = element.attributes.visible || 'false';
|
|
16
16
|
const literal = 'literal' in element.attributes;
|
|
17
|
-
const
|
|
17
|
+
const trimAttr = element.attributes.trim;
|
|
18
|
+
const trim = trimAttr !== 'false'; // Trim by default unless explicitly set to false
|
|
18
19
|
|
|
19
20
|
if (!name) {
|
|
20
21
|
throw new Error('<defvar> requires name attribute');
|
|
@@ -85,12 +86,13 @@ function serializeToXml(children: DiracElement[]): string {
|
|
|
85
86
|
} else {
|
|
86
87
|
xml += '>';
|
|
87
88
|
|
|
88
|
-
//
|
|
89
|
-
if
|
|
89
|
+
// Only add text content if there are no children
|
|
90
|
+
// (if there are children, text is stored in text node children)
|
|
91
|
+
if (child.text && child.children.length === 0) {
|
|
90
92
|
xml += escapeXml(child.text);
|
|
91
93
|
}
|
|
92
94
|
|
|
93
|
-
// Add children
|
|
95
|
+
// Add children (which may include text nodes)
|
|
94
96
|
if (child.children.length > 0) {
|
|
95
97
|
xml += serializeToXml(child.children);
|
|
96
98
|
}
|
package/src/tags/output.ts
CHANGED
|
@@ -4,17 +4,47 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { DiracSession, DiracElement } from '../types/index.js';
|
|
7
|
-
import { emit, substituteVariables } from '../runtime/session.js';
|
|
7
|
+
import { emit, substituteVariables, substituteAttribute } from '../runtime/session.js';
|
|
8
8
|
import { integrateChildren } from '../runtime/interpreter.js';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
9
11
|
|
|
10
12
|
export async function executeOutput(session: DiracSession, element: DiracElement): Promise<void> {
|
|
11
|
-
|
|
13
|
+
const fileAttr = element.attributes?.file;
|
|
14
|
+
const filePath = fileAttr ? substituteAttribute(session, fileAttr) : null;
|
|
15
|
+
|
|
16
|
+
// If writing to a file, collect content first
|
|
17
|
+
if (filePath) {
|
|
18
|
+
let content = '';
|
|
19
|
+
|
|
20
|
+
if (element.children && element.children.length > 0) {
|
|
21
|
+
// Capture output from children
|
|
22
|
+
const prevOutput = session.output;
|
|
23
|
+
session.output = [];
|
|
24
|
+
await integrateChildren(session, element);
|
|
25
|
+
content = session.output.join('');
|
|
26
|
+
session.output = prevOutput;
|
|
27
|
+
} else if (element.text) {
|
|
28
|
+
content = substituteVariables(session, element.text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Ensure directory exists
|
|
32
|
+
const dir = path.dirname(filePath);
|
|
33
|
+
if (dir !== '.' && !fs.existsSync(dir)) {
|
|
34
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Append to file
|
|
38
|
+
fs.appendFileSync(filePath, content + '\n', 'utf8');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Normal output to stdout
|
|
12
43
|
if (element.children && element.children.length > 0) {
|
|
13
44
|
await integrateChildren(session, element);
|
|
14
45
|
return;
|
|
15
46
|
}
|
|
16
47
|
|
|
17
|
-
// If only text content, use it (with variable substitution)
|
|
18
48
|
if (element.text) {
|
|
19
49
|
const content = substituteVariables(session, element.text);
|
|
20
50
|
emit(session, content);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- TEST: generate_and_execute_dirac -->
|
|
2
|
+
<!-- EXPECT: Generated file executed
|
|
3
|
+
Result: 42 -->
|
|
4
|
+
<dirac>
|
|
5
|
+
<!-- Define a DIRAC script as literal -->
|
|
6
|
+
<defvar name="generated_script" literal="true" trim="false">
|
|
7
|
+
<dirac>
|
|
8
|
+
<defvar name="value">42</defvar>
|
|
9
|
+
<output>Result: <variable name="value" /></output>
|
|
10
|
+
</dirac>
|
|
11
|
+
</defvar>
|
|
12
|
+
|
|
13
|
+
<!-- Write to file -->
|
|
14
|
+
<output file="temp-generated.di"><variable name="generated_script" /></output>
|
|
15
|
+
|
|
16
|
+
<!-- Execute the generated script -->
|
|
17
|
+
<output>Generated file executed</output>
|
|
18
|
+
<system shell="bash">
|
|
19
|
+
node dist/cli.js temp-generated.di
|
|
20
|
+
rm temp-generated.di
|
|
21
|
+
</system>
|
|
22
|
+
</dirac>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- TEST: output_file_basic -->
|
|
2
|
+
<!-- EXPECT: stdout output
|
|
3
|
+
File written -->
|
|
4
|
+
<dirac>
|
|
5
|
+
<!-- Write to file -->
|
|
6
|
+
<output file="output-test-temp.txt">File line 1</output>
|
|
7
|
+
<output file="output-test-temp.txt">File line 2</output>
|
|
8
|
+
|
|
9
|
+
<!-- Output to stdout to verify test runs -->
|
|
10
|
+
<output>stdout output</output>
|
|
11
|
+
|
|
12
|
+
<!-- Use system to verify file and clean up -->
|
|
13
|
+
<system shell="bash">
|
|
14
|
+
if [ -f output-test-temp.txt ]; then
|
|
15
|
+
echo "File written"
|
|
16
|
+
rm output-test-temp.txt
|
|
17
|
+
fi
|
|
18
|
+
</system>
|
|
19
|
+
</dirac>
|
|
@@ -18,9 +18,9 @@ main after outer: a=x b=y c=z -->
|
|
|
18
18
|
</subroutine>
|
|
19
19
|
|
|
20
20
|
<!-- Define main scope variables -->
|
|
21
|
-
<defvar name="a"
|
|
22
|
-
<defvar name="b"
|
|
23
|
-
<defvar name="c"
|
|
21
|
+
<defvar name="a">x</defvar>
|
|
22
|
+
<defvar name="b">y</defvar>
|
|
23
|
+
<defvar name="c">z</defvar>
|
|
24
24
|
|
|
25
25
|
<output>main: a=<variable name="a" /> b=<variable name="b" /> c=<variable name="c" /></output>
|
|
26
26
|
|
|
@@ -15,9 +15,9 @@ x=a y=b z=c -->
|
|
|
15
15
|
</subroutine>
|
|
16
16
|
|
|
17
17
|
<!-- Define main scope variables -->
|
|
18
|
-
<defvar name="x"
|
|
19
|
-
<defvar name="y"
|
|
20
|
-
<defvar name="z"
|
|
18
|
+
<defvar name="x">a</defvar>
|
|
19
|
+
<defvar name="y">b</defvar>
|
|
20
|
+
<defvar name="z">c</defvar>
|
|
21
21
|
|
|
22
22
|
<!-- Verify initial state -->
|
|
23
23
|
<output>x=<variable name="x" /> y=<variable name="y" /> z=<variable name="z" /></output>
|
package/tests/tag-check.test.di
CHANGED
|
@@ -18,7 +18,7 @@ Color changed to: red -->
|
|
|
18
18
|
</subroutine>
|
|
19
19
|
|
|
20
20
|
<!-- Test: tag-check should auto-correct similar tag names and execute -->
|
|
21
|
-
<defvar name="result"
|
|
21
|
+
<defvar name="result">
|
|
22
22
|
<tag-check execute="true" autocorrect="true">
|
|
23
23
|
<background-set color="red" />
|
|
24
24
|
</tag-check>
|
package/test-eval.di
DELETED