@tokens-studio/tokenscript-interpreter 0.33.0 → 0.34.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/chunk-33CDF4L4.js +6444 -0
- package/dist/chunk-33CDF4L4.js.map +1 -0
- package/dist/chunk-AXH5N7KV.js +99 -0
- package/dist/chunk-AXH5N7KV.js.map +1 -0
- package/dist/cli.js +221 -2
- package/dist/cli.js.map +1 -1
- package/dist/compliance-suite.js +2 -2
- package/dist/config-DtbN3iyg.d.ts +918 -0
- package/dist/lib/{chunk-QYRJ6NSL.cjs → chunk-LEYHQJTL.cjs} +3 -2
- package/dist/lib/chunk-LEYHQJTL.cjs.map +1 -0
- package/dist/lib/{chunk-GKSWF7FF.cjs → chunk-LMGHS2NP.cjs} +102 -100
- package/dist/lib/chunk-LMGHS2NP.cjs.map +1 -0
- package/dist/lib/{chunk-LI2D53SH.js → chunk-LSTH2XJ4.js} +5 -3
- package/dist/lib/chunk-LSTH2XJ4.js.map +1 -0
- package/dist/lib/{chunk-YD3MIYOO.js → chunk-ODVWXGOM.js} +3 -2
- package/dist/lib/chunk-ODVWXGOM.js.map +1 -0
- package/dist/lib/{chunk-DFN353G4.js → chunk-RWXDOZAS.js} +225 -4
- package/dist/lib/chunk-RWXDOZAS.js.map +1 -0
- package/dist/lib/{chunk-AQEJB7EO.cjs → chunk-YCIBJDRB.cjs} +767 -546
- package/dist/lib/chunk-YCIBJDRB.cjs.map +1 -0
- package/dist/lib/index.cjs +91 -91
- package/dist/lib/index.d.cts +4 -4
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.js +3 -3
- package/dist/lib/{interpreter-DNmBc--s.d.ts → interpreter-6QwMkUqD.d.cts} +30 -2
- package/dist/lib/{interpreter-CP7CNwDa.d.cts → interpreter-v7WiwSP9.d.ts} +30 -2
- package/dist/lib/interpreter.cjs +73 -73
- package/dist/lib/interpreter.d.cts +4 -4
- package/dist/lib/interpreter.d.ts +4 -4
- package/dist/lib/interpreter.js +3 -3
- package/dist/lib/processor-node.cjs +12 -12
- package/dist/lib/processor-node.d.cts +3 -3
- package/dist/lib/processor-node.d.ts +3 -3
- package/dist/lib/processor-node.js +3 -3
- package/dist/lib/processor.cjs +17 -17
- package/dist/lib/processor.d.cts +4 -4
- package/dist/lib/processor.d.ts +4 -4
- package/dist/lib/processor.js +3 -3
- package/dist/lib/schema.cjs +5 -5
- package/dist/lib/schema.d.cts +1 -1
- package/dist/lib/schema.d.ts +1 -1
- package/dist/lib/schema.js +3 -3
- package/dist/lib/syntax-highlighting.cjs +15 -15
- package/dist/lib/syntax-highlighting.d.cts +1 -1
- package/dist/lib/syntax-highlighting.d.ts +1 -1
- package/dist/lib/syntax-highlighting.js +2 -2
- package/dist/lib/{types-DHgmzR1Z.d.ts → types-BI0AZ4Ej.d.ts} +2 -2
- package/dist/lib/{types-BimJex2v.d.cts → types-EB8V9c46.d.cts} +1 -0
- package/dist/lib/{types-BimJex2v.d.ts → types-EB8V9c46.d.ts} +1 -0
- package/dist/lib/{types-DsJuwrq3.d.cts → types-cFwP43uv.d.cts} +2 -2
- package/dist/lib/types.cjs +6 -6
- package/dist/lib/types.d.cts +1 -1
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/types.js +1 -1
- package/dist/processor/index.d.ts +1 -1
- package/dist/processor/index.js +2 -2
- package/dist/repl.d.ts +1 -1
- package/dist/repl.js +2 -2
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/package.json +1 -1
- package/dist/lib/chunk-AQEJB7EO.cjs.map +0 -1
- package/dist/lib/chunk-DFN353G4.js.map +0 -1
- package/dist/lib/chunk-GKSWF7FF.cjs.map +0 -1
- package/dist/lib/chunk-LI2D53SH.js.map +0 -1
- package/dist/lib/chunk-QYRJ6NSL.cjs.map +0 -1
- package/dist/lib/chunk-YD3MIYOO.js.map +0 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var Operations = /* @__PURE__ */ ((Operations2) => {
|
|
3
|
+
Operations2["SUBTRACT"] = "-";
|
|
4
|
+
Operations2["ADD"] = "+";
|
|
5
|
+
Operations2["MULTIPLY"] = "*";
|
|
6
|
+
Operations2["DIVIDE"] = "/";
|
|
7
|
+
Operations2["POWER"] = "^";
|
|
8
|
+
Operations2["LOGIC_AND"] = "&&";
|
|
9
|
+
Operations2["LOGIC_OR"] = "||";
|
|
10
|
+
Operations2["LOGIC_NOT"] = "!";
|
|
11
|
+
return Operations2;
|
|
12
|
+
})(Operations || {});
|
|
13
|
+
var SupportedFormats = /* @__PURE__ */ ((SupportedFormats2) => {
|
|
14
|
+
SupportedFormats2["PX"] = "px";
|
|
15
|
+
SupportedFormats2["EM"] = "em";
|
|
16
|
+
SupportedFormats2["REM"] = "rem";
|
|
17
|
+
SupportedFormats2["VW"] = "vw";
|
|
18
|
+
SupportedFormats2["VH"] = "vh";
|
|
19
|
+
SupportedFormats2["PT"] = "pt";
|
|
20
|
+
SupportedFormats2["IN"] = "in";
|
|
21
|
+
SupportedFormats2["CM"] = "cm";
|
|
22
|
+
SupportedFormats2["MM"] = "mm";
|
|
23
|
+
SupportedFormats2["DEG"] = "deg";
|
|
24
|
+
SupportedFormats2["PERCENTAGE"] = "%";
|
|
25
|
+
SupportedFormats2["S"] = "s";
|
|
26
|
+
SupportedFormats2["MS"] = "ms";
|
|
27
|
+
return SupportedFormats2;
|
|
28
|
+
})(SupportedFormats || {});
|
|
29
|
+
var ReservedKeyword = /* @__PURE__ */ ((ReservedKeyword2) => {
|
|
30
|
+
ReservedKeyword2["TRUE"] = "true";
|
|
31
|
+
ReservedKeyword2["FALSE"] = "false";
|
|
32
|
+
ReservedKeyword2["NULL"] = "null";
|
|
33
|
+
ReservedKeyword2["UNDEFINED"] = "undefined";
|
|
34
|
+
ReservedKeyword2["WHILE"] = "while";
|
|
35
|
+
ReservedKeyword2["IF"] = "if";
|
|
36
|
+
ReservedKeyword2["ELSE"] = "else";
|
|
37
|
+
ReservedKeyword2["ELIF"] = "elif";
|
|
38
|
+
ReservedKeyword2["RETURN"] = "return";
|
|
39
|
+
ReservedKeyword2["VARIABLE"] = "variable";
|
|
40
|
+
ReservedKeyword2["FOR"] = "for";
|
|
41
|
+
return ReservedKeyword2;
|
|
42
|
+
})(ReservedKeyword || {});
|
|
43
|
+
var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
44
|
+
TokenType2["REFERENCE"] = "REFERENCE";
|
|
45
|
+
TokenType2["NUMBER"] = "NUMBER";
|
|
46
|
+
TokenType2["OPERATION"] = "OPERATION";
|
|
47
|
+
TokenType2["FORMAT"] = "FORMAT";
|
|
48
|
+
TokenType2["LPAREN"] = "LPAREN";
|
|
49
|
+
TokenType2["RPAREN"] = "RPAREN";
|
|
50
|
+
TokenType2["EOF"] = "EOF";
|
|
51
|
+
TokenType2["COMMA"] = "COMMA";
|
|
52
|
+
TokenType2["HEX_COLOR"] = "HEX_COLOR";
|
|
53
|
+
TokenType2["STRING"] = "STRING";
|
|
54
|
+
TokenType2["EXPLICIT_STRING"] = "EXPLICIT_STRING";
|
|
55
|
+
TokenType2["TEMPLATE_STRING"] = "TEMPLATE_STRING";
|
|
56
|
+
TokenType2["ASSIGN"] = "ASSIGN";
|
|
57
|
+
TokenType2["IS_EQ"] = "IS_EQ";
|
|
58
|
+
TokenType2["IS_GT"] = "GT";
|
|
59
|
+
TokenType2["IS_LT"] = "LT";
|
|
60
|
+
TokenType2["IS_GT_EQ"] = "IS_GT_EQ";
|
|
61
|
+
TokenType2["IS_LT_EQ"] = "IS_LT_EQ";
|
|
62
|
+
TokenType2["IS_NOT_EQ"] = "IS_NOT_EQ";
|
|
63
|
+
TokenType2["RESERVED_KEYWORD"] = "RESERVED_KEYWORD";
|
|
64
|
+
TokenType2["SEMICOLON"] = "SEMICOLON";
|
|
65
|
+
TokenType2["LOGIC_NOT"] = "LOGIC_NOT";
|
|
66
|
+
TokenType2["COLON"] = "COLON";
|
|
67
|
+
TokenType2["DOT"] = "DOT";
|
|
68
|
+
TokenType2["LOGIC_AND"] = "LOGIC_AND";
|
|
69
|
+
TokenType2["LOGIC_OR"] = "LOGIC_OR";
|
|
70
|
+
TokenType2["LBLOCK"] = "LBLOCK";
|
|
71
|
+
TokenType2["RBLOCK"] = "RBLOCK";
|
|
72
|
+
TokenType2["PARTIAL_REFERENCE"] = "PARTIAL_REFERENCE";
|
|
73
|
+
TokenType2["PARTIAL_STRING"] = "PARTIAL_STRING";
|
|
74
|
+
return TokenType2;
|
|
75
|
+
})(TokenType || {});
|
|
76
|
+
var UNINTERPRETED_KEYWORDS = [
|
|
77
|
+
"inside",
|
|
78
|
+
"outside",
|
|
79
|
+
"above",
|
|
80
|
+
"below",
|
|
81
|
+
"left",
|
|
82
|
+
"right",
|
|
83
|
+
"top",
|
|
84
|
+
"bottom",
|
|
85
|
+
"before",
|
|
86
|
+
"after",
|
|
87
|
+
"between",
|
|
88
|
+
"uppercase",
|
|
89
|
+
"lowercase",
|
|
90
|
+
"underline",
|
|
91
|
+
"none",
|
|
92
|
+
"innerShadow",
|
|
93
|
+
"outerShadow",
|
|
94
|
+
"shadow"
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
export { Operations, ReservedKeyword, SupportedFormats, TokenType, UNINTERPRETED_KEYWORDS };
|
|
98
|
+
//# sourceMappingURL=chunk-AXH5N7KV.js.map
|
|
99
|
+
//# sourceMappingURL=chunk-AXH5N7KV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"names":["Operations","SupportedFormats","ReservedKeyword","TokenType"],"mappings":"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","file":"chunk-AXH5N7KV.js","sourcesContent":["import type { Config } from \"@interpreter/config/config\";\n\nexport enum Operations {\n SUBTRACT = \"-\",\n ADD = \"+\",\n MULTIPLY = \"*\",\n DIVIDE = \"/\",\n POWER = \"^\",\n LOGIC_AND = \"&&\",\n LOGIC_OR = \"||\",\n LOGIC_NOT = \"!\",\n}\n\nexport enum SupportedFormats {\n PX = \"px\",\n EM = \"em\",\n REM = \"rem\",\n VW = \"vw\",\n VH = \"vh\",\n PT = \"pt\",\n IN = \"in\",\n CM = \"cm\",\n MM = \"mm\",\n DEG = \"deg\",\n PERCENTAGE = \"%\",\n // Time units\n S = \"s\",\n MS = \"ms\",\n}\n\nexport enum ReservedKeyword {\n TRUE = \"true\",\n FALSE = \"false\",\n NULL = \"null\",\n UNDEFINED = \"undefined\",\n WHILE = \"while\",\n IF = \"if\",\n ELSE = \"else\",\n ELIF = \"elif\",\n RETURN = \"return\",\n VARIABLE = \"variable\",\n FOR = \"for\",\n}\n\nexport enum TokenType {\n REFERENCE = \"REFERENCE\",\n NUMBER = \"NUMBER\",\n OPERATION = \"OPERATION\",\n FORMAT = \"FORMAT\",\n LPAREN = \"LPAREN\",\n RPAREN = \"RPAREN\",\n EOF = \"EOF\",\n COMMA = \"COMMA\",\n HEX_COLOR = \"HEX_COLOR\",\n STRING = \"STRING\",\n EXPLICIT_STRING = \"EXPLICIT_STRING\",\n TEMPLATE_STRING = \"TEMPLATE_STRING\",\n ASSIGN = \"ASSIGN\",\n IS_EQ = \"IS_EQ\",\n IS_GT = \"GT\",\n IS_LT = \"LT\",\n IS_GT_EQ = \"IS_GT_EQ\",\n IS_LT_EQ = \"IS_LT_EQ\",\n IS_NOT_EQ = \"IS_NOT_EQ\",\n RESERVED_KEYWORD = \"RESERVED_KEYWORD\",\n SEMICOLON = \"SEMICOLON\",\n LOGIC_NOT = \"LOGIC_NOT\",\n COLON = \"COLON\",\n DOT = \"DOT\",\n LOGIC_AND = \"LOGIC_AND\",\n LOGIC_OR = \"LOGIC_OR\",\n LBLOCK = \"LBLOCK\",\n RBLOCK = \"RBLOCK\",\n // Partial tokens for tolerant parsing\n PARTIAL_REFERENCE = \"PARTIAL_REFERENCE\",\n PARTIAL_STRING = \"PARTIAL_STRING\",\n}\n\nexport interface Token {\n type: TokenType;\n value: any;\n line: number;\n pos: number;\n endPos: number;\n}\n\nexport interface ASTNode {\n token?: Token;\n nodeType: string;\n}\n\n/**\n * Metadata attached to a symbol that is preserved across cloning operations.\n * This data is not accessible to the tokenscript language itself and is intended\n * for external use (e.g., storing token IDs for tracing).\n */\nexport type SymbolMetadata = Record<string, unknown>;\n\nexport interface ISymbolType {\n type: string;\n value: any;\n\n /**\n * Optional metadata attached to this symbol.\n * This is a reference that is preserved (not cloned) during deepCopy/cloneIfMutable operations.\n * It is not accessible to the tokenscript language and is intended for external use.\n */\n metadata?: SymbolMetadata;\n\n cloneIfMutable(): ISymbolType;\n deepCopy(): ISymbolType;\n\n typeEquals(other: ISymbolType): boolean;\n equals(other: ISymbolType): boolean;\n validValue(value: any): boolean;\n\n toJSON?(): any;\n toString(): string;\n getTypeName(): string;\n toJs(options?: { recursive?: boolean; stringify?: boolean }): any;\n\n hasMethod?(methodName: string, args: ISymbolType[]): boolean;\n callMethod?(methodName: string, args: ISymbolType[]): ISymbolType | null | undefined;\n hasAttribute?(attributeName: string): boolean;\n getAttribute?(attributeName: string): ISymbolType | null;\n setAttribute?(attributeName: string, value: ISymbolType, config?: Config): void;\n}\n\nexport const UNINTERPRETED_KEYWORDS: string[] = [\n \"inside\",\n \"outside\",\n \"above\",\n \"below\",\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n \"before\",\n \"after\",\n \"between\",\n \"uppercase\",\n \"lowercase\",\n \"underline\",\n \"none\",\n \"innerShadow\",\n \"outerShadow\",\n \"shadow\",\n];\n\nexport type ReferenceRecordValue = string | number | ISymbolType;\n\nexport type ReferenceRecord = Record<string, ReferenceRecordValue | Array<ReferenceRecordValue>>;\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import * as readlineSync from 'readline-sync';
|
|
|
12
12
|
|
|
13
13
|
// package.json
|
|
14
14
|
var package_default = {
|
|
15
|
-
version: "0.
|
|
15
|
+
version: "0.33.0"};
|
|
16
16
|
|
|
17
17
|
// src/types.ts
|
|
18
18
|
var SupportedFormats = /* @__PURE__ */ ((SupportedFormats2) => {
|
|
@@ -151,6 +151,13 @@ var StringNode = class {
|
|
|
151
151
|
this.value = token.value;
|
|
152
152
|
}
|
|
153
153
|
};
|
|
154
|
+
var TemplateStringNode = class {
|
|
155
|
+
constructor(parts, token) {
|
|
156
|
+
this.parts = parts;
|
|
157
|
+
this.token = token;
|
|
158
|
+
this.nodeType = "TemplateStringNode";
|
|
159
|
+
}
|
|
160
|
+
};
|
|
154
161
|
var UnaryOpNode = class {
|
|
155
162
|
constructor(opToken, expr, token) {
|
|
156
163
|
this.opToken = opToken;
|
|
@@ -398,6 +405,10 @@ function walkAST(node, onVisit) {
|
|
|
398
405
|
for (const statement of node.statements) {
|
|
399
406
|
walkAST(statement, onVisit);
|
|
400
407
|
}
|
|
408
|
+
} else if (node instanceof TemplateStringNode) {
|
|
409
|
+
for (const part of node.parts) {
|
|
410
|
+
walkAST(part, onVisit);
|
|
411
|
+
}
|
|
401
412
|
} else if (node instanceof AttributeAccessNode) {
|
|
402
413
|
walkAST(node.left, onVisit);
|
|
403
414
|
if (node.right instanceof FunctionCallNode || node.right instanceof PartialFunctionCallNode) {
|
|
@@ -2548,6 +2559,51 @@ var Lexer = class {
|
|
|
2548
2559
|
endPos: this.pos
|
|
2549
2560
|
};
|
|
2550
2561
|
}
|
|
2562
|
+
/**
|
|
2563
|
+
* Read a backtick-delimited template string.
|
|
2564
|
+
* Supports escape sequences: \{ \$ \` \\
|
|
2565
|
+
* The raw content (with escapes preserved) is stored as the token value.
|
|
2566
|
+
* The parser handles splitting into segments.
|
|
2567
|
+
*/
|
|
2568
|
+
templateString() {
|
|
2569
|
+
const startPos = this.pos;
|
|
2570
|
+
this.eat("`");
|
|
2571
|
+
let result = "";
|
|
2572
|
+
while (this.currentChar !== null && this.currentChar !== "`") {
|
|
2573
|
+
if (this.currentChar === "\\") {
|
|
2574
|
+
const next = this.peek();
|
|
2575
|
+
if (next === "{" || next === "$" || next === "`" || next === "\\") {
|
|
2576
|
+
result += "\\";
|
|
2577
|
+
result += next;
|
|
2578
|
+
this.advance();
|
|
2579
|
+
this.advance();
|
|
2580
|
+
continue;
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
result += this.currentChar;
|
|
2584
|
+
this.advance();
|
|
2585
|
+
}
|
|
2586
|
+
if (this.currentChar === null) {
|
|
2587
|
+
if (this.tolerant) {
|
|
2588
|
+
return {
|
|
2589
|
+
type: "TEMPLATE_STRING" /* TEMPLATE_STRING */,
|
|
2590
|
+
value: result,
|
|
2591
|
+
line: this.line,
|
|
2592
|
+
pos: startPos,
|
|
2593
|
+
endPos: this.pos
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
this.error("LEXER_UNTERMINATED_TEMPLATE_STRING" /* UNTERMINATED_TEMPLATE_STRING */, {});
|
|
2597
|
+
}
|
|
2598
|
+
this.eat("`");
|
|
2599
|
+
return {
|
|
2600
|
+
type: "TEMPLATE_STRING" /* TEMPLATE_STRING */,
|
|
2601
|
+
value: result,
|
|
2602
|
+
line: this.line,
|
|
2603
|
+
pos: startPos,
|
|
2604
|
+
endPos: this.pos
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2551
2607
|
hexColor() {
|
|
2552
2608
|
const startPos = this.pos;
|
|
2553
2609
|
let result = "";
|
|
@@ -2598,6 +2654,9 @@ var Lexer = class {
|
|
|
2598
2654
|
if (this.currentChar === "'" || this.currentChar === '"') {
|
|
2599
2655
|
return this.collectToken(this.explicitString(this.currentChar));
|
|
2600
2656
|
}
|
|
2657
|
+
if (this.currentChar === "`") {
|
|
2658
|
+
return this.collectToken(this.templateString());
|
|
2659
|
+
}
|
|
2601
2660
|
if (this.isValidIdentifierStart(this.currentChar)) {
|
|
2602
2661
|
return this.collectToken(this.stringElement());
|
|
2603
2662
|
}
|
|
@@ -2974,7 +3033,7 @@ var Lexer = class {
|
|
|
2974
3033
|
};
|
|
2975
3034
|
|
|
2976
3035
|
// src/interpreter/parser.ts
|
|
2977
|
-
var Parser = class {
|
|
3036
|
+
var Parser = class _Parser {
|
|
2978
3037
|
constructor(lexer, options) {
|
|
2979
3038
|
this.requiredReferences = /* @__PURE__ */ new Set();
|
|
2980
3039
|
this.incompleteInfo = [];
|
|
@@ -3506,6 +3565,9 @@ ${contextText}`;
|
|
|
3506
3565
|
node = this.attributeAccess(node);
|
|
3507
3566
|
return node;
|
|
3508
3567
|
}
|
|
3568
|
+
if (token.type === "TEMPLATE_STRING" /* TEMPLATE_STRING */) {
|
|
3569
|
+
return this.templateString();
|
|
3570
|
+
}
|
|
3509
3571
|
if (token.type === "EXPLICIT_STRING" /* EXPLICIT_STRING */) {
|
|
3510
3572
|
this.eat("EXPLICIT_STRING" /* EXPLICIT_STRING */);
|
|
3511
3573
|
let node = new StringNode(token);
|
|
@@ -3565,6 +3627,122 @@ ${contextText}`;
|
|
|
3565
3627
|
this.eat("RPAREN" /* RPAREN */);
|
|
3566
3628
|
return new FunctionCallNode(functionName.value, args, functionName);
|
|
3567
3629
|
}
|
|
3630
|
+
/**
|
|
3631
|
+
* Parse a TEMPLATE_STRING token into a TemplateStringNode.
|
|
3632
|
+
* Scans the raw content for:
|
|
3633
|
+
* - {ref.path} → ReferenceNode
|
|
3634
|
+
* - ${expression} → parsed sub-expression
|
|
3635
|
+
* - \{ \${ \` \\ → escaped literals (backslash removed)
|
|
3636
|
+
* - everything else → literal StringNode segments
|
|
3637
|
+
*/
|
|
3638
|
+
templateString() {
|
|
3639
|
+
const token = this.currentToken;
|
|
3640
|
+
const raw = token.value;
|
|
3641
|
+
this.eat("TEMPLATE_STRING" /* TEMPLATE_STRING */);
|
|
3642
|
+
const parts = [];
|
|
3643
|
+
let literal = "";
|
|
3644
|
+
let i = 0;
|
|
3645
|
+
const flushLiteral = () => {
|
|
3646
|
+
if (literal.length > 0) {
|
|
3647
|
+
parts.push(new StringNode({ ...token, value: literal }));
|
|
3648
|
+
literal = "";
|
|
3649
|
+
}
|
|
3650
|
+
};
|
|
3651
|
+
while (i < raw.length) {
|
|
3652
|
+
const ch = raw[i];
|
|
3653
|
+
if (ch === "\\" && i + 1 < raw.length) {
|
|
3654
|
+
const next = raw[i + 1];
|
|
3655
|
+
if (next === "{" || next === "`" || next === "\\") {
|
|
3656
|
+
literal += next;
|
|
3657
|
+
i += 2;
|
|
3658
|
+
continue;
|
|
3659
|
+
}
|
|
3660
|
+
if (next === "$") {
|
|
3661
|
+
if (i + 2 < raw.length && raw[i + 2] === "{") {
|
|
3662
|
+
literal += "${";
|
|
3663
|
+
i += 3;
|
|
3664
|
+
} else {
|
|
3665
|
+
literal += "$";
|
|
3666
|
+
i += 2;
|
|
3667
|
+
}
|
|
3668
|
+
continue;
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
if (ch === "$" && i + 1 < raw.length && raw[i + 1] === "{") {
|
|
3672
|
+
flushLiteral();
|
|
3673
|
+
const start = i + 2;
|
|
3674
|
+
let depth = 1;
|
|
3675
|
+
let j = start;
|
|
3676
|
+
while (j < raw.length && depth > 0) {
|
|
3677
|
+
if (raw[j] === "`") {
|
|
3678
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3679
|
+
message: "Nested template strings are not allowed inside ${...}"
|
|
3680
|
+
});
|
|
3681
|
+
}
|
|
3682
|
+
if (raw[j] === "{") depth++;
|
|
3683
|
+
else if (raw[j] === "}") depth--;
|
|
3684
|
+
if (depth > 0) j++;
|
|
3685
|
+
}
|
|
3686
|
+
if (depth !== 0) {
|
|
3687
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3688
|
+
message: "Unterminated ${...} in template string"
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3691
|
+
const exprStr = raw.slice(start, j);
|
|
3692
|
+
const subLexer = new Lexer(exprStr);
|
|
3693
|
+
const subParser = new _Parser(subLexer);
|
|
3694
|
+
const exprNode = subParser.expr();
|
|
3695
|
+
for (const ref of subParser.requiredReferences) {
|
|
3696
|
+
this.requiredReferences.add(ref);
|
|
3697
|
+
}
|
|
3698
|
+
parts.push(exprNode);
|
|
3699
|
+
i = j + 1;
|
|
3700
|
+
continue;
|
|
3701
|
+
}
|
|
3702
|
+
if (ch === "{") {
|
|
3703
|
+
flushLiteral();
|
|
3704
|
+
const start = i + 1;
|
|
3705
|
+
let j = start;
|
|
3706
|
+
while (j < raw.length && raw[j] !== "}") {
|
|
3707
|
+
if (raw[j] === "{") {
|
|
3708
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3709
|
+
message: "Nested braces in template reference"
|
|
3710
|
+
});
|
|
3711
|
+
}
|
|
3712
|
+
j++;
|
|
3713
|
+
}
|
|
3714
|
+
if (j >= raw.length) {
|
|
3715
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3716
|
+
message: "Unterminated {ref} in template string"
|
|
3717
|
+
});
|
|
3718
|
+
}
|
|
3719
|
+
let refPath = raw.slice(start, j);
|
|
3720
|
+
refPath = refPath.replace(/[ \t]/g, "");
|
|
3721
|
+
if (refPath.length === 0) {
|
|
3722
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3723
|
+
message: "Empty reference in template string"
|
|
3724
|
+
});
|
|
3725
|
+
}
|
|
3726
|
+
this.requiredReferences.add(refPath);
|
|
3727
|
+
parts.push(
|
|
3728
|
+
new ReferenceNode({
|
|
3729
|
+
...token,
|
|
3730
|
+
type: "REFERENCE" /* REFERENCE */,
|
|
3731
|
+
value: refPath
|
|
3732
|
+
})
|
|
3733
|
+
);
|
|
3734
|
+
i = j + 1;
|
|
3735
|
+
continue;
|
|
3736
|
+
}
|
|
3737
|
+
literal += ch;
|
|
3738
|
+
i++;
|
|
3739
|
+
}
|
|
3740
|
+
flushLiteral();
|
|
3741
|
+
if (parts.length === 1 && parts[0] instanceof StringNode) {
|
|
3742
|
+
return parts[0];
|
|
3743
|
+
}
|
|
3744
|
+
return new TemplateStringNode(parts, token);
|
|
3745
|
+
}
|
|
3568
3746
|
parse(inlineMode = false) {
|
|
3569
3747
|
if (this.tolerant && !inlineMode) {
|
|
3570
3748
|
this.error("PARSER_TOLERANT_REQUIRES_INLINE" /* TOLERANT_REQUIRES_INLINE */);
|
|
@@ -8215,6 +8393,47 @@ var Interpreter = class {
|
|
|
8215
8393
|
visitStringNode(node) {
|
|
8216
8394
|
return new StringSymbol(node.value, this.config);
|
|
8217
8395
|
}
|
|
8396
|
+
visitTemplateStringNode(node) {
|
|
8397
|
+
if (node.parts.length === 0) {
|
|
8398
|
+
return new StringSymbol("", this.config);
|
|
8399
|
+
}
|
|
8400
|
+
if (node.parts.length === 1) {
|
|
8401
|
+
const val = this.visit(node.parts[0]);
|
|
8402
|
+
this.validateTemplateValue(val, node);
|
|
8403
|
+
return val;
|
|
8404
|
+
}
|
|
8405
|
+
let result = "";
|
|
8406
|
+
for (const part of node.parts) {
|
|
8407
|
+
const val = this.visit(part);
|
|
8408
|
+
this.validateTemplateValue(val, node);
|
|
8409
|
+
result += val.toString();
|
|
8410
|
+
}
|
|
8411
|
+
return new StringSymbol(result, this.config);
|
|
8412
|
+
}
|
|
8413
|
+
/**
|
|
8414
|
+
* Validate that a value is a primitive type allowed in template string interpolation.
|
|
8415
|
+
* Lists, Dictionaries, and non-hex Colors are rejected.
|
|
8416
|
+
*/
|
|
8417
|
+
validateTemplateValue(val, node) {
|
|
8418
|
+
if (val instanceof ListSymbol) {
|
|
8419
|
+
throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
|
|
8420
|
+
token: node.token,
|
|
8421
|
+
data: { valueType: "List" }
|
|
8422
|
+
});
|
|
8423
|
+
}
|
|
8424
|
+
if (val instanceof DictionarySymbol) {
|
|
8425
|
+
throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
|
|
8426
|
+
token: node.token,
|
|
8427
|
+
data: { valueType: "Dictionary" }
|
|
8428
|
+
});
|
|
8429
|
+
}
|
|
8430
|
+
if (val instanceof ColorSymbol && !val.isHex()) {
|
|
8431
|
+
throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
|
|
8432
|
+
token: node.token,
|
|
8433
|
+
data: { valueType: `Color.${val.subType}` }
|
|
8434
|
+
});
|
|
8435
|
+
}
|
|
8436
|
+
}
|
|
8218
8437
|
/**
|
|
8219
8438
|
* Bare identifiers are treated as string literals if not found as variables
|
|
8220
8439
|
* Check symbol table first (variables override references), then references
|