@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.
Files changed (71) hide show
  1. package/dist/chunk-33CDF4L4.js +6444 -0
  2. package/dist/chunk-33CDF4L4.js.map +1 -0
  3. package/dist/chunk-AXH5N7KV.js +99 -0
  4. package/dist/chunk-AXH5N7KV.js.map +1 -0
  5. package/dist/chunk-GJIOYGP6.js +6446 -0
  6. package/dist/chunk-GJIOYGP6.js.map +1 -0
  7. package/dist/chunk-NGG6MBER.js +6452 -0
  8. package/dist/chunk-NGG6MBER.js.map +1 -0
  9. package/dist/cli.js +234 -7
  10. package/dist/cli.js.map +1 -1
  11. package/dist/compliance-suite.js +2 -2
  12. package/dist/config-DtbN3iyg.d.ts +918 -0
  13. package/dist/lib/{chunk-DFN353G4.js → chunk-6FR6JBDM.js} +238 -9
  14. package/dist/lib/chunk-6FR6JBDM.js.map +1 -0
  15. package/dist/lib/{chunk-QYRJ6NSL.cjs → chunk-LEYHQJTL.cjs} +3 -2
  16. package/dist/lib/chunk-LEYHQJTL.cjs.map +1 -0
  17. package/dist/lib/{chunk-GKSWF7FF.cjs → chunk-LMGHS2NP.cjs} +102 -100
  18. package/dist/lib/chunk-LMGHS2NP.cjs.map +1 -0
  19. package/dist/lib/{chunk-LI2D53SH.js → chunk-LSTH2XJ4.js} +5 -3
  20. package/dist/lib/chunk-LSTH2XJ4.js.map +1 -0
  21. package/dist/lib/{chunk-YD3MIYOO.js → chunk-ODVWXGOM.js} +3 -2
  22. package/dist/lib/chunk-ODVWXGOM.js.map +1 -0
  23. package/dist/lib/{chunk-AQEJB7EO.cjs → chunk-ZURBS3EE.cjs} +780 -551
  24. package/dist/lib/chunk-ZURBS3EE.cjs.map +1 -0
  25. package/dist/lib/index.cjs +91 -91
  26. package/dist/lib/index.d.cts +4 -4
  27. package/dist/lib/index.d.ts +4 -4
  28. package/dist/lib/index.js +3 -3
  29. package/dist/lib/{interpreter-DNmBc--s.d.ts → interpreter-6QwMkUqD.d.cts} +30 -2
  30. package/dist/lib/{interpreter-CP7CNwDa.d.cts → interpreter-v7WiwSP9.d.ts} +30 -2
  31. package/dist/lib/interpreter.cjs +73 -73
  32. package/dist/lib/interpreter.d.cts +4 -4
  33. package/dist/lib/interpreter.d.ts +4 -4
  34. package/dist/lib/interpreter.js +3 -3
  35. package/dist/lib/processor-node.cjs +12 -12
  36. package/dist/lib/processor-node.d.cts +3 -3
  37. package/dist/lib/processor-node.d.ts +3 -3
  38. package/dist/lib/processor-node.js +3 -3
  39. package/dist/lib/processor.cjs +17 -17
  40. package/dist/lib/processor.d.cts +4 -4
  41. package/dist/lib/processor.d.ts +4 -4
  42. package/dist/lib/processor.js +3 -3
  43. package/dist/lib/schema.cjs +5 -5
  44. package/dist/lib/schema.d.cts +1 -1
  45. package/dist/lib/schema.d.ts +1 -1
  46. package/dist/lib/schema.js +3 -3
  47. package/dist/lib/syntax-highlighting.cjs +15 -15
  48. package/dist/lib/syntax-highlighting.d.cts +1 -1
  49. package/dist/lib/syntax-highlighting.d.ts +1 -1
  50. package/dist/lib/syntax-highlighting.js +2 -2
  51. package/dist/lib/{types-DHgmzR1Z.d.ts → types-BI0AZ4Ej.d.ts} +2 -2
  52. package/dist/lib/{types-BimJex2v.d.cts → types-EB8V9c46.d.cts} +1 -0
  53. package/dist/lib/{types-BimJex2v.d.ts → types-EB8V9c46.d.ts} +1 -0
  54. package/dist/lib/{types-DsJuwrq3.d.cts → types-cFwP43uv.d.cts} +2 -2
  55. package/dist/lib/types.cjs +6 -6
  56. package/dist/lib/types.d.cts +1 -1
  57. package/dist/lib/types.d.ts +1 -1
  58. package/dist/lib/types.js +1 -1
  59. package/dist/processor/index.d.ts +1 -1
  60. package/dist/processor/index.js +2 -2
  61. package/dist/repl.d.ts +1 -1
  62. package/dist/repl.js +2 -2
  63. package/dist/types.d.ts +1 -1
  64. package/dist/types.js +1 -1
  65. package/package.json +1 -1
  66. package/dist/lib/chunk-AQEJB7EO.cjs.map +0 -1
  67. package/dist/lib/chunk-DFN353G4.js.map +0 -1
  68. package/dist/lib/chunk-GKSWF7FF.cjs.map +0 -1
  69. package/dist/lib/chunk-LI2D53SH.js.map +0 -1
  70. package/dist/lib/chunk-QYRJ6NSL.cjs.map +0 -1
  71. 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.32.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
- return this.explicitList();
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
- return new BooleanNode(token.value === "true" /* TRUE */, token);
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
- return new NullNode(token);
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
- return new HexColorNode(token);
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