@tokens-studio/tokenscript-interpreter 0.33.0 → 0.36.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/chunk-GJIOYGP6.js +6446 -0
- package/dist/chunk-GJIOYGP6.js.map +1 -0
- package/dist/chunk-NGG6MBER.js +6452 -0
- package/dist/chunk-NGG6MBER.js.map +1 -0
- package/dist/cli.js +234 -7
- 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-DFN353G4.js → chunk-6FR6JBDM.js} +238 -9
- package/dist/lib/chunk-6FR6JBDM.js.map +1 -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-AQEJB7EO.cjs → chunk-ZURBS3EE.cjs} +780 -551
- package/dist/lib/chunk-ZURBS3EE.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
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.35.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 = [];
|
|
@@ -3420,7 +3479,9 @@ ${contextText}`;
|
|
|
3420
3479
|
factor() {
|
|
3421
3480
|
const token = this.currentToken;
|
|
3422
3481
|
if (token.type === "LBLOCK" /* LBLOCK */) {
|
|
3423
|
-
|
|
3482
|
+
let node = this.explicitList();
|
|
3483
|
+
node = this.attributeAccess(node);
|
|
3484
|
+
return node;
|
|
3424
3485
|
}
|
|
3425
3486
|
if (token.type === "OPERATION" /* OPERATION */ && (token.value === "+" /* ADD */ || token.value === "-" /* SUBTRACT */ || token.value === "!" /* LOGIC_NOT */)) {
|
|
3426
3487
|
this.eat("OPERATION" /* OPERATION */);
|
|
@@ -3436,11 +3497,15 @@ ${contextText}`;
|
|
|
3436
3497
|
}
|
|
3437
3498
|
if (token.type === "RESERVED_KEYWORD" /* RESERVED_KEYWORD */ && (token.value === "true" /* TRUE */ || token.value === "false" /* FALSE */)) {
|
|
3438
3499
|
this.eat("RESERVED_KEYWORD" /* RESERVED_KEYWORD */);
|
|
3439
|
-
|
|
3500
|
+
let boolNode = new BooleanNode(token.value === "true" /* TRUE */, token);
|
|
3501
|
+
boolNode = this.attributeAccess(boolNode);
|
|
3502
|
+
return boolNode;
|
|
3440
3503
|
}
|
|
3441
3504
|
if (token.type === "RESERVED_KEYWORD" /* RESERVED_KEYWORD */ && token.value === "null" /* NULL */) {
|
|
3442
3505
|
this.eat("RESERVED_KEYWORD" /* RESERVED_KEYWORD */);
|
|
3443
|
-
|
|
3506
|
+
let nullNode = new NullNode(token);
|
|
3507
|
+
nullNode = this.attributeAccess(nullNode);
|
|
3508
|
+
return nullNode;
|
|
3444
3509
|
}
|
|
3445
3510
|
if (token.type === "NUMBER" /* NUMBER */) {
|
|
3446
3511
|
return this.number();
|
|
@@ -3467,7 +3532,7 @@ ${contextText}`;
|
|
|
3467
3532
|
if (this.currentToken.type === "FORMAT" /* FORMAT */) {
|
|
3468
3533
|
return this.format(node);
|
|
3469
3534
|
}
|
|
3470
|
-
return node;
|
|
3535
|
+
return this.attributeAccess(node);
|
|
3471
3536
|
}
|
|
3472
3537
|
if (token.type === "PARTIAL_REFERENCE" /* PARTIAL_REFERENCE */) {
|
|
3473
3538
|
let node = this.reference();
|
|
@@ -3481,7 +3546,9 @@ ${contextText}`;
|
|
|
3481
3546
|
}
|
|
3482
3547
|
if (token.type === "HEX_COLOR" /* HEX_COLOR */) {
|
|
3483
3548
|
this.eat("HEX_COLOR" /* HEX_COLOR */);
|
|
3484
|
-
|
|
3549
|
+
let hexNode = new HexColorNode(token);
|
|
3550
|
+
hexNode = this.attributeAccess(hexNode);
|
|
3551
|
+
return hexNode;
|
|
3485
3552
|
}
|
|
3486
3553
|
if (token.type === "PARTIAL_STRING" /* PARTIAL_STRING */) {
|
|
3487
3554
|
this.eat("PARTIAL_STRING" /* PARTIAL_STRING */);
|
|
@@ -3506,6 +3573,9 @@ ${contextText}`;
|
|
|
3506
3573
|
node = this.attributeAccess(node);
|
|
3507
3574
|
return node;
|
|
3508
3575
|
}
|
|
3576
|
+
if (token.type === "TEMPLATE_STRING" /* TEMPLATE_STRING */) {
|
|
3577
|
+
return this.templateString();
|
|
3578
|
+
}
|
|
3509
3579
|
if (token.type === "EXPLICIT_STRING" /* EXPLICIT_STRING */) {
|
|
3510
3580
|
this.eat("EXPLICIT_STRING" /* EXPLICIT_STRING */);
|
|
3511
3581
|
let node = new StringNode(token);
|
|
@@ -3565,6 +3635,122 @@ ${contextText}`;
|
|
|
3565
3635
|
this.eat("RPAREN" /* RPAREN */);
|
|
3566
3636
|
return new FunctionCallNode(functionName.value, args, functionName);
|
|
3567
3637
|
}
|
|
3638
|
+
/**
|
|
3639
|
+
* Parse a TEMPLATE_STRING token into a TemplateStringNode.
|
|
3640
|
+
* Scans the raw content for:
|
|
3641
|
+
* - {ref.path} → ReferenceNode
|
|
3642
|
+
* - ${expression} → parsed sub-expression
|
|
3643
|
+
* - \{ \${ \` \\ → escaped literals (backslash removed)
|
|
3644
|
+
* - everything else → literal StringNode segments
|
|
3645
|
+
*/
|
|
3646
|
+
templateString() {
|
|
3647
|
+
const token = this.currentToken;
|
|
3648
|
+
const raw = token.value;
|
|
3649
|
+
this.eat("TEMPLATE_STRING" /* TEMPLATE_STRING */);
|
|
3650
|
+
const parts = [];
|
|
3651
|
+
let literal = "";
|
|
3652
|
+
let i = 0;
|
|
3653
|
+
const flushLiteral = () => {
|
|
3654
|
+
if (literal.length > 0) {
|
|
3655
|
+
parts.push(new StringNode({ ...token, value: literal }));
|
|
3656
|
+
literal = "";
|
|
3657
|
+
}
|
|
3658
|
+
};
|
|
3659
|
+
while (i < raw.length) {
|
|
3660
|
+
const ch = raw[i];
|
|
3661
|
+
if (ch === "\\" && i + 1 < raw.length) {
|
|
3662
|
+
const next = raw[i + 1];
|
|
3663
|
+
if (next === "{" || next === "`" || next === "\\") {
|
|
3664
|
+
literal += next;
|
|
3665
|
+
i += 2;
|
|
3666
|
+
continue;
|
|
3667
|
+
}
|
|
3668
|
+
if (next === "$") {
|
|
3669
|
+
if (i + 2 < raw.length && raw[i + 2] === "{") {
|
|
3670
|
+
literal += "${";
|
|
3671
|
+
i += 3;
|
|
3672
|
+
} else {
|
|
3673
|
+
literal += "$";
|
|
3674
|
+
i += 2;
|
|
3675
|
+
}
|
|
3676
|
+
continue;
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
if (ch === "$" && i + 1 < raw.length && raw[i + 1] === "{") {
|
|
3680
|
+
flushLiteral();
|
|
3681
|
+
const start = i + 2;
|
|
3682
|
+
let depth = 1;
|
|
3683
|
+
let j = start;
|
|
3684
|
+
while (j < raw.length && depth > 0) {
|
|
3685
|
+
if (raw[j] === "`") {
|
|
3686
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3687
|
+
message: "Nested template strings are not allowed inside ${...}"
|
|
3688
|
+
});
|
|
3689
|
+
}
|
|
3690
|
+
if (raw[j] === "{") depth++;
|
|
3691
|
+
else if (raw[j] === "}") depth--;
|
|
3692
|
+
if (depth > 0) j++;
|
|
3693
|
+
}
|
|
3694
|
+
if (depth !== 0) {
|
|
3695
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3696
|
+
message: "Unterminated ${...} in template string"
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3699
|
+
const exprStr = raw.slice(start, j);
|
|
3700
|
+
const subLexer = new Lexer(exprStr);
|
|
3701
|
+
const subParser = new _Parser(subLexer);
|
|
3702
|
+
const exprNode = subParser.expr();
|
|
3703
|
+
for (const ref of subParser.requiredReferences) {
|
|
3704
|
+
this.requiredReferences.add(ref);
|
|
3705
|
+
}
|
|
3706
|
+
parts.push(exprNode);
|
|
3707
|
+
i = j + 1;
|
|
3708
|
+
continue;
|
|
3709
|
+
}
|
|
3710
|
+
if (ch === "{") {
|
|
3711
|
+
flushLiteral();
|
|
3712
|
+
const start = i + 1;
|
|
3713
|
+
let j = start;
|
|
3714
|
+
while (j < raw.length && raw[j] !== "}") {
|
|
3715
|
+
if (raw[j] === "{") {
|
|
3716
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3717
|
+
message: "Nested braces in template reference"
|
|
3718
|
+
});
|
|
3719
|
+
}
|
|
3720
|
+
j++;
|
|
3721
|
+
}
|
|
3722
|
+
if (j >= raw.length) {
|
|
3723
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3724
|
+
message: "Unterminated {ref} in template string"
|
|
3725
|
+
});
|
|
3726
|
+
}
|
|
3727
|
+
let refPath = raw.slice(start, j);
|
|
3728
|
+
refPath = refPath.replace(/[ \t]/g, "");
|
|
3729
|
+
if (refPath.length === 0) {
|
|
3730
|
+
this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
|
|
3731
|
+
message: "Empty reference in template string"
|
|
3732
|
+
});
|
|
3733
|
+
}
|
|
3734
|
+
this.requiredReferences.add(refPath);
|
|
3735
|
+
parts.push(
|
|
3736
|
+
new ReferenceNode({
|
|
3737
|
+
...token,
|
|
3738
|
+
type: "REFERENCE" /* REFERENCE */,
|
|
3739
|
+
value: refPath
|
|
3740
|
+
})
|
|
3741
|
+
);
|
|
3742
|
+
i = j + 1;
|
|
3743
|
+
continue;
|
|
3744
|
+
}
|
|
3745
|
+
literal += ch;
|
|
3746
|
+
i++;
|
|
3747
|
+
}
|
|
3748
|
+
flushLiteral();
|
|
3749
|
+
if (parts.length === 1 && parts[0] instanceof StringNode) {
|
|
3750
|
+
return parts[0];
|
|
3751
|
+
}
|
|
3752
|
+
return new TemplateStringNode(parts, token);
|
|
3753
|
+
}
|
|
3568
3754
|
parse(inlineMode = false) {
|
|
3569
3755
|
if (this.tolerant && !inlineMode) {
|
|
3570
3756
|
this.error("PARSER_TOLERANT_REQUIRES_INLINE" /* TOLERANT_REQUIRES_INLINE */);
|
|
@@ -8215,6 +8401,47 @@ var Interpreter = class {
|
|
|
8215
8401
|
visitStringNode(node) {
|
|
8216
8402
|
return new StringSymbol(node.value, this.config);
|
|
8217
8403
|
}
|
|
8404
|
+
visitTemplateStringNode(node) {
|
|
8405
|
+
if (node.parts.length === 0) {
|
|
8406
|
+
return new StringSymbol("", this.config);
|
|
8407
|
+
}
|
|
8408
|
+
if (node.parts.length === 1) {
|
|
8409
|
+
const val = this.visit(node.parts[0]);
|
|
8410
|
+
this.validateTemplateValue(val, node);
|
|
8411
|
+
return val;
|
|
8412
|
+
}
|
|
8413
|
+
let result = "";
|
|
8414
|
+
for (const part of node.parts) {
|
|
8415
|
+
const val = this.visit(part);
|
|
8416
|
+
this.validateTemplateValue(val, node);
|
|
8417
|
+
result += val.toString();
|
|
8418
|
+
}
|
|
8419
|
+
return new StringSymbol(result, this.config);
|
|
8420
|
+
}
|
|
8421
|
+
/**
|
|
8422
|
+
* Validate that a value is a primitive type allowed in template string interpolation.
|
|
8423
|
+
* Lists, Dictionaries, and non-hex Colors are rejected.
|
|
8424
|
+
*/
|
|
8425
|
+
validateTemplateValue(val, node) {
|
|
8426
|
+
if (val instanceof ListSymbol) {
|
|
8427
|
+
throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
|
|
8428
|
+
token: node.token,
|
|
8429
|
+
data: { valueType: "List" }
|
|
8430
|
+
});
|
|
8431
|
+
}
|
|
8432
|
+
if (val instanceof DictionarySymbol) {
|
|
8433
|
+
throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
|
|
8434
|
+
token: node.token,
|
|
8435
|
+
data: { valueType: "Dictionary" }
|
|
8436
|
+
});
|
|
8437
|
+
}
|
|
8438
|
+
if (val instanceof ColorSymbol && !val.isHex()) {
|
|
8439
|
+
throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
|
|
8440
|
+
token: node.token,
|
|
8441
|
+
data: { valueType: `Color.${val.subType}` }
|
|
8442
|
+
});
|
|
8443
|
+
}
|
|
8444
|
+
}
|
|
8218
8445
|
/**
|
|
8219
8446
|
* Bare identifiers are treated as string literals if not found as variables
|
|
8220
8447
|
* Check symbol table first (variables override references), then references
|