@lokascript/framework 3.1.0 → 3.2.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/index.cjs CHANGED
@@ -1953,7 +1953,7 @@ var StringLiteralExtractor = class {
1953
1953
  }
1954
1954
  canExtract(input, position) {
1955
1955
  const char = input[position];
1956
- if (char === "'" && position > 0 && /[\p{L}\p{N}_)\]]/u.test(input[position - 1])) {
1956
+ if (char === "'" && position > 0 && /[\p{L}\p{M}\p{N}_)\]]/u.test(input[position - 1])) {
1957
1957
  return false;
1958
1958
  }
1959
1959
  return char === '"' || char === "'" || char === "`" || char === "\u201C" || // Chinese double quote open "
@@ -2498,11 +2498,18 @@ function convertRepeat(node) {
2498
2498
  roles.condition = convertValue(node.whileCondition);
2499
2499
  } else if (typeof node.untilEvent === "string") {
2500
2500
  variant = "until";
2501
- roles.condition = (0, import_intent.createLiteral)(node.untilEvent);
2501
+ roles.loopType = (0, import_intent.createLiteral)("until-event");
2502
+ roles.event = (0, import_intent.createLiteral)(node.untilEvent);
2503
+ if (node.untilEventTarget && typeof node.untilEventTarget === "object") {
2504
+ roles.source = convertValue(node.untilEventTarget);
2505
+ }
2502
2506
  } else {
2503
2507
  variant = "forever";
2504
2508
  }
2505
- return (0, import_intent.createLoopNode)("repeat", roles, variant, body);
2509
+ return (0, import_intent.createLoopNode)("repeat", roles, variant, body, void 0, indexNameOf(node));
2510
+ }
2511
+ function indexNameOf(node) {
2512
+ return typeof node.indexName === "string" ? node.indexName : void 0;
2506
2513
  }
2507
2514
  function convertForEach(node) {
2508
2515
  const bodyNodes = Array.isArray(node.body) ? node.body : [];
@@ -2512,8 +2519,7 @@ function convertForEach(node) {
2512
2519
  roles.source = convertValue(node.collection);
2513
2520
  }
2514
2521
  const itemName = typeof node.itemName === "string" ? node.itemName : void 0;
2515
- const indexName = typeof node.indexName === "string" ? node.indexName : void 0;
2516
- return (0, import_intent.createLoopNode)("repeat", roles, "for", body, itemName, indexName);
2522
+ return (0, import_intent.createLoopNode)("repeat", roles, "for", body, itemName, indexNameOf(node));
2517
2523
  }
2518
2524
  function convertWhile(node) {
2519
2525
  const bodyNodes = Array.isArray(node.body) ? node.body : [];
@@ -2522,7 +2528,7 @@ function convertWhile(node) {
2522
2528
  if (node.condition && typeof node.condition === "object") {
2523
2529
  roles.condition = convertValue(node.condition);
2524
2530
  }
2525
- return (0, import_intent.createLoopNode)("repeat", roles, "while", body);
2531
+ return (0, import_intent.createLoopNode)("repeat", roles, "while", body, void 0, indexNameOf(node));
2526
2532
  }
2527
2533
  function convertValue(node) {
2528
2534
  switch (node.type) {
@@ -2849,28 +2855,64 @@ function convertCommand2(node) {
2849
2855
  roles
2850
2856
  };
2851
2857
  }
2858
+ function block(nodes) {
2859
+ return { type: "block", commands: (nodes ?? []).map(semanticNodeToRuntimeAST) };
2860
+ }
2852
2861
  function convertConditional(node) {
2862
+ const name = node.action === "unless" ? "unless" : "if";
2853
2863
  const conditionValue = node.roles.get("condition");
2864
+ if (!conditionValue) return { type: "command", name, args: [] };
2854
2865
  return {
2855
2866
  type: "command",
2856
- name: "if",
2857
- args: conditionValue ? [semanticValueToAST(conditionValue)] : [],
2858
- condition: conditionValue ? semanticValueToAST(conditionValue) : void 0,
2859
- thenBranch: (node.thenBranch ?? []).map(semanticNodeToRuntimeAST),
2860
- elseBranch: (node.elseBranch ?? []).map(semanticNodeToRuntimeAST)
2867
+ name,
2868
+ args: [
2869
+ semanticValueToAST(conditionValue),
2870
+ block(node.thenBranch),
2871
+ ...node.elseBranch && node.elseBranch.length > 0 ? [block(node.elseBranch)] : []
2872
+ ]
2861
2873
  };
2862
2874
  }
2875
+ var LOOP_FORMS = /* @__PURE__ */ new Set(["for", "times", "while", "until", "until-event", "forever"]);
2876
+ function valueText(value) {
2877
+ if (!value) return void 0;
2878
+ if (value.type === "literal") return String(value.value);
2879
+ if (value.type === "expression") return value.raw;
2880
+ if (value.type === "reference" || value.type === "selector") return value.value;
2881
+ return void 0;
2882
+ }
2863
2883
  function convertLoop(node) {
2864
- const countValue = node.roles.get("patient") || node.roles.get("count");
2865
- return {
2866
- type: "command",
2867
- name: "repeat",
2868
- args: countValue ? [semanticValueToAST(countValue)] : [],
2869
- loopVariant: node.loopVariant ?? "forever",
2870
- body: (node.body ?? []).map(semanticNodeToRuntimeAST),
2871
- loopVariable: node.loopVariable,
2872
- indexVariable: node.indexVariable
2884
+ const text = (value) => ({ type: "string", value });
2885
+ const operand = (role) => {
2886
+ const value = node.roles.get(role);
2887
+ return value ? semanticValueToAST(value) : void 0;
2873
2888
  };
2889
+ const declared = valueText(node.roles.get("loopType"));
2890
+ const form = node.action === "for" ? "for" : declared && LOOP_FORMS.has(declared) ? declared : node.loopVariant ?? "forever";
2891
+ const modifiers = { loopType: text(form) };
2892
+ const slot = (name, value) => {
2893
+ if (value) modifiers[name] = value;
2894
+ };
2895
+ switch (form) {
2896
+ case "for":
2897
+ if (node.loopVariable) slot("for", text(node.loopVariable));
2898
+ slot("in", operand("source"));
2899
+ break;
2900
+ case "times":
2901
+ slot("times", operand("quantity") ?? operand("patient") ?? operand("count"));
2902
+ break;
2903
+ case "while":
2904
+ case "until":
2905
+ slot(form, operand("condition"));
2906
+ break;
2907
+ case "until-event": {
2908
+ const event = valueText(node.roles.get("event"));
2909
+ if (event) slot("event", text(event));
2910
+ slot("from", operand("source"));
2911
+ break;
2912
+ }
2913
+ }
2914
+ if (node.indexVariable) slot("index", text(node.indexVariable));
2915
+ return { type: "command", name: "repeat", args: [block(node.body)], modifiers };
2874
2916
  }
2875
2917
  function semanticValueToAST(value) {
2876
2918
  switch (value.type) {
@@ -6629,7 +6671,7 @@ function accumulateIndented(statements, config) {
6629
6671
  const top = stack[stack.length - 1];
6630
6672
  if (top.indent >= targetIndent) {
6631
6673
  stack.pop();
6632
- const block = {
6674
+ const block2 = {
6633
6675
  type: top.type,
6634
6676
  ...top.name != null && { name: top.name },
6635
6677
  statements: top.stmts,
@@ -6638,9 +6680,9 @@ function accumulateIndented(statements, config) {
6638
6680
  indent: top.indent
6639
6681
  };
6640
6682
  if (stack.length > 0) {
6641
- stack[stack.length - 1].children.push(block);
6683
+ stack[stack.length - 1].children.push(block2);
6642
6684
  } else {
6643
- rootBlocks.push(block);
6685
+ rootBlocks.push(block2);
6644
6686
  }
6645
6687
  } else {
6646
6688
  break;