@primmel/primmel 1.21.14 → 1.21.16

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.
@@ -1998,7 +1998,6 @@ var st = function(e, t) {
1998
1998
  for (let e of t.block.split("\n")) n += e === "" ? "\n" : " " + e + "\n";
1999
1999
  n += " }\n";
2000
2000
  }
2001
- for (let t of e.stepRequires ?? []) n += " requires { " + t + " }\n";
2002
2001
  let i = e.inputRefs && e.inputRefs.length > 0 ? e.inputRefs : e.input.map((e) => e.id);
2003
2002
  if (i.length > 0) {
2004
2003
  n += " reference_data_registry {\n";
@@ -6409,8 +6408,11 @@ function Da() {
6409
6408
  };
6410
6409
  }
6411
6410
  function Oa(e) {
6412
- let t = Da();
6413
- return Aa(n(e), t, 0), t;
6411
+ let t = Da(), r = n(e);
6412
+ Aa(r, t, 0);
6413
+ let a = 0;
6414
+ for (; a < r.length;) r[a] === "when" && r[a + 1]?.startsWith("{") ? (t.when = ce(i(r[a + 1])), a += 2) : a += 1;
6415
+ return t;
6414
6416
  }
6415
6417
  function ka(e) {
6416
6418
  return ce(e);
@@ -6550,8 +6552,12 @@ var Na = function(e, t) {
6550
6552
  else if (e === "binds_to") o.bindsTo = Ta(s[c++]);
6551
6553
  else if (e === "subjects") o.subjects = ja(i(s[c++]));
6552
6554
  else if (e === "parameters") o.parameters = Ma(i(s[c++]));
6553
- else if (e === "limit") o.limit = Oa(i(s[c++]));
6554
- else if (e === "applicability") o.applicability = R(i(s[c++]));
6555
+ else if (e === "limit") {
6556
+ let e = "";
6557
+ s[c] !== void 0 && !s[c].startsWith("{") && (e = a(s[c++]));
6558
+ let t = Oa(i(s[c++]));
6559
+ e ? (t.name = e, (o.limits ??= []).push(t)) : o.limit ? (o.limits ??= []).push(t) : o.limit = t;
6560
+ } else if (e === "applicability") o.applicability = R(i(s[c++]));
6555
6561
  else if (e === "channel") o.channel = a(s[c++]);
6556
6562
  else if (e === "report_row") o.reportRow = a(s[c++]);
6557
6563
  else if (e === "obligation") o.obligation = a(s[c++]);
@@ -6580,12 +6586,17 @@ var Na = function(e, t) {
6580
6586
  };
6581
6587
  function Pa(e) {
6582
6588
  if (e.argsBound) {
6583
- let t = " limit {\n";
6589
+ let t = e.name ? " limit " + JSON.stringify(e.name) + " {\n" : " limit {\n";
6584
6590
  if ((e.args ?? []).length > 0) {
6585
6591
  t += " args {\n";
6586
6592
  for (let n of e.args ?? []) t += " " + n.name + " <- " + n.source + "\n";
6587
6593
  t += " }\n";
6588
6594
  }
6595
+ if (e.when) {
6596
+ t += " when {\n";
6597
+ for (let n of e.when.split("\n")) t += " " + n + "\n";
6598
+ t += " }\n";
6599
+ }
6589
6600
  t += " expression {\n";
6590
6601
  for (let n of e.expression.split("\n")) t += " " + n + "\n";
6591
6602
  if (t += " }\n", e.modality && (t += " modality " + e.modality + "\n"), e.relativeTo && (t += " relative_to " + e.relativeTo + "\n"), e.notes && (t += " notes \"" + s(e.notes) + "\"\n"), e.accepts) {
@@ -6620,7 +6631,11 @@ var Fa = function(e) {
6620
6631
  }
6621
6632
  t += " }\n";
6622
6633
  }
6623
- if (e.limit && (t += Pa(e.limit)), e.applicability.length > 0 && (t += " applicability {\n " + z(e.applicability).trim() + "\n }\n"), e.channel && (t += " channel " + e.channel + "\n"), e.reportRow && (t += " report_row " + e.reportRow + "\n"), e.obligation && (t += " obligation " + e.obligation + "\n"), e.acceptanceCriteria && (t += " acceptance_criteria {\n " + e.acceptanceCriteria + "\n }\n"), e.verificationMethod) {
6634
+ if (e.limit) {
6635
+ t += Pa(e.limit);
6636
+ for (let n of e.limits ?? []) t += Pa(n);
6637
+ }
6638
+ if (e.applicability.length > 0 && (t += " applicability {\n " + z(e.applicability).trim() + "\n }\n"), e.channel && (t += " channel " + e.channel + "\n"), e.reportRow && (t += " report_row " + e.reportRow + "\n"), e.obligation && (t += " obligation " + e.obligation + "\n"), e.acceptanceCriteria && (t += " acceptance_criteria {\n " + e.acceptanceCriteria + "\n }\n"), e.verificationMethod) {
6624
6639
  let n = " verification { method " + e.verificationMethod;
6625
6640
  e.verificationDescription && (n += " description \"" + s(e.verificationDescription) + "\""), t += n + " }\n";
6626
6641
  }
@@ -4114,9 +4114,6 @@ var dumpProcess = function(process2, ctx) {
4114
4114
  }
4115
4115
  out += " }\n";
4116
4116
  }
4117
- for (const req of process2.stepRequires ?? []) {
4118
- out += " requires { " + req + " }\n";
4119
- }
4120
4117
  const inputIds = process2.inputRefs && process2.inputRefs.length > 0 ? process2.inputRefs : process2.input.map((r) => r.id);
4121
4118
  if (inputIds.length > 0) {
4122
4119
  out += " reference_data_registry {\n";
@@ -12011,7 +12008,17 @@ function blankLimit() {
12011
12008
  }
12012
12009
  function readLimit(block) {
12013
12010
  const limit = blankLimit();
12014
- readLegacyLimitFields(tokenize(block), limit, 0);
12011
+ const lt = tokenize(block);
12012
+ readLegacyLimitFields(lt, limit, 0);
12013
+ let i = 0;
12014
+ while (i < lt.length) {
12015
+ if (lt[i] === "when" && lt[i + 1]?.startsWith("{")) {
12016
+ limit.when = canonicalizeExpression(unwrapBlock(lt[i + 1]));
12017
+ i += 2;
12018
+ } else {
12019
+ i += 1;
12020
+ }
12021
+ }
12015
12022
  return limit;
12016
12023
  }
12017
12024
  function readExpressionBlock(raw) {
@@ -12242,7 +12249,19 @@ var parseRequirement = function(id, data) {
12242
12249
  } else if (cmd === "parameters") {
12243
12250
  result.parameters = readParameters(unwrapBlock(t[i++]));
12244
12251
  } else if (cmd === "limit") {
12245
- result.limit = readLimit(unwrapBlock(t[i++]));
12252
+ let name = "";
12253
+ if (t[i] !== void 0 && !t[i].startsWith("{")) {
12254
+ name = stripWrapping(t[i++]);
12255
+ }
12256
+ const lim = readLimit(unwrapBlock(t[i++]));
12257
+ if (name) {
12258
+ lim.name = name;
12259
+ (result.limits ??= []).push(lim);
12260
+ } else if (result.limit) {
12261
+ (result.limits ??= []).push(lim);
12262
+ } else {
12263
+ result.limit = lim;
12264
+ }
12246
12265
  } else if (cmd === "applicability") {
12247
12266
  result.applicability = parseApplicability(unwrapBlock(t[i++]));
12248
12267
  } else if (cmd === "channel") {
@@ -12301,7 +12320,8 @@ var parseRequirement = function(id, data) {
12301
12320
  };
12302
12321
  function dumpLimit(limit) {
12303
12322
  if (limit.argsBound) {
12304
- let out2 = " limit {\n";
12323
+ const head = limit.name ? " limit " + JSON.stringify(limit.name) + " {\n" : " limit {\n";
12324
+ let out2 = head;
12305
12325
  if ((limit.args ?? []).length > 0) {
12306
12326
  out2 += " args {\n";
12307
12327
  for (const a of limit.args ?? []) {
@@ -12309,6 +12329,13 @@ function dumpLimit(limit) {
12309
12329
  }
12310
12330
  out2 += " }\n";
12311
12331
  }
12332
+ if (limit.when) {
12333
+ out2 += " when {\n";
12334
+ for (const line of limit.when.split("\n")) {
12335
+ out2 += " " + line + "\n";
12336
+ }
12337
+ out2 += " }\n";
12338
+ }
12312
12339
  out2 += " expression {\n";
12313
12340
  for (const line of limit.expression.split("\n")) {
12314
12341
  out2 += " " + line + "\n";
@@ -12458,6 +12485,9 @@ var dumpRequirement = function(r) {
12458
12485
  }
12459
12486
  if (r.limit) {
12460
12487
  out += dumpLimit(r.limit);
12488
+ for (const lim of r.limits ?? []) {
12489
+ out += dumpLimit(lim);
12490
+ }
12461
12491
  }
12462
12492
  if (r.applicability.length > 0) {
12463
12493
  out += " applicability {\n " + dumpApplicabilityEntries(r.applicability).trim() + "\n }\n";
@@ -26821,9 +26851,76 @@ function checkPackage(dir, options = {}) {
26821
26851
  };
26822
26852
  kindOf(ast);
26823
26853
  };
26854
+ const checkGuard = (rid, name, lim) => {
26855
+ if (!lim.when) {
26856
+ return;
26857
+ }
26858
+ const args2 = new Set((lim.args ?? []).map((a) => a.name));
26859
+ try {
26860
+ const ast = parseExpression(lim.when);
26861
+ const ids = freeIdentifiers(ast);
26862
+ for (const call of new Set(ids.calls)) {
26863
+ if (!INLINE_FUNCTION_WORDS.has(call)) {
26864
+ err(
26865
+ "C171",
26866
+ `requirement ${rid}: limit ${name}'s when-guard calls "${call}(\u2026)", which no argument binds and which is not in the expression function vocabulary (expression-identifiers-resolve)`
26867
+ );
26868
+ }
26869
+ }
26870
+ for (const id of new Set(ids.names)) {
26871
+ const root = id.split(".")[0];
26872
+ if (args2.has(id) || id.includes(".") && (root === "self" || CONTEXT_ROOTS.has(root) || args2.has(root))) {
26873
+ continue;
26874
+ }
26875
+ err(
26876
+ "C171",
26877
+ `requirement ${rid}: limit ${name}'s when-guard names "${id}", which no argument binds (expression-identifiers-resolve)`
26878
+ );
26879
+ }
26880
+ const top = ast.type;
26881
+ if (!(top === "binop" && [
26882
+ "<=",
26883
+ ">=",
26884
+ "<",
26885
+ ">",
26886
+ "=",
26887
+ "!=",
26888
+ "\u2260",
26889
+ "and",
26890
+ "or",
26891
+ "xor",
26892
+ "implies"
26893
+ ].includes(ast.op) || top === "unop" && ast.op === "not")) {
26894
+ err(
26895
+ "C84",
26896
+ `requirement ${rid}: limit ${name}'s when-guard does not evaluate to a boolean \u2014 the guard is one comparison or logical composition (constraint-shape)`
26897
+ );
26898
+ }
26899
+ } catch (e) {
26900
+ err(
26901
+ "C171",
26902
+ `requirement ${rid}: limit ${name}'s when-guard does not parse \u2014 ${String(e.message ?? e)} (expression-identifiers-resolve)`
26903
+ );
26904
+ }
26905
+ };
26824
26906
  for (const r of standard.requirements ?? []) {
26825
26907
  if (r.limit?.argsBound) {
26826
26908
  checkInlineLimit("requirement", r.id, r.limit, null);
26909
+ checkGuard(r.id, "(the unnamed limit)", r.limit);
26910
+ }
26911
+ for (const lim of r.limits ?? []) {
26912
+ const label = lim.name ? `"${lim.name}"` : "(an unnamed limit)";
26913
+ if (lim.argsBound) {
26914
+ checkInlineLimit("requirement", r.id, lim, null);
26915
+ } else if (lim.expression) {
26916
+ err(
26917
+ "C171",
26918
+ `requirement ${r.id}: limit ${label} must carry the inline carrier \u2014 args { \u2026 } and expression { \u2026 } (expression-identifiers-resolve)`
26919
+ );
26920
+ }
26921
+ checkGuard(r.id, label, lim);
26922
+ }
26923
+ if (r.limit?.argsBound || (r.limits ?? []).length > 0) {
26827
26924
  continue;
26828
26925
  }
26829
26926
  const expr = r.limit?.expression;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primmel/primmel",
3
- "version": "1.21.14",
3
+ "version": "1.21.16",
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",