@primmel/primmel 1.21.13 → 1.21.14

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.
@@ -2561,7 +2561,7 @@ var OPERATORS = [
2561
2561
  ".",
2562
2562
  "|"
2563
2563
  ];
2564
- var NAV_OPS = /* @__PURE__ */ new Set(["forAll", "exists", "select"]);
2564
+ var NAV_OPS = /* @__PURE__ */ new Set(["forAll", "exists", "select", "collect"]);
2565
2565
  function lex(src) {
2566
2566
  const tokens = [];
2567
2567
  let i = 0;
@@ -2695,6 +2695,29 @@ var ExprParser = class {
2695
2695
  return inner;
2696
2696
  }
2697
2697
  if (tok.kind === "name") {
2698
+ if (tok.value === "true" || tok.value === "false") {
2699
+ return { type: "bool", value: tok.value === "true" };
2700
+ }
2701
+ if (tok.value === "if") {
2702
+ const cond = this.parseLevel(0);
2703
+ const thenTok = this.take();
2704
+ if (thenTok.kind !== "name" || thenTok.value !== "then") {
2705
+ throw new Error('expression: expected "then" in the conditional');
2706
+ }
2707
+ const whenTrue = this.parseLevel(0);
2708
+ const elseTok = this.take();
2709
+ if (elseTok.kind !== "name" || elseTok.value !== "else") {
2710
+ throw new Error('expression: expected "else" in the conditional');
2711
+ }
2712
+ const whenFalse = this.parseLevel(0);
2713
+ const endTok = this.take();
2714
+ if (endTok.kind !== "name" || endTok.value !== "endif") {
2715
+ throw new Error(
2716
+ 'expression: expected "endif" to close the conditional'
2717
+ );
2718
+ }
2719
+ return { type: "ifelse", cond, then: whenTrue, else: whenFalse };
2720
+ }
2698
2721
  const segs = [tok.value];
2699
2722
  while (this.peek()?.kind === "op" && this.peek().value === ".") {
2700
2723
  this.take();
@@ -2734,7 +2757,7 @@ var ExprParser = class {
2734
2757
  const opTok = this.take();
2735
2758
  if (opTok.kind !== "name" || !NAV_OPS.has(opTok.value)) {
2736
2759
  throw new Error(
2737
- "expression: expected a collection iterator (forAll | exists | select)"
2760
+ "expression: expected a collection iterator (forAll | exists | select | collect)"
2738
2761
  );
2739
2762
  }
2740
2763
  if (this.peek()?.kind !== "op" || this.peek().value !== "(") {
@@ -2785,6 +2808,13 @@ function freeIdentifiers(ast) {
2785
2808
  return;
2786
2809
  case "str":
2787
2810
  return;
2811
+ case "bool":
2812
+ return;
2813
+ case "ifelse":
2814
+ walk(node.cond, bound);
2815
+ walk(node.then, bound);
2816
+ walk(node.else, bound);
2817
+ return;
2788
2818
  case "name": {
2789
2819
  if (bound.has(node.path[0].split(".")[0])) {
2790
2820
  return;
@@ -2823,6 +2853,10 @@ function renderExpression(ast) {
2823
2853
  return String(ast.value);
2824
2854
  case "str":
2825
2855
  return "'" + ast.value + "'";
2856
+ case "bool":
2857
+ return ast.value ? "true" : "false";
2858
+ case "ifelse":
2859
+ return "if " + renderExpression(ast.cond) + " then " + renderExpression(ast.then) + " else " + renderExpression(ast.else) + " endif";
2826
2860
  case "name":
2827
2861
  return ast.path.join(".");
2828
2862
  case "call":
@@ -26538,9 +26572,12 @@ function checkPackage(dir, options = {}) {
26538
26572
  if (INLINE_FUNCTION_WORDS.has(call)) {
26539
26573
  continue;
26540
26574
  }
26575
+ if (globalExprNames.has(call)) {
26576
+ continue;
26577
+ }
26541
26578
  if (call.includes(".")) {
26542
26579
  const root = call.split(".")[0];
26543
- if (argNames.has(root) || root === "self" || CONTEXT_ROOTS.has(root)) {
26580
+ if (argNames.has(root) || globalExprNames.has(root) || root === "self" || CONTEXT_ROOTS.has(root)) {
26544
26581
  continue;
26545
26582
  }
26546
26583
  }
@@ -26700,6 +26737,17 @@ function checkPackage(dir, options = {}) {
26700
26737
  return null;
26701
26738
  case "str":
26702
26739
  return null;
26740
+ case "bool":
26741
+ return null;
26742
+ case "ifelse": {
26743
+ kindOf(node.cond);
26744
+ const l = kindOf(node.then);
26745
+ const r = kindOf(node.else);
26746
+ if (l !== void 0 && r !== void 0 && l !== null && r !== null && l !== r) {
26747
+ kindMixErr(node, l, r);
26748
+ }
26749
+ return l !== void 0 && l !== null ? l : r;
26750
+ }
26703
26751
  case "name": {
26704
26752
  const root = node.path[0];
26705
26753
  if (node.path.length > 1 && (root === "self" || CONTEXT_ROOTS.has(root))) {
@@ -26747,7 +26795,7 @@ function checkPackage(dir, options = {}) {
26747
26795
  case "unop":
26748
26796
  return node.op === "not" ? null : kindOf(node.operand);
26749
26797
  case "nav":
26750
- return node.op === "select" ? void 0 : null;
26798
+ return node.op === "select" ? void 0 : node.op === "collect" ? kindOf(node.body) : null;
26751
26799
  case "binop": {
26752
26800
  if (["<=", ">=", "<", ">", "=", "!=", "\u2260"].includes(node.op)) {
26753
26801
  const l2 = kindOf(node.left);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primmel/primmel",
3
- "version": "1.21.13",
3
+ "version": "1.21.14",
4
4
  "description": "Primmel — parser, types, and serializer for the Primmel modelling language (successor to MMEL)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",