dirac-lang 0.1.89 → 0.1.91
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/{agent-BWFKP5AW.js → agent-OP5VWQN3.js} +5 -5
- package/dist/{chunk-ZVWMNAEP.js → chunk-B7KLVI42.js} +2 -2
- package/dist/{chunk-HJSHCEK4.js → chunk-ECAW4X46.js} +1 -1
- package/dist/{chunk-QGEYKDIA.js → chunk-PKLOBITC.js} +436 -36
- package/dist/{chunk-2VFQ2YBT.js → chunk-PPH7KYKH.js} +13 -2
- package/dist/{chunk-B5OYG2NX.js → chunk-R42DSFUB.js} +2 -2
- package/dist/{chunk-BGG2SULN.js → chunk-SLGJRZ3P.js} +1 -1
- package/dist/cli.js +14 -15
- package/dist/{cron-M6QJMAUB.js → cron-QRAJN2S2.js} +4 -4
- package/dist/index.js +5 -5
- package/dist/interpreter-4XJNFNMA.js +12 -0
- package/dist/{run-at-I5ZV3QBL.js → run-at-THEZWPTK.js} +4 -4
- package/dist/{schedule-QRJ6IYKM.js → schedule-FMQJKZ4Z.js} +4 -4
- package/dist/{session-YZHVQ4XN.js → session-IH5LO7FS.js} +1 -1
- package/dist/{session-server-IAC5KFJC.js → session-server-6Z2THFHB.js} +5 -5
- package/dist/{shell-5IR72NFQ.js → shell-U5L7KXSV.js} +77 -18
- package/dist/{subroutine-5SNHBXRN.js → subroutine-7JJKHTV4.js} +2 -2
- package/dist/{subroutine-index-E6XE6XNL.js → subroutine-index-RVJSWWJ7.js} +2 -2
- package/dist/{tag-validator-DBQVSG75.js → tag-validator-TSD3CDMQ.js} +1 -1
- package/dist/test-runner.js +4 -4
- package/lib/ai.di +2 -1
- package/package.json +1 -1
- package/dist/chunk-AJSYOXXZ.js +0 -323
- package/dist/interpreter-NYE2UVMD.js +0 -12
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
SessionServer,
|
|
3
3
|
getSocketPath,
|
|
4
4
|
isSessionRunning
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-B7KLVI42.js";
|
|
6
|
+
import "./chunk-PKLOBITC.js";
|
|
7
|
+
import "./chunk-ECAW4X46.js";
|
|
8
|
+
import "./chunk-SLGJRZ3P.js";
|
|
9
9
|
import "./chunk-HRHAMPOB.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-PPH7KYKH.js";
|
|
11
11
|
|
|
12
12
|
// src/agent.ts
|
|
13
13
|
import fs from "fs";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
integrate
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PKLOBITC.js";
|
|
4
4
|
import {
|
|
5
5
|
DiracParser
|
|
6
6
|
} from "./chunk-HRHAMPOB.js";
|
|
7
7
|
import {
|
|
8
8
|
createSession
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PPH7KYKH.js";
|
|
10
10
|
|
|
11
11
|
// src/session-server.ts
|
|
12
12
|
import net from "net";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeSubroutine
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ECAW4X46.js";
|
|
4
4
|
import {
|
|
5
5
|
executeIndexSubroutines,
|
|
6
6
|
executeRegistryStats,
|
|
7
7
|
executeSearchSubroutines,
|
|
8
8
|
registry
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-SLGJRZ3P.js";
|
|
10
10
|
import {
|
|
11
11
|
DiracParser
|
|
12
12
|
} from "./chunk-HRHAMPOB.js";
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
substituteVariables,
|
|
35
35
|
throwException,
|
|
36
36
|
unsetExceptionBoundary
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-PPH7KYKH.js";
|
|
38
38
|
|
|
39
39
|
// src/tags/parameters.ts
|
|
40
40
|
async function executeParameters(session, element) {
|
|
@@ -297,7 +297,7 @@ async function executeCall(session, element) {
|
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
async function registerExtendChain(session, subroutine, currentName) {
|
|
300
|
-
const { executeSubroutine: executeSubroutine2 } = await import("./subroutine-
|
|
300
|
+
const { executeSubroutine: executeSubroutine2 } = await import("./subroutine-7JJKHTV4.js");
|
|
301
301
|
const extendsAttr = subroutine.attributes.extends;
|
|
302
302
|
let parentName;
|
|
303
303
|
if (extendsAttr) {
|
|
@@ -487,12 +487,12 @@ async function executeIf(session, element) {
|
|
|
487
487
|
const condition = await evaluatePredicate(session, conditionElement);
|
|
488
488
|
if (condition) {
|
|
489
489
|
if (thenElement) {
|
|
490
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
490
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
491
491
|
await integrateChildren2(session, thenElement);
|
|
492
492
|
}
|
|
493
493
|
} else {
|
|
494
494
|
if (elseElement) {
|
|
495
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
495
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
496
496
|
await integrateChildren2(session, elseElement);
|
|
497
497
|
}
|
|
498
498
|
}
|
|
@@ -505,7 +505,7 @@ async function evaluatePredicate(session, predicateElement) {
|
|
|
505
505
|
return await evaluateCondition(session, predicateElement);
|
|
506
506
|
}
|
|
507
507
|
const outputLengthBefore = session.output.length;
|
|
508
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
508
|
+
const { integrate: integrate2 } = await import("./interpreter-4XJNFNMA.js");
|
|
509
509
|
await integrate2(session, predicateElement);
|
|
510
510
|
const newOutputChunks = session.output.slice(outputLengthBefore);
|
|
511
511
|
const result = newOutputChunks.join("").trim();
|
|
@@ -528,11 +528,11 @@ async function evaluateCondition(session, condElement) {
|
|
|
528
528
|
}
|
|
529
529
|
const outputLengthBefore = session.output.length;
|
|
530
530
|
const args = [];
|
|
531
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
531
|
+
const { integrate: integrate2 } = await import("./interpreter-4XJNFNMA.js");
|
|
532
532
|
for (const child of condElement.children) {
|
|
533
533
|
if (child.tag.toLowerCase() === "arg") {
|
|
534
534
|
const argOutputStart = session.output.length;
|
|
535
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
535
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
536
536
|
await integrateChildren2(session, child);
|
|
537
537
|
const newChunks = session.output.slice(argOutputStart);
|
|
538
538
|
const argValue = newChunks.join("");
|
|
@@ -821,7 +821,7 @@ async function executeLLM(session, element) {
|
|
|
821
821
|
let systemPrompt = "";
|
|
822
822
|
let currentUserPrompt = userPrompt;
|
|
823
823
|
if (!noExtra) {
|
|
824
|
-
const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-
|
|
824
|
+
const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-IH5LO7FS.js");
|
|
825
825
|
const allSubroutines = getAvailableSubroutines2(session);
|
|
826
826
|
if (session.debug) {
|
|
827
827
|
console.error(`[LLM] Total subroutines from session: ${allSubroutines.length}`);
|
|
@@ -1035,20 +1035,6 @@ ${result}
|
|
|
1035
1035
|
console.error(`[LLM] Feedback mode enabled (max iterations: ${maxIterations})`);
|
|
1036
1036
|
}
|
|
1037
1037
|
}
|
|
1038
|
-
const containsDiracCode = (response) => {
|
|
1039
|
-
const trimmed = response.trim();
|
|
1040
|
-
if (isCustom) {
|
|
1041
|
-
return trimmed.includes("<dirac>") || trimmed.includes("<dirac ");
|
|
1042
|
-
}
|
|
1043
|
-
return /<[a-zA-Z_][\w-]*(\s|>|\/)/m.test(trimmed);
|
|
1044
|
-
};
|
|
1045
|
-
if (!containsDiracCode(result)) {
|
|
1046
|
-
if (session.debug) {
|
|
1047
|
-
console.error("[LLM] Response does not contain Dirac code, skipping execution");
|
|
1048
|
-
}
|
|
1049
|
-
emit(session, result);
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
1038
|
let iteration = 0;
|
|
1053
1039
|
while (iteration < maxIterations && (iteration === 0 || feedbackMode)) {
|
|
1054
1040
|
iteration++;
|
|
@@ -1071,7 +1057,7 @@ ${result}
|
|
|
1071
1057
|
const parser = new DiracParser();
|
|
1072
1058
|
let dynamicAST = parser.parse(diracCode);
|
|
1073
1059
|
if (validateTags) {
|
|
1074
|
-
const { validateDiracCode, applyCorrectedTags } = await import("./tag-validator-
|
|
1060
|
+
const { validateDiracCode, applyCorrectedTags } = await import("./tag-validator-TSD3CDMQ.js");
|
|
1075
1061
|
let validation = await validateDiracCode(session, dynamicAST, { autocorrect });
|
|
1076
1062
|
let retryCount = 0;
|
|
1077
1063
|
while (!validation.valid && retryCount < maxRetries) {
|
|
@@ -1709,7 +1695,7 @@ async function getBestTagMatch(candidate, allowed) {
|
|
|
1709
1695
|
return { tag: allowed[bestIdx], score: bestScore };
|
|
1710
1696
|
}
|
|
1711
1697
|
async function executeTagCheck(session, element) {
|
|
1712
|
-
const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-
|
|
1698
|
+
const { getAvailableSubroutines: getAvailableSubroutines2 } = await import("./session-IH5LO7FS.js");
|
|
1713
1699
|
const subroutines = getAvailableSubroutines2(session);
|
|
1714
1700
|
const allowed = new Set(subroutines.map((s) => s.name));
|
|
1715
1701
|
console.error("[tag-check] Allowed subroutines:", Array.from(allowed));
|
|
@@ -1802,7 +1788,7 @@ async function executeTagCheck(session, element) {
|
|
|
1802
1788
|
const executeTag = correctedTag || tagName;
|
|
1803
1789
|
console.error(`[tag-check] Executing <${executeTag}/> as all checks passed and execute=true.`);
|
|
1804
1790
|
const elementToExecute = correctedTag ? { ...child, tag: correctedTag } : child;
|
|
1805
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
1791
|
+
const { integrate: integrate2 } = await import("./interpreter-4XJNFNMA.js");
|
|
1806
1792
|
await integrate2(session, elementToExecute);
|
|
1807
1793
|
}
|
|
1808
1794
|
}
|
|
@@ -1811,7 +1797,7 @@ async function executeTagCheck(session, element) {
|
|
|
1811
1797
|
// src/tags/throw.ts
|
|
1812
1798
|
async function executeThrow(session, element) {
|
|
1813
1799
|
const exceptionName = element.attributes?.name || "exception";
|
|
1814
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1800
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
1815
1801
|
const exceptionDom = {
|
|
1816
1802
|
tag: "exception-content",
|
|
1817
1803
|
attributes: { name: exceptionName },
|
|
@@ -1824,7 +1810,7 @@ async function executeThrow(session, element) {
|
|
|
1824
1810
|
// src/tags/try.ts
|
|
1825
1811
|
async function executeTry(session, element) {
|
|
1826
1812
|
setExceptionBoundary(session);
|
|
1827
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1813
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
1828
1814
|
await integrateChildren2(session, element);
|
|
1829
1815
|
unsetExceptionBoundary(session);
|
|
1830
1816
|
}
|
|
@@ -1834,7 +1820,7 @@ async function executeCatch(session, element) {
|
|
|
1834
1820
|
const exceptionName = element.attributes?.name || "exception";
|
|
1835
1821
|
const caughtCount = lookupException(session, exceptionName);
|
|
1836
1822
|
if (caughtCount > 0) {
|
|
1837
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1823
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
1838
1824
|
await integrateChildren2(session, element);
|
|
1839
1825
|
}
|
|
1840
1826
|
flushCurrentException(session);
|
|
@@ -1843,7 +1829,7 @@ async function executeCatch(session, element) {
|
|
|
1843
1829
|
// src/tags/exception.ts
|
|
1844
1830
|
async function executeException(session, element) {
|
|
1845
1831
|
const exceptions = getCurrentExceptions(session);
|
|
1846
|
-
const { integrateChildren: integrateChildren2 } = await import("./interpreter-
|
|
1832
|
+
const { integrateChildren: integrateChildren2 } = await import("./interpreter-4XJNFNMA.js");
|
|
1847
1833
|
for (const exceptionDom of exceptions) {
|
|
1848
1834
|
await integrateChildren2(session, exceptionDom);
|
|
1849
1835
|
}
|
|
@@ -2044,7 +2030,7 @@ async function executeLoadContext(session, element) {
|
|
|
2044
2030
|
query = element.text.trim();
|
|
2045
2031
|
}
|
|
2046
2032
|
if (!query && element.children.length > 0) {
|
|
2047
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
2033
|
+
const { integrate: integrate2 } = await import("./interpreter-4XJNFNMA.js");
|
|
2048
2034
|
const beforeOutput = session.output.length;
|
|
2049
2035
|
for (const child of element.children) {
|
|
2050
2036
|
await integrate2(session, child);
|
|
@@ -2113,7 +2099,7 @@ async function executeLoadContext(session, element) {
|
|
|
2113
2099
|
parameters: s.parameters.map((p) => p.name),
|
|
2114
2100
|
filePath: s.filePath
|
|
2115
2101
|
}));
|
|
2116
|
-
const { setVariable: setVariable2 } = await import("./session-
|
|
2102
|
+
const { setVariable: setVariable2 } = await import("./session-IH5LO7FS.js");
|
|
2117
2103
|
setVariable2(session, outputVar, JSON.stringify(summary, null, 2), false);
|
|
2118
2104
|
}
|
|
2119
2105
|
}
|
|
@@ -2298,9 +2284,332 @@ import { writeFileSync as writeFileSync4, readFileSync as readFileSync2, unlinkS
|
|
|
2298
2284
|
import { tmpdir } from "os";
|
|
2299
2285
|
import { join as join4 } from "path";
|
|
2300
2286
|
import { spawnSync } from "child_process";
|
|
2287
|
+
|
|
2288
|
+
// src/runtime/braket-parser.ts
|
|
2289
|
+
var BraKetParser = class {
|
|
2290
|
+
lines = [];
|
|
2291
|
+
currentLine = 0;
|
|
2292
|
+
/**
|
|
2293
|
+
* Parse bra-ket notation and compile to XML
|
|
2294
|
+
*/
|
|
2295
|
+
parse(source) {
|
|
2296
|
+
this.lines = source.split("\n");
|
|
2297
|
+
this.currentLine = 0;
|
|
2298
|
+
const xml = ["<dirac>"];
|
|
2299
|
+
this.parseBlock(xml, -1);
|
|
2300
|
+
xml.push("</dirac>");
|
|
2301
|
+
return xml.join("\n");
|
|
2302
|
+
}
|
|
2303
|
+
/**
|
|
2304
|
+
* Parse a block of lines at a given indentation level
|
|
2305
|
+
*/
|
|
2306
|
+
parseBlock(output, parentIndent) {
|
|
2307
|
+
while (this.currentLine < this.lines.length) {
|
|
2308
|
+
const line = this.parseLine(this.lines[this.currentLine]);
|
|
2309
|
+
if (line.type === "empty") {
|
|
2310
|
+
this.currentLine++;
|
|
2311
|
+
continue;
|
|
2312
|
+
}
|
|
2313
|
+
if (line.indent <= parentIndent) {
|
|
2314
|
+
break;
|
|
2315
|
+
}
|
|
2316
|
+
if (line.type === "bra") {
|
|
2317
|
+
const attrs = line.attrs ? ` ${this.convertBraAttributes(line.attrs)}` : "";
|
|
2318
|
+
output.push(`${" ".repeat(line.indent)}<subroutine name="${line.tag}"${attrs}>`);
|
|
2319
|
+
this.currentLine++;
|
|
2320
|
+
this.parseBlock(output, line.indent);
|
|
2321
|
+
output.push(`${" ".repeat(line.indent)}</subroutine>`);
|
|
2322
|
+
continue;
|
|
2323
|
+
}
|
|
2324
|
+
if (line.type === "ket") {
|
|
2325
|
+
const indent = " ".repeat(line.indent);
|
|
2326
|
+
const attrs = line.attrs ? ` ${this.convertKetAttributes(line.attrs, line.tag || "")}` : "";
|
|
2327
|
+
const nextLine = this.currentLine + 1 < this.lines.length ? this.parseLine(this.lines[this.currentLine + 1]) : null;
|
|
2328
|
+
if (nextLine && nextLine.indent > line.indent && nextLine.type !== "empty") {
|
|
2329
|
+
output.push(`${indent}<${line.tag}${attrs}>`);
|
|
2330
|
+
this.currentLine++;
|
|
2331
|
+
this.parseBlock(output, line.indent);
|
|
2332
|
+
output.push(`${indent}</${line.tag}>`);
|
|
2333
|
+
} else {
|
|
2334
|
+
if (line.text) {
|
|
2335
|
+
const content = this.convertInlineKets(line.text);
|
|
2336
|
+
output.push(`${indent}<${line.tag}${attrs}>${content}</${line.tag}>`);
|
|
2337
|
+
} else {
|
|
2338
|
+
output.push(`${indent}<${line.tag}${attrs}/>`);
|
|
2339
|
+
}
|
|
2340
|
+
this.currentLine++;
|
|
2341
|
+
}
|
|
2342
|
+
continue;
|
|
2343
|
+
}
|
|
2344
|
+
if (line.type === "text") {
|
|
2345
|
+
const indent = " ".repeat(line.indent);
|
|
2346
|
+
const content = this.convertInlineKets(line.text || "");
|
|
2347
|
+
output.push(`${indent}${content}`);
|
|
2348
|
+
this.currentLine++;
|
|
2349
|
+
continue;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
/**
|
|
2354
|
+
* Parse a single line into structured form
|
|
2355
|
+
*/
|
|
2356
|
+
parseLine(raw) {
|
|
2357
|
+
const match = raw.match(/^(\s*)(.*)/);
|
|
2358
|
+
const indent = match ? Math.floor(match[1].length / 2) : 0;
|
|
2359
|
+
const content = match ? match[2] : "";
|
|
2360
|
+
if (!content.trim()) {
|
|
2361
|
+
return { indent, type: "empty", raw };
|
|
2362
|
+
}
|
|
2363
|
+
if (content.startsWith("#")) {
|
|
2364
|
+
return { indent, type: "empty", raw };
|
|
2365
|
+
}
|
|
2366
|
+
if (content.startsWith("<") && content.endsWith("|")) {
|
|
2367
|
+
const tagMatch = content.match(/^<([a-zA-Z_][a-zA-Z0-9_-]*)\s*/);
|
|
2368
|
+
if (tagMatch) {
|
|
2369
|
+
const tagName = tagMatch[1];
|
|
2370
|
+
const afterTag = content.substring(tagMatch[0].length, content.length - 1);
|
|
2371
|
+
return {
|
|
2372
|
+
indent,
|
|
2373
|
+
type: "bra",
|
|
2374
|
+
tag: tagName,
|
|
2375
|
+
attrs: afterTag.trim() || void 0,
|
|
2376
|
+
raw
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
const ketMatch = content.match(/^\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>\s*(.*)/);
|
|
2381
|
+
if (ketMatch) {
|
|
2382
|
+
return {
|
|
2383
|
+
indent,
|
|
2384
|
+
type: "ket",
|
|
2385
|
+
tag: ketMatch[1],
|
|
2386
|
+
attrs: ketMatch[2].trim() || void 0,
|
|
2387
|
+
text: ketMatch[3] || void 0,
|
|
2388
|
+
raw
|
|
2389
|
+
};
|
|
2390
|
+
}
|
|
2391
|
+
return {
|
|
2392
|
+
indent,
|
|
2393
|
+
type: "text",
|
|
2394
|
+
text: content,
|
|
2395
|
+
raw
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Convert bra-ket attribute syntax to XML
|
|
2400
|
+
* Examples:
|
|
2401
|
+
* name=value → name="value"
|
|
2402
|
+
* x=5 y=10 → x="5" y="10"
|
|
2403
|
+
* select=@* → select="@*"
|
|
2404
|
+
*/
|
|
2405
|
+
convertAttributes(attrs) {
|
|
2406
|
+
if (!attrs) return "";
|
|
2407
|
+
const parts = [];
|
|
2408
|
+
let current = "";
|
|
2409
|
+
let inQuotes = false;
|
|
2410
|
+
let quoteChar = "";
|
|
2411
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
2412
|
+
const char = attrs[i];
|
|
2413
|
+
if ((char === '"' || char === "'") && (i === 0 || attrs[i - 1] !== "\\")) {
|
|
2414
|
+
if (!inQuotes) {
|
|
2415
|
+
inQuotes = true;
|
|
2416
|
+
quoteChar = char;
|
|
2417
|
+
current += char;
|
|
2418
|
+
} else if (char === quoteChar) {
|
|
2419
|
+
inQuotes = false;
|
|
2420
|
+
current += char;
|
|
2421
|
+
} else {
|
|
2422
|
+
current += char;
|
|
2423
|
+
}
|
|
2424
|
+
} else if (char === " " && !inQuotes) {
|
|
2425
|
+
if (current.trim()) {
|
|
2426
|
+
parts.push(current.trim());
|
|
2427
|
+
current = "";
|
|
2428
|
+
}
|
|
2429
|
+
} else {
|
|
2430
|
+
current += char;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
if (current.trim()) {
|
|
2434
|
+
parts.push(current.trim());
|
|
2435
|
+
}
|
|
2436
|
+
return parts.map((part) => {
|
|
2437
|
+
const match = part.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=(.+)$/);
|
|
2438
|
+
if (!match) return part;
|
|
2439
|
+
const [, name, value] = match;
|
|
2440
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2441
|
+
return `${name}=${value}`;
|
|
2442
|
+
}
|
|
2443
|
+
return `${name}="${value}"`;
|
|
2444
|
+
}).join(" ");
|
|
2445
|
+
}
|
|
2446
|
+
/**
|
|
2447
|
+
* Convert bra-ket attribute syntax to XML for subroutine definitions
|
|
2448
|
+
* Automatically converts parameter attributes to param-* format
|
|
2449
|
+
* Reserved attributes (description, extends, visible) are kept as-is
|
|
2450
|
+
*
|
|
2451
|
+
* Examples:
|
|
2452
|
+
* name=String → param-name="String"
|
|
2453
|
+
* x=number y=string → param-x="number" param-y="string"
|
|
2454
|
+
* description=Adds → description="Adds" (reserved, no prefix)
|
|
2455
|
+
*/
|
|
2456
|
+
convertBraAttributes(attrs) {
|
|
2457
|
+
if (!attrs) return "";
|
|
2458
|
+
const RESERVED = /* @__PURE__ */ new Set(["description", "extends", "visible"]);
|
|
2459
|
+
const parts = [];
|
|
2460
|
+
let current = "";
|
|
2461
|
+
let inQuotes = false;
|
|
2462
|
+
let quoteChar = "";
|
|
2463
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
2464
|
+
const char = attrs[i];
|
|
2465
|
+
if ((char === '"' || char === "'") && (i === 0 || attrs[i - 1] !== "\\")) {
|
|
2466
|
+
if (!inQuotes) {
|
|
2467
|
+
inQuotes = true;
|
|
2468
|
+
quoteChar = char;
|
|
2469
|
+
current += char;
|
|
2470
|
+
} else if (char === quoteChar) {
|
|
2471
|
+
inQuotes = false;
|
|
2472
|
+
current += char;
|
|
2473
|
+
} else {
|
|
2474
|
+
current += char;
|
|
2475
|
+
}
|
|
2476
|
+
} else if (char === " " && !inQuotes) {
|
|
2477
|
+
if (current.trim()) {
|
|
2478
|
+
parts.push(current.trim());
|
|
2479
|
+
current = "";
|
|
2480
|
+
}
|
|
2481
|
+
} else {
|
|
2482
|
+
current += char;
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
if (current.trim()) {
|
|
2486
|
+
parts.push(current.trim());
|
|
2487
|
+
}
|
|
2488
|
+
return parts.map((part) => {
|
|
2489
|
+
const match = part.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=(.+)$/);
|
|
2490
|
+
if (!match) return part;
|
|
2491
|
+
const [, name, value] = match;
|
|
2492
|
+
const isReserved = RESERVED.has(name);
|
|
2493
|
+
const attrName = isReserved ? name : `param-${name}`;
|
|
2494
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2495
|
+
return `${attrName}=${value}`;
|
|
2496
|
+
}
|
|
2497
|
+
return `${attrName}="${value}"`;
|
|
2498
|
+
}).join(" ");
|
|
2499
|
+
}
|
|
2500
|
+
/**
|
|
2501
|
+
* Convert ket attribute syntax to XML, supporting positional arguments
|
|
2502
|
+
* Detects unnamed values and marks them as _positional-N for runtime resolution
|
|
2503
|
+
*
|
|
2504
|
+
* Examples:
|
|
2505
|
+
* |greeting zhi> → <call name="greeting" _positional-0="zhi"/>
|
|
2506
|
+
* |add 5 10> → <call name="add" _positional-0="5" _positional-1="10"/>
|
|
2507
|
+
* |add x=5 y=10> → <call name="add" x="5" y="10"/> (named, no change)
|
|
2508
|
+
* |output>Hello → <output>Hello</output> (text content, no params)
|
|
2509
|
+
*/
|
|
2510
|
+
convertKetAttributes(attrs, tagName) {
|
|
2511
|
+
if (!attrs) return "";
|
|
2512
|
+
const parts = this.parseAttributeParts(attrs);
|
|
2513
|
+
const hasPositional = parts.some((part) => !part.includes("="));
|
|
2514
|
+
if (!hasPositional) {
|
|
2515
|
+
return this.convertAttributes(attrs);
|
|
2516
|
+
}
|
|
2517
|
+
let positionalIndex = 0;
|
|
2518
|
+
return parts.map((part) => {
|
|
2519
|
+
const match = part.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=(.+)$/);
|
|
2520
|
+
if (match) {
|
|
2521
|
+
const [, name, value] = match;
|
|
2522
|
+
const quotedValue = this.quoteValue(value);
|
|
2523
|
+
return `${name}=${quotedValue}`;
|
|
2524
|
+
} else {
|
|
2525
|
+
const quotedValue = this.quoteValue(part);
|
|
2526
|
+
return `_positional-${positionalIndex++}=${quotedValue}`;
|
|
2527
|
+
}
|
|
2528
|
+
}).join(" ");
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Parse attribute string into parts, respecting quotes
|
|
2532
|
+
*/
|
|
2533
|
+
parseAttributeParts(attrs) {
|
|
2534
|
+
const parts = [];
|
|
2535
|
+
let current = "";
|
|
2536
|
+
let inQuotes = false;
|
|
2537
|
+
let quoteChar = "";
|
|
2538
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
2539
|
+
const char = attrs[i];
|
|
2540
|
+
if ((char === '"' || char === "'") && (i === 0 || attrs[i - 1] !== "\\")) {
|
|
2541
|
+
if (!inQuotes) {
|
|
2542
|
+
inQuotes = true;
|
|
2543
|
+
quoteChar = char;
|
|
2544
|
+
current += char;
|
|
2545
|
+
} else if (char === quoteChar) {
|
|
2546
|
+
inQuotes = false;
|
|
2547
|
+
current += char;
|
|
2548
|
+
} else {
|
|
2549
|
+
current += char;
|
|
2550
|
+
}
|
|
2551
|
+
} else if (char === " " && !inQuotes) {
|
|
2552
|
+
if (current.trim()) {
|
|
2553
|
+
parts.push(current.trim());
|
|
2554
|
+
current = "";
|
|
2555
|
+
}
|
|
2556
|
+
} else {
|
|
2557
|
+
current += char;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
if (current.trim()) {
|
|
2561
|
+
parts.push(current.trim());
|
|
2562
|
+
}
|
|
2563
|
+
return parts;
|
|
2564
|
+
}
|
|
2565
|
+
/**
|
|
2566
|
+
* Quote a value if not already quoted
|
|
2567
|
+
*/
|
|
2568
|
+
quoteValue(value) {
|
|
2569
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2570
|
+
return value;
|
|
2571
|
+
}
|
|
2572
|
+
return `"${value}"`;
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Escape XML special characters in text content
|
|
2576
|
+
*/
|
|
2577
|
+
escapeXml(text) {
|
|
2578
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
2579
|
+
}
|
|
2580
|
+
/**
|
|
2581
|
+
* Convert inline kets within text content
|
|
2582
|
+
* Example: "Hello |variable name=x> world" → "Hello <variable name="x"/> world"
|
|
2583
|
+
* Example: "if x < 10 and y > 5" → "if x < 10 and y > 5"
|
|
2584
|
+
*/
|
|
2585
|
+
convertInlineKets(text) {
|
|
2586
|
+
const parts = [];
|
|
2587
|
+
let lastIndex = 0;
|
|
2588
|
+
const ketRegex = /\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>/g;
|
|
2589
|
+
let match;
|
|
2590
|
+
while ((match = ketRegex.exec(text)) !== null) {
|
|
2591
|
+
if (match.index > lastIndex) {
|
|
2592
|
+
const beforeText = text.substring(lastIndex, match.index);
|
|
2593
|
+
parts.push(this.escapeXml(beforeText));
|
|
2594
|
+
}
|
|
2595
|
+
const [, tag, attrs] = match;
|
|
2596
|
+
const attrStr = attrs.trim() ? ` ${this.convertAttributes(attrs.trim())}` : "";
|
|
2597
|
+
parts.push(`<${tag}${attrStr}/>`);
|
|
2598
|
+
lastIndex = ketRegex.lastIndex;
|
|
2599
|
+
}
|
|
2600
|
+
if (lastIndex < text.length) {
|
|
2601
|
+
const remainingText = text.substring(lastIndex);
|
|
2602
|
+
parts.push(this.escapeXml(remainingText));
|
|
2603
|
+
}
|
|
2604
|
+
return parts.join("");
|
|
2605
|
+
}
|
|
2606
|
+
};
|
|
2607
|
+
|
|
2608
|
+
// src/tags/edit-subroutine.ts
|
|
2301
2609
|
async function executeEditSubroutine(session, element) {
|
|
2302
2610
|
const name = element.attributes.name;
|
|
2303
2611
|
const editor = element.attributes.editor || process.env.EDITOR || process.env.VISUAL || "vi";
|
|
2612
|
+
const format = element.attributes.format || "braket";
|
|
2304
2613
|
if (!name) {
|
|
2305
2614
|
throw new Error("<edit-subroutine> requires name attribute");
|
|
2306
2615
|
}
|
|
@@ -2344,8 +2653,20 @@ async function executeEditSubroutine(session, element) {
|
|
|
2344
2653
|
console.error(`[edit-subroutine] No source file, serializing from AST`);
|
|
2345
2654
|
}
|
|
2346
2655
|
}
|
|
2656
|
+
let content;
|
|
2657
|
+
if (format === "braket") {
|
|
2658
|
+
content = serializeSubroutineToBraKet(subroutine);
|
|
2659
|
+
if (session.debug) {
|
|
2660
|
+
console.error(`[edit-subroutine] Using bra-ket format`);
|
|
2661
|
+
}
|
|
2662
|
+
} else {
|
|
2663
|
+
content = xml;
|
|
2664
|
+
if (session.debug) {
|
|
2665
|
+
console.error(`[edit-subroutine] Using XML format`);
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2347
2668
|
const tempFile = join4(tmpdir(), `dirac-edit-${name}-${Date.now()}.di`);
|
|
2348
|
-
writeFileSync4(tempFile,
|
|
2669
|
+
writeFileSync4(tempFile, content, "utf-8");
|
|
2349
2670
|
if (session.debug) {
|
|
2350
2671
|
console.error(`[edit-subroutine] Wrote '${name}' to temp file: ${tempFile}`);
|
|
2351
2672
|
console.error(`[edit-subroutine] Opening with editor: ${editor}`);
|
|
@@ -2373,8 +2694,15 @@ async function executeEditSubroutine(session, element) {
|
|
|
2373
2694
|
if (oldIndex !== -1) {
|
|
2374
2695
|
session.subroutines.splice(oldIndex, 1);
|
|
2375
2696
|
}
|
|
2697
|
+
let xmlContent;
|
|
2698
|
+
if (format === "braket") {
|
|
2699
|
+
const braketParser = new BraKetParser();
|
|
2700
|
+
xmlContent = braketParser.parse(editedContent);
|
|
2701
|
+
} else {
|
|
2702
|
+
xmlContent = editedContent;
|
|
2703
|
+
}
|
|
2376
2704
|
const parser = new DiracParser();
|
|
2377
|
-
const ast = parser.parse(
|
|
2705
|
+
const ast = parser.parse(xmlContent);
|
|
2378
2706
|
await integrate(session, ast);
|
|
2379
2707
|
const editedSub = session.subroutines.find((s) => s.name === name);
|
|
2380
2708
|
if (editedSub) {
|
|
@@ -2384,6 +2712,77 @@ async function executeEditSubroutine(session, element) {
|
|
|
2384
2712
|
emit(session, `Subroutine '${name}' updated in session (use save-subroutine to persist)
|
|
2385
2713
|
`);
|
|
2386
2714
|
}
|
|
2715
|
+
function serializeSubroutineToBraKet(sub) {
|
|
2716
|
+
const lines = [];
|
|
2717
|
+
lines.push(`# Editing subroutine: ${sub.name}`);
|
|
2718
|
+
lines.push("");
|
|
2719
|
+
serializeElementToBraKet(sub.element, lines, 0);
|
|
2720
|
+
return lines.join("\n");
|
|
2721
|
+
}
|
|
2722
|
+
function serializeElementToBraKet(el, lines, indent) {
|
|
2723
|
+
const indentStr = " ".repeat(indent);
|
|
2724
|
+
if (!el.tag || el.tag === "") {
|
|
2725
|
+
if (el.text) {
|
|
2726
|
+
}
|
|
2727
|
+
return;
|
|
2728
|
+
}
|
|
2729
|
+
if (el.tag === "subroutine") {
|
|
2730
|
+
const name = el.attributes?.name || "unnamed";
|
|
2731
|
+
let braLine = `${indentStr}<${name}`;
|
|
2732
|
+
if (el.attributes) {
|
|
2733
|
+
for (const [key, value] of Object.entries(el.attributes)) {
|
|
2734
|
+
if (key !== "name" && typeof value === "string") {
|
|
2735
|
+
const attrName = key.startsWith("param-") ? key.substring(6) : key;
|
|
2736
|
+
braLine += ` ${attrName}=${value}`;
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
braLine += "|";
|
|
2741
|
+
lines.push(braLine);
|
|
2742
|
+
if (el.children && el.children.length > 0) {
|
|
2743
|
+
for (const child of el.children) {
|
|
2744
|
+
serializeElementToBraKet(child, lines, indent + 1);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
return;
|
|
2748
|
+
}
|
|
2749
|
+
let ketLine = `${indentStr}|${el.tag}`;
|
|
2750
|
+
if (el.attributes) {
|
|
2751
|
+
for (const [key, value] of Object.entries(el.attributes)) {
|
|
2752
|
+
if (typeof value === "string") {
|
|
2753
|
+
const needsQuotes = value.includes(" ") || value.includes("=");
|
|
2754
|
+
ketLine += ` ${key}=${needsQuotes ? '"' + value + '"' : value}`;
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
ketLine += ">";
|
|
2759
|
+
if (el.children && el.children.length > 0) {
|
|
2760
|
+
const hasComplexChildren = el.children.some(
|
|
2761
|
+
(c) => c.tag && c.tag !== "variable" && (c.children?.length > 0 || c.tag === "subroutine")
|
|
2762
|
+
);
|
|
2763
|
+
if (!hasComplexChildren) {
|
|
2764
|
+
let inlineContent = "";
|
|
2765
|
+
for (const child of el.children) {
|
|
2766
|
+
if (!child.tag || child.tag === "") {
|
|
2767
|
+
inlineContent += child.text || "";
|
|
2768
|
+
} else if (child.tag === "variable") {
|
|
2769
|
+
const varName = child.attributes?.name || "";
|
|
2770
|
+
inlineContent += `|variable name=${varName}>`;
|
|
2771
|
+
} else {
|
|
2772
|
+
inlineContent += `|${child.tag}>`;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
lines.push(ketLine + inlineContent);
|
|
2776
|
+
} else {
|
|
2777
|
+
lines.push(ketLine);
|
|
2778
|
+
for (const child of el.children) {
|
|
2779
|
+
serializeElementToBraKet(child, lines, indent + 1);
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
} else {
|
|
2783
|
+
lines.push(ketLine);
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2387
2786
|
function serializeSubroutineToXML(sub) {
|
|
2388
2787
|
const lines = [];
|
|
2389
2788
|
lines.push("<!-- Editing subroutine: " + sub.name + " -->");
|
|
@@ -2475,7 +2874,7 @@ async function executeForeach(session, element) {
|
|
|
2475
2874
|
const parser2 = new DiracParser2();
|
|
2476
2875
|
try {
|
|
2477
2876
|
const fromElement = parser2.parse(fromAttr);
|
|
2478
|
-
const { integrate: integrate2 } = await import("./interpreter-
|
|
2877
|
+
const { integrate: integrate2 } = await import("./interpreter-4XJNFNMA.js");
|
|
2479
2878
|
await integrate2(session, fromElement);
|
|
2480
2879
|
} catch (e) {
|
|
2481
2880
|
session.output = savedOutput;
|
|
@@ -3170,6 +3569,7 @@ function listScheduledTasks() {
|
|
|
3170
3569
|
}
|
|
3171
3570
|
|
|
3172
3571
|
export {
|
|
3572
|
+
BraKetParser,
|
|
3173
3573
|
executeSchedule,
|
|
3174
3574
|
stopScheduledTask,
|
|
3175
3575
|
stopAllScheduledTasks,
|