@lokascript/framework 2.3.1 → 2.4.0
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/api/index.js +29 -516
- package/dist/api/index.js.map +1 -1
- package/dist/core/index.js +20 -128
- package/dist/core/index.js.map +1 -1
- package/dist/core/pattern-matching/index.js +19 -12
- package/dist/core/pattern-matching/index.js.map +1 -1
- package/dist/core/tokenization/index.js.map +1 -1
- package/dist/core/types.d.ts +7 -354
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +21 -129
- package/dist/core/types.js.map +1 -1
- package/dist/generation/diagnostics.d.ts +5 -115
- package/dist/generation/diagnostics.d.ts.map +1 -1
- package/dist/generation/index.js +20 -77
- package/dist/generation/index.js.map +1 -1
- package/dist/index.cjs +189 -1458
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +108 -1347
- package/dist/index.js.map +1 -1
- package/dist/interfaces/value-extractor.d.ts +20 -0
- package/dist/interfaces/value-extractor.d.ts.map +1 -1
- package/dist/ir/explicit-parser.d.ts +2 -83
- package/dist/ir/explicit-parser.d.ts.map +1 -1
- package/dist/ir/explicit-renderer.d.ts +2 -31
- package/dist/ir/explicit-renderer.d.ts.map +1 -1
- package/dist/ir/index.js +89 -1260
- package/dist/ir/index.js.map +1 -1
- package/dist/ir/protocol-json.d.ts +2 -70
- package/dist/ir/protocol-json.d.ts.map +1 -1
- package/dist/ir/references.d.ts +2 -16
- package/dist/ir/references.d.ts.map +1 -1
- package/dist/ir/types.d.ts +2 -148
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/parsing/index.js +19 -12
- package/dist/parsing/index.js.map +1 -1
- package/dist/schema/command-schema.d.ts +3 -92
- package/dist/schema/command-schema.d.ts.map +1 -1
- package/dist/schema/index.js +3 -20
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/index.js +1066 -712
- package/dist/testing/index.js.map +1 -1
- package/package.json +6 -2
- package/src/core/types.ts +71 -600
- package/src/generation/diagnostics.ts +12 -233
- package/src/interfaces/value-extractor.ts +32 -0
- package/src/ir/explicit-parser.ts +12 -792
- package/src/ir/explicit-renderer.ts +2 -195
- package/src/ir/from-interchange.test.ts +91 -4
- package/src/ir/from-interchange.ts +59 -0
- package/src/ir/protocol-json.test.ts +16 -7
- package/src/ir/protocol-json.ts +9 -748
- package/src/ir/references.ts +2 -30
- package/src/ir/types.ts +18 -190
- package/src/schema/command-schema.ts +3 -134
package/dist/api/index.js
CHANGED
|
@@ -1,75 +1,23 @@
|
|
|
1
1
|
// src/core/types.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
action,
|
|
22
|
-
roles: rolesMap
|
|
23
|
-
};
|
|
24
|
-
if (metadata) {
|
|
25
|
-
return { ...node, metadata };
|
|
26
|
-
}
|
|
27
|
-
return node;
|
|
28
|
-
}
|
|
29
|
-
function createEventHandlerNode(action, roles, body, metadata, eventModifiers) {
|
|
30
|
-
const rolesMap = roles instanceof Map ? roles : new Map(Object.entries(roles));
|
|
31
|
-
const base = {
|
|
32
|
-
kind: "event-handler",
|
|
33
|
-
action,
|
|
34
|
-
roles: rolesMap,
|
|
35
|
-
body
|
|
36
|
-
};
|
|
37
|
-
return {
|
|
38
|
-
...base,
|
|
39
|
-
...eventModifiers && { eventModifiers },
|
|
40
|
-
...metadata && { metadata }
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function createConditionalNode(action, roles, thenBranch, elseBranch, metadata) {
|
|
44
|
-
const rolesMap = roles instanceof Map ? roles : new Map(Object.entries(roles));
|
|
45
|
-
const base = {
|
|
46
|
-
kind: "conditional",
|
|
47
|
-
action,
|
|
48
|
-
roles: rolesMap,
|
|
49
|
-
thenBranch
|
|
50
|
-
};
|
|
51
|
-
return {
|
|
52
|
-
...base,
|
|
53
|
-
...elseBranch && { elseBranch },
|
|
54
|
-
...metadata && { metadata }
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
function createLoopNode(action, roles, loopVariant, body, loopVariable, indexVariable, metadata) {
|
|
58
|
-
const rolesMap = roles instanceof Map ? roles : new Map(Object.entries(roles));
|
|
59
|
-
const base = {
|
|
60
|
-
kind: "loop",
|
|
61
|
-
action,
|
|
62
|
-
roles: rolesMap,
|
|
63
|
-
loopVariant,
|
|
64
|
-
body
|
|
65
|
-
};
|
|
66
|
-
return {
|
|
67
|
-
...base,
|
|
68
|
-
...loopVariable && { loopVariable },
|
|
69
|
-
...indexVariable && { indexVariable },
|
|
70
|
-
...metadata && { metadata }
|
|
71
|
-
};
|
|
72
|
-
}
|
|
2
|
+
import {
|
|
3
|
+
createLiteral,
|
|
4
|
+
createSelector,
|
|
5
|
+
createReference,
|
|
6
|
+
createPropertyPath,
|
|
7
|
+
createExpression,
|
|
8
|
+
createFlag,
|
|
9
|
+
createCommandNode,
|
|
10
|
+
createEventHandlerNode,
|
|
11
|
+
createConditionalNode,
|
|
12
|
+
createCompoundNode,
|
|
13
|
+
createLoopNode,
|
|
14
|
+
createTryNode,
|
|
15
|
+
createAsyncNode,
|
|
16
|
+
createMatchNode,
|
|
17
|
+
extractValue,
|
|
18
|
+
extractRoleValue,
|
|
19
|
+
getRoleValue
|
|
20
|
+
} from "@lokascript/intent";
|
|
73
21
|
|
|
74
22
|
// src/core/logger.ts
|
|
75
23
|
var DebugLogger = class {
|
|
@@ -1657,454 +1605,19 @@ var InMemoryProfileProvider = class {
|
|
|
1657
1605
|
}
|
|
1658
1606
|
};
|
|
1659
1607
|
|
|
1660
|
-
// src/ir/references.ts
|
|
1661
|
-
var DEFAULT_REFERENCES = /* @__PURE__ */ new Set([
|
|
1662
|
-
"me",
|
|
1663
|
-
"you",
|
|
1664
|
-
"it",
|
|
1665
|
-
"result",
|
|
1666
|
-
"event",
|
|
1667
|
-
"target",
|
|
1668
|
-
"body"
|
|
1669
|
-
]);
|
|
1670
|
-
function isValidReference2(value, referenceSet = DEFAULT_REFERENCES) {
|
|
1671
|
-
return referenceSet.has(value);
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
1608
|
// src/ir/explicit-parser.ts
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
"finally"
|
|
1685
|
-
// v1.2: try/catch/finally
|
|
1686
|
-
]);
|
|
1687
|
-
function isNestedCommand(value) {
|
|
1688
|
-
const inner = value.slice(1, -1);
|
|
1689
|
-
let depth = 0;
|
|
1690
|
-
for (const ch of inner) {
|
|
1691
|
-
if (ch === "[") depth++;
|
|
1692
|
-
else if (ch === "]") depth--;
|
|
1693
|
-
else if (depth === 0 && (ch === " " || ch === ":")) return true;
|
|
1694
|
-
}
|
|
1695
|
-
return false;
|
|
1696
|
-
}
|
|
1697
|
-
function parseExplicit(input, options = {}) {
|
|
1698
|
-
const trimmed = input.trim();
|
|
1699
|
-
const collect = options.collectDiagnostics === true;
|
|
1700
|
-
const diagnostics = [];
|
|
1701
|
-
if (!trimmed.startsWith("[") || !trimmed.endsWith("]")) {
|
|
1702
|
-
throw new Error("Explicit syntax must be wrapped in brackets: [command role:value ...]");
|
|
1703
|
-
}
|
|
1704
|
-
const content = trimmed.slice(1, -1).trim();
|
|
1705
|
-
if (!content) {
|
|
1706
|
-
throw new Error("Empty explicit statement");
|
|
1707
|
-
}
|
|
1708
|
-
const tokens = tokenizeExplicit(content);
|
|
1709
|
-
if (tokens.length === 0) {
|
|
1710
|
-
throw new Error("No command specified in explicit statement");
|
|
1711
|
-
}
|
|
1712
|
-
const command = tokens[0].toLowerCase();
|
|
1713
|
-
const roles = /* @__PURE__ */ new Map();
|
|
1714
|
-
const refSet = options.referenceSet ?? DEFAULT_REFERENCES;
|
|
1715
|
-
const schema = options.schemaLookup?.getSchema(command);
|
|
1716
|
-
const validRoleNames = schema ? new Set(schema.roles.map((r) => r.role)) : null;
|
|
1717
|
-
for (let i = 1; i < tokens.length; i++) {
|
|
1718
|
-
const token = tokens[i];
|
|
1719
|
-
if (token.startsWith("+") || token.startsWith("~")) {
|
|
1720
|
-
const enabled = token.startsWith("+");
|
|
1721
|
-
const flagName = token.slice(1);
|
|
1722
|
-
if (!flagName) {
|
|
1723
|
-
if (collect) {
|
|
1724
|
-
diagnostics.push({
|
|
1725
|
-
severity: "error",
|
|
1726
|
-
code: "EMPTY_FLAG",
|
|
1727
|
-
message: `Empty flag name: "${token}"`,
|
|
1728
|
-
source: "schema"
|
|
1729
|
-
});
|
|
1730
|
-
continue;
|
|
1731
|
-
}
|
|
1732
|
-
throw new Error(`Empty flag name: "${token}"`);
|
|
1733
|
-
}
|
|
1734
|
-
if (validRoleNames && !validRoleNames.has(flagName)) {
|
|
1735
|
-
const roleList = [...validRoleNames].join(", ");
|
|
1736
|
-
if (collect) {
|
|
1737
|
-
diagnostics.push({
|
|
1738
|
-
severity: "error",
|
|
1739
|
-
code: "UNKNOWN_FLAG",
|
|
1740
|
-
message: `Unknown flag "${flagName}" for command "${command}"`,
|
|
1741
|
-
source: "schema",
|
|
1742
|
-
suggestions: [...validRoleNames].map((r) => `+${r}`)
|
|
1743
|
-
});
|
|
1744
|
-
roles.set(flagName, createFlag(flagName, enabled));
|
|
1745
|
-
continue;
|
|
1746
|
-
}
|
|
1747
|
-
throw new Error(
|
|
1748
|
-
`Unknown flag "${flagName}" for command "${command}". Valid roles: ${roleList}`
|
|
1749
|
-
);
|
|
1750
|
-
}
|
|
1751
|
-
roles.set(flagName, createFlag(flagName, enabled));
|
|
1752
|
-
continue;
|
|
1753
|
-
}
|
|
1754
|
-
const colonIndex = token.indexOf(":");
|
|
1755
|
-
if (colonIndex === -1) {
|
|
1756
|
-
if (collect) {
|
|
1757
|
-
diagnostics.push({
|
|
1758
|
-
severity: "error",
|
|
1759
|
-
code: "INVALID_ROLE_FORMAT",
|
|
1760
|
-
message: `Invalid role format: "${token}". Expected role:value or +flag`,
|
|
1761
|
-
source: "schema"
|
|
1762
|
-
});
|
|
1763
|
-
continue;
|
|
1764
|
-
}
|
|
1765
|
-
throw new Error(`Invalid role format: "${token}". Expected role:value or +flag`);
|
|
1766
|
-
}
|
|
1767
|
-
const roleName = token.slice(0, colonIndex);
|
|
1768
|
-
if (validRoleNames && !STRUCTURAL_ROLES.has(roleName) && !validRoleNames.has(roleName)) {
|
|
1769
|
-
const roleList = [...validRoleNames].join(", ");
|
|
1770
|
-
if (collect) {
|
|
1771
|
-
diagnostics.push({
|
|
1772
|
-
severity: "error",
|
|
1773
|
-
code: "UNKNOWN_ROLE",
|
|
1774
|
-
message: `Unknown role "${roleName}" for command "${command}"`,
|
|
1775
|
-
source: "schema",
|
|
1776
|
-
suggestions: [...validRoleNames]
|
|
1777
|
-
});
|
|
1778
|
-
} else {
|
|
1779
|
-
throw new Error(
|
|
1780
|
-
`Unknown role "${roleName}" for command "${command}". Valid roles: ${roleList}`
|
|
1781
|
-
);
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
const role = roleName;
|
|
1785
|
-
const valueStr = token.slice(colonIndex + 1);
|
|
1786
|
-
if (STRUCTURAL_ROLES.has(roleName) && valueStr.startsWith("[") && isNestedCommand(valueStr)) {
|
|
1787
|
-
const nestedEnd = findMatchingBracket(token, colonIndex + 1);
|
|
1788
|
-
const nestedSyntax = token.slice(colonIndex + 1, nestedEnd + 1);
|
|
1789
|
-
roles.set(role, { type: "expression", raw: nestedSyntax });
|
|
1790
|
-
continue;
|
|
1791
|
-
}
|
|
1792
|
-
const value = parseExplicitValue(valueStr, refSet);
|
|
1793
|
-
roles.set(role, value);
|
|
1794
|
-
}
|
|
1795
|
-
if (schema && command !== "on") {
|
|
1796
|
-
for (const roleSpec of schema.roles) {
|
|
1797
|
-
if (roleSpec.required && !roles.has(roleSpec.role) && !roleSpec.default) {
|
|
1798
|
-
if (collect) {
|
|
1799
|
-
diagnostics.push({
|
|
1800
|
-
severity: "error",
|
|
1801
|
-
code: "MISSING_REQUIRED_ROLE",
|
|
1802
|
-
message: `Missing required role "${roleSpec.role}" for command "${command}": ${roleSpec.description}`,
|
|
1803
|
-
source: "schema"
|
|
1804
|
-
});
|
|
1805
|
-
} else {
|
|
1806
|
-
throw new Error(
|
|
1807
|
-
`Missing required role "${roleSpec.role}" for command "${command}": ${roleSpec.description}`
|
|
1808
|
-
);
|
|
1809
|
-
}
|
|
1810
|
-
}
|
|
1811
|
-
}
|
|
1812
|
-
}
|
|
1813
|
-
const attachDiagnostics = (node) => {
|
|
1814
|
-
if (diagnostics.length === 0) return node;
|
|
1815
|
-
return { ...node, diagnostics };
|
|
1816
|
-
};
|
|
1817
|
-
switch (command) {
|
|
1818
|
-
case "on": {
|
|
1819
|
-
const eventValue = roles.get("event");
|
|
1820
|
-
if (!eventValue) {
|
|
1821
|
-
if (collect) {
|
|
1822
|
-
diagnostics.push({
|
|
1823
|
-
severity: "error",
|
|
1824
|
-
code: "MISSING_EVENT_ROLE",
|
|
1825
|
-
message: "Event handler requires event role: [on event:click ...]",
|
|
1826
|
-
source: "schema"
|
|
1827
|
-
});
|
|
1828
|
-
return attachDiagnostics(
|
|
1829
|
-
createEventHandlerNode("on", roles, [], {
|
|
1830
|
-
sourceLanguage: "explicit"
|
|
1831
|
-
})
|
|
1832
|
-
);
|
|
1833
|
-
}
|
|
1834
|
-
throw new Error("Event handler requires event role: [on event:click ...]");
|
|
1835
|
-
}
|
|
1836
|
-
const body = extractStructuralBody(roles, "body", options);
|
|
1837
|
-
roles.delete("body");
|
|
1838
|
-
return attachDiagnostics(
|
|
1839
|
-
createEventHandlerNode("on", roles, body, {
|
|
1840
|
-
sourceLanguage: "explicit"
|
|
1841
|
-
})
|
|
1842
|
-
);
|
|
1843
|
-
}
|
|
1844
|
-
case "if": {
|
|
1845
|
-
const thenBranch = extractStructuralBody(roles, "then", options);
|
|
1846
|
-
const elseBranch = extractStructuralBody(roles, "else", options);
|
|
1847
|
-
roles.delete("then");
|
|
1848
|
-
roles.delete("else");
|
|
1849
|
-
return attachDiagnostics(
|
|
1850
|
-
createConditionalNode(
|
|
1851
|
-
command,
|
|
1852
|
-
roles,
|
|
1853
|
-
thenBranch,
|
|
1854
|
-
elseBranch.length > 0 ? elseBranch : void 0,
|
|
1855
|
-
{
|
|
1856
|
-
sourceLanguage: "explicit"
|
|
1857
|
-
}
|
|
1858
|
-
)
|
|
1859
|
-
);
|
|
1860
|
-
}
|
|
1861
|
-
case "repeat": {
|
|
1862
|
-
const loopBody = extractStructuralBody(roles, "loop-body", options);
|
|
1863
|
-
const loopVariantValue = roles.get("loop-variant");
|
|
1864
|
-
const variableValue = roles.get("variable");
|
|
1865
|
-
const indexVariableValue = roles.get("index-variable");
|
|
1866
|
-
roles.delete("loop-body");
|
|
1867
|
-
roles.delete("loop-variant");
|
|
1868
|
-
roles.delete("variable");
|
|
1869
|
-
roles.delete("index-variable");
|
|
1870
|
-
let variant;
|
|
1871
|
-
if (loopVariantValue && loopVariantValue.type === "literal" && typeof loopVariantValue.value === "string") {
|
|
1872
|
-
variant = loopVariantValue.value;
|
|
1873
|
-
} else if (roles.has("quantity")) {
|
|
1874
|
-
variant = "times";
|
|
1875
|
-
} else if (roles.has("source")) {
|
|
1876
|
-
variant = "for";
|
|
1877
|
-
} else if (roles.has("condition")) {
|
|
1878
|
-
variant = "while";
|
|
1879
|
-
} else {
|
|
1880
|
-
variant = "forever";
|
|
1881
|
-
}
|
|
1882
|
-
const loopVariable = variableValue?.type === "literal" && typeof variableValue.value === "string" ? variableValue.value : variableValue?.type === "expression" ? variableValue.raw : void 0;
|
|
1883
|
-
const indexVariable = indexVariableValue?.type === "literal" && typeof indexVariableValue.value === "string" ? indexVariableValue.value : void 0;
|
|
1884
|
-
return attachDiagnostics(
|
|
1885
|
-
createLoopNode(command, roles, variant, loopBody, loopVariable, indexVariable, {
|
|
1886
|
-
sourceLanguage: "explicit"
|
|
1887
|
-
})
|
|
1888
|
-
);
|
|
1889
|
-
}
|
|
1890
|
-
default:
|
|
1891
|
-
return attachDiagnostics(
|
|
1892
|
-
createCommandNode(command, roles, {
|
|
1893
|
-
sourceLanguage: "explicit"
|
|
1894
|
-
})
|
|
1895
|
-
);
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
function isExplicitSyntax(input) {
|
|
1899
|
-
const trimmed = input.trim();
|
|
1900
|
-
return trimmed.startsWith("[") && trimmed.endsWith("]");
|
|
1901
|
-
}
|
|
1902
|
-
function extractStructuralBody(roles, roleName, options) {
|
|
1903
|
-
const value = roles.get(roleName);
|
|
1904
|
-
if (!value) return [];
|
|
1905
|
-
if (value.type === "expression") {
|
|
1906
|
-
return [parseExplicit(value.raw, options)];
|
|
1907
|
-
}
|
|
1908
|
-
return [];
|
|
1909
|
-
}
|
|
1910
|
-
function inferSelectorKind(value) {
|
|
1911
|
-
if (!value) return void 0;
|
|
1912
|
-
if (value.startsWith("#")) return "id";
|
|
1913
|
-
if (value.startsWith(".")) return "class";
|
|
1914
|
-
if (value.startsWith("[")) return "attribute";
|
|
1915
|
-
if (value.startsWith("<") || value.startsWith("*")) return "element";
|
|
1916
|
-
if (/[>+~ ]/.test(value) && value.length > 1) return "complex";
|
|
1917
|
-
return void 0;
|
|
1918
|
-
}
|
|
1919
|
-
function tokenizeExplicit(content) {
|
|
1920
|
-
const tokens = [];
|
|
1921
|
-
let current = "";
|
|
1922
|
-
let inString = false;
|
|
1923
|
-
let stringChar = "";
|
|
1924
|
-
let bracketDepth = 0;
|
|
1925
|
-
for (let i = 0; i < content.length; i++) {
|
|
1926
|
-
const char = content[i];
|
|
1927
|
-
if (inString) {
|
|
1928
|
-
current += char;
|
|
1929
|
-
if (char === stringChar && content[i - 1] !== "\\") {
|
|
1930
|
-
inString = false;
|
|
1931
|
-
}
|
|
1932
|
-
continue;
|
|
1933
|
-
}
|
|
1934
|
-
if (char === '"' || char === "'") {
|
|
1935
|
-
inString = true;
|
|
1936
|
-
stringChar = char;
|
|
1937
|
-
current += char;
|
|
1938
|
-
continue;
|
|
1939
|
-
}
|
|
1940
|
-
if (char === "[") {
|
|
1941
|
-
bracketDepth++;
|
|
1942
|
-
current += char;
|
|
1943
|
-
continue;
|
|
1944
|
-
}
|
|
1945
|
-
if (char === "]") {
|
|
1946
|
-
bracketDepth--;
|
|
1947
|
-
current += char;
|
|
1948
|
-
continue;
|
|
1949
|
-
}
|
|
1950
|
-
if (char === " " && bracketDepth === 0) {
|
|
1951
|
-
if (current) {
|
|
1952
|
-
tokens.push(current);
|
|
1953
|
-
current = "";
|
|
1954
|
-
}
|
|
1955
|
-
continue;
|
|
1956
|
-
}
|
|
1957
|
-
current += char;
|
|
1958
|
-
}
|
|
1959
|
-
if (current) {
|
|
1960
|
-
tokens.push(current);
|
|
1961
|
-
}
|
|
1962
|
-
return tokens;
|
|
1963
|
-
}
|
|
1964
|
-
function parseExplicitValue(valueStr, referenceSet) {
|
|
1965
|
-
if (valueStr.startsWith("#") || valueStr.startsWith(".") || valueStr.startsWith("[") || valueStr.startsWith("@") || valueStr.startsWith("*")) {
|
|
1966
|
-
return createSelector(valueStr, inferSelectorKind(valueStr));
|
|
1967
|
-
}
|
|
1968
|
-
if (valueStr.startsWith('"') || valueStr.startsWith("'")) {
|
|
1969
|
-
const inner = valueStr.slice(1, -1);
|
|
1970
|
-
return createLiteral(inner, "string");
|
|
1971
|
-
}
|
|
1972
|
-
if (valueStr === "true") return createLiteral(true, "boolean");
|
|
1973
|
-
if (valueStr === "false") return createLiteral(false, "boolean");
|
|
1974
|
-
const lowerRef = valueStr.toLowerCase();
|
|
1975
|
-
if (isValidReference2(lowerRef, referenceSet)) {
|
|
1976
|
-
return createReference(lowerRef);
|
|
1977
|
-
}
|
|
1978
|
-
const numMatch = valueStr.match(/^(-?\d+(?:\.\d+)?)(ms|s|m|h)?$/);
|
|
1979
|
-
if (numMatch) {
|
|
1980
|
-
const num = parseFloat(numMatch[1]);
|
|
1981
|
-
const suffix = numMatch[2];
|
|
1982
|
-
if (suffix) {
|
|
1983
|
-
return createLiteral(valueStr, "duration");
|
|
1984
|
-
}
|
|
1985
|
-
return createLiteral(num, "number");
|
|
1986
|
-
}
|
|
1987
|
-
return createLiteral(valueStr);
|
|
1988
|
-
}
|
|
1989
|
-
function findMatchingBracket(str, start) {
|
|
1990
|
-
let depth = 0;
|
|
1991
|
-
for (let i = start; i < str.length; i++) {
|
|
1992
|
-
if (str[i] === "[") depth++;
|
|
1993
|
-
else if (str[i] === "]") {
|
|
1994
|
-
depth--;
|
|
1995
|
-
if (depth === 0) return i;
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
return str.length - 1;
|
|
1999
|
-
}
|
|
1609
|
+
import {
|
|
1610
|
+
STRUCTURAL_ROLES,
|
|
1611
|
+
parseExplicit,
|
|
1612
|
+
isExplicitSyntax,
|
|
1613
|
+
parseCompound,
|
|
1614
|
+
parseDocument,
|
|
1615
|
+
isCompoundSyntax,
|
|
1616
|
+
isDocumentSyntax
|
|
1617
|
+
} from "@lokascript/intent";
|
|
2000
1618
|
|
|
2001
1619
|
// src/ir/explicit-renderer.ts
|
|
2002
|
-
|
|
2003
|
-
let result;
|
|
2004
|
-
if (node.kind === "compound") {
|
|
2005
|
-
const compoundNode = node;
|
|
2006
|
-
const renderedStatements = compoundNode.statements.map((stmt) => renderExplicit(stmt));
|
|
2007
|
-
result = renderedStatements.join(` ${compoundNode.chainType} `);
|
|
2008
|
-
} else {
|
|
2009
|
-
result = renderBracketCommand(node);
|
|
2010
|
-
}
|
|
2011
|
-
if (node.annotations && node.annotations.length > 0) {
|
|
2012
|
-
const annParts = node.annotations.map(
|
|
2013
|
-
(ann) => ann.value !== void 0 ? `@${ann.name}(${ann.value})` : `@${ann.name}`
|
|
2014
|
-
);
|
|
2015
|
-
return annParts.join(" ") + " " + result;
|
|
2016
|
-
}
|
|
2017
|
-
return result;
|
|
2018
|
-
}
|
|
2019
|
-
function renderBracketCommand(node) {
|
|
2020
|
-
const parts = [node.action];
|
|
2021
|
-
for (const [role, value] of node.roles) {
|
|
2022
|
-
if (value.type === "flag") {
|
|
2023
|
-
parts.push(value.enabled ? `+${value.name}` : `~${value.name}`);
|
|
2024
|
-
} else {
|
|
2025
|
-
parts.push(`${role}:${valueToString(value)}`);
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
if (node.kind === "event-handler") {
|
|
2029
|
-
const eventNode = node;
|
|
2030
|
-
if (eventNode.body && eventNode.body.length > 0) {
|
|
2031
|
-
const bodyParts = eventNode.body.map((n) => renderExplicit(n));
|
|
2032
|
-
parts.push(`body:${bodyParts.join(" ")}`);
|
|
2033
|
-
}
|
|
2034
|
-
}
|
|
2035
|
-
if (node.kind === "conditional") {
|
|
2036
|
-
const condNode = node;
|
|
2037
|
-
if (condNode.thenBranch && condNode.thenBranch.length > 0) {
|
|
2038
|
-
const thenParts = condNode.thenBranch.map((n) => renderExplicit(n));
|
|
2039
|
-
parts.push(`then:${thenParts.join(" ")}`);
|
|
2040
|
-
}
|
|
2041
|
-
if (condNode.elseBranch && condNode.elseBranch.length > 0) {
|
|
2042
|
-
const elseParts = condNode.elseBranch.map((n) => renderExplicit(n));
|
|
2043
|
-
parts.push(`else:${elseParts.join(" ")}`);
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
if (node.kind === "loop") {
|
|
2047
|
-
const loopNode = node;
|
|
2048
|
-
if (loopNode.loopVariant) {
|
|
2049
|
-
parts.push(`loop-variant:${loopNode.loopVariant}`);
|
|
2050
|
-
}
|
|
2051
|
-
if (loopNode.loopVariable) {
|
|
2052
|
-
parts.push(`variable:${loopNode.loopVariable}`);
|
|
2053
|
-
}
|
|
2054
|
-
if (loopNode.indexVariable) {
|
|
2055
|
-
parts.push(`index-variable:${loopNode.indexVariable}`);
|
|
2056
|
-
}
|
|
2057
|
-
if (loopNode.body && loopNode.body.length > 0) {
|
|
2058
|
-
const bodyParts = loopNode.body.map((n) => renderExplicit(n));
|
|
2059
|
-
parts.push(`loop-body:${bodyParts.join(" ")}`);
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
if (node.kind === "command") {
|
|
2063
|
-
const cmd = node;
|
|
2064
|
-
if (cmd.body && cmd.body.length > 0) {
|
|
2065
|
-
const bodyParts = cmd.body.map((n) => renderExplicit(n));
|
|
2066
|
-
parts.push(`body:${bodyParts.join(" ")}`);
|
|
2067
|
-
}
|
|
2068
|
-
if (cmd.catchBranch && cmd.catchBranch.length > 0) {
|
|
2069
|
-
const catchParts = cmd.catchBranch.map((n) => renderExplicit(n));
|
|
2070
|
-
parts.push(`catch:${catchParts.join(" ")}`);
|
|
2071
|
-
}
|
|
2072
|
-
if (cmd.finallyBranch && cmd.finallyBranch.length > 0) {
|
|
2073
|
-
const finallyParts = cmd.finallyBranch.map((n) => renderExplicit(n));
|
|
2074
|
-
parts.push(`finally:${finallyParts.join(" ")}`);
|
|
2075
|
-
}
|
|
2076
|
-
if (cmd.asyncVariant) {
|
|
2077
|
-
parts.push(`async-variant:${cmd.asyncVariant}`);
|
|
2078
|
-
}
|
|
2079
|
-
if (cmd.asyncBody && cmd.asyncBody.length > 0) {
|
|
2080
|
-
const asyncParts = cmd.asyncBody.map((n) => renderExplicit(n));
|
|
2081
|
-
parts.push(`async-body:${asyncParts.join(" ")}`);
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2084
|
-
return `[${parts.join(" ")}]`;
|
|
2085
|
-
}
|
|
2086
|
-
function valueToString(value) {
|
|
2087
|
-
switch (value.type) {
|
|
2088
|
-
case "literal":
|
|
2089
|
-
if (typeof value.value === "string") {
|
|
2090
|
-
if (value.dataType === "string" || /\s/.test(value.value)) {
|
|
2091
|
-
return `"${value.value}"`;
|
|
2092
|
-
}
|
|
2093
|
-
return value.value;
|
|
2094
|
-
}
|
|
2095
|
-
return String(value.value);
|
|
2096
|
-
case "selector":
|
|
2097
|
-
return value.value;
|
|
2098
|
-
case "reference":
|
|
2099
|
-
return value.value;
|
|
2100
|
-
case "property-path":
|
|
2101
|
-
return `${valueToString(value.object)}'s ${value.property}`;
|
|
2102
|
-
case "expression":
|
|
2103
|
-
return value.raw;
|
|
2104
|
-
case "flag":
|
|
2105
|
-
return value.name;
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
1620
|
+
import { renderExplicit, renderDocument } from "@lokascript/intent";
|
|
2108
1621
|
|
|
2109
1622
|
// src/api/create-dsl.ts
|
|
2110
1623
|
var DSLRegistry = class {
|