@cortex-js/compute-engine 0.56.0 → 0.57.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 (258) hide show
  1. package/dist/compile.esm.js +450 -42
  2. package/dist/compile.min.esm.js +57 -57
  3. package/dist/compile.min.umd.cjs +58 -58
  4. package/dist/compile.umd.cjs +450 -42
  5. package/dist/compute-engine.esm.js +677 -49
  6. package/dist/compute-engine.min.esm.js +62 -62
  7. package/dist/compute-engine.min.umd.cjs +62 -62
  8. package/dist/compute-engine.umd.cjs +677 -49
  9. package/dist/core.esm.js +676 -48
  10. package/dist/core.min.esm.js +61 -61
  11. package/dist/core.min.umd.cjs +61 -61
  12. package/dist/core.umd.cjs +676 -48
  13. package/dist/interval.esm.js +228 -16
  14. package/dist/interval.min.esm.js +6 -6
  15. package/dist/interval.min.umd.cjs +6 -6
  16. package/dist/interval.umd.cjs +228 -16
  17. package/dist/latex-syntax.esm.js +269 -16
  18. package/dist/latex-syntax.min.esm.js +6 -6
  19. package/dist/latex-syntax.min.umd.cjs +6 -6
  20. package/dist/latex-syntax.umd.cjs +269 -16
  21. package/dist/math-json.esm.js +2 -2
  22. package/dist/math-json.min.esm.js +2 -2
  23. package/dist/math-json.min.umd.cjs +2 -2
  24. package/dist/math-json.umd.cjs +2 -2
  25. package/dist/numerics.esm.js +2 -2
  26. package/dist/numerics.min.esm.js +2 -2
  27. package/dist/numerics.min.umd.cjs +2 -2
  28. package/dist/numerics.umd.cjs +2 -2
  29. package/dist/types/big-decimal/big-decimal.d.ts +1 -1
  30. package/dist/types/big-decimal/index.d.ts +1 -1
  31. package/dist/types/big-decimal/transcendentals.d.ts +1 -1
  32. package/dist/types/big-decimal/utils.d.ts +1 -1
  33. package/dist/types/common/ansi-codes.d.ts +1 -1
  34. package/dist/types/common/configuration-change.d.ts +1 -1
  35. package/dist/types/common/fuzzy-string-match.d.ts +1 -1
  36. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  37. package/dist/types/common/interruptible.d.ts +1 -1
  38. package/dist/types/common/one-of.d.ts +1 -1
  39. package/dist/types/common/signals.d.ts +1 -1
  40. package/dist/types/common/type/ast-nodes.d.ts +1 -1
  41. package/dist/types/common/type/boxed-type.d.ts +1 -1
  42. package/dist/types/common/type/lexer.d.ts +1 -1
  43. package/dist/types/common/type/parse.d.ts +1 -1
  44. package/dist/types/common/type/parser.d.ts +1 -1
  45. package/dist/types/common/type/primitive.d.ts +1 -1
  46. package/dist/types/common/type/reduce.d.ts +1 -1
  47. package/dist/types/common/type/serialize.d.ts +1 -1
  48. package/dist/types/common/type/subtype.d.ts +1 -1
  49. package/dist/types/common/type/type-builder.d.ts +1 -1
  50. package/dist/types/common/type/types.d.ts +1 -1
  51. package/dist/types/common/type/utils.d.ts +1 -1
  52. package/dist/types/common/utils.d.ts +1 -1
  53. package/dist/types/compile.d.ts +1 -1
  54. package/dist/types/compute-engine/assume.d.ts +1 -1
  55. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +6 -1
  56. package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
  57. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
  58. package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
  59. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
  60. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
  61. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  62. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  63. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  64. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  65. package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
  66. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  67. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  68. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
  69. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
  70. package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
  71. package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
  72. package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
  73. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  74. package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
  75. package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
  76. package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
  77. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  78. package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
  79. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
  80. package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
  81. package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
  82. package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
  83. package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
  84. package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
  85. package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
  86. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
  87. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  88. package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
  89. package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
  90. package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
  91. package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
  92. package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
  93. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  94. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
  95. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
  96. package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
  97. package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
  98. package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
  99. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
  100. package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
  101. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  102. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  103. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  104. package/dist/types/compute-engine/compilation/base-compiler.d.ts +55 -6
  105. package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
  106. package/dist/types/compute-engine/compilation/constant-folding.d.ts +1 -1
  107. package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
  108. package/dist/types/compute-engine/compilation/gpu-target.d.ts +1 -1
  109. package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
  110. package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
  111. package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
  112. package/dist/types/compute-engine/compilation/types.d.ts +1 -1
  113. package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
  114. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  115. package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
  116. package/dist/types/compute-engine/engine-cache.d.ts +1 -1
  117. package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
  118. package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
  119. package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
  120. package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
  121. package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
  122. package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
  123. package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
  124. package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
  125. package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
  126. package/dist/types/compute-engine/engine-scope.d.ts +1 -1
  127. package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
  128. package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
  129. package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
  130. package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
  131. package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
  132. package/dist/types/compute-engine/free-functions.d.ts +1 -1
  133. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  134. package/dist/types/compute-engine/global-types.d.ts +1 -1
  135. package/dist/types/compute-engine/index.d.ts +3 -2
  136. package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
  137. package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
  138. package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
  139. package/dist/types/compute-engine/interval/index.d.ts +1 -1
  140. package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
  141. package/dist/types/compute-engine/interval/types.d.ts +1 -1
  142. package/dist/types/compute-engine/interval/util.d.ts +1 -1
  143. package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +1 -1
  144. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  145. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  146. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  147. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +1 -1
  148. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  149. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  150. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  151. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  152. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  153. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  154. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  155. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  156. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  157. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  158. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
  159. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  160. package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +1 -1
  161. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  162. package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
  163. package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
  164. package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
  165. package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
  166. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  167. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  168. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  169. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  170. package/dist/types/compute-engine/latex-syntax/types.d.ts +40 -1
  171. package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
  172. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  173. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  174. package/dist/types/compute-engine/library/collections.d.ts +5 -3
  175. package/dist/types/compute-engine/library/colors.d.ts +1 -1
  176. package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
  177. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  178. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  179. package/dist/types/compute-engine/library/core.d.ts +1 -1
  180. package/dist/types/compute-engine/library/fractals.d.ts +1 -1
  181. package/dist/types/compute-engine/library/library.d.ts +1 -1
  182. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  183. package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
  184. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  185. package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
  186. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  187. package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
  188. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  189. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  190. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  191. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  192. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  193. package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
  194. package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
  195. package/dist/types/compute-engine/library/units.d.ts +1 -1
  196. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  197. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
  198. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
  199. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
  200. package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
  201. package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
  202. package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
  203. package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
  204. package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
  205. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
  206. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  207. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  208. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  209. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  210. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  211. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  212. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  213. package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
  214. package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
  215. package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
  216. package/dist/types/compute-engine/numerics/types.d.ts +1 -1
  217. package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
  218. package/dist/types/compute-engine/oeis.d.ts +1 -1
  219. package/dist/types/compute-engine/sequence.d.ts +1 -1
  220. package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
  221. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  222. package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
  223. package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
  224. package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
  225. package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
  226. package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
  227. package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
  228. package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
  229. package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
  230. package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
  231. package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
  232. package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
  233. package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
  234. package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
  235. package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
  236. package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
  237. package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
  238. package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
  239. package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
  240. package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
  241. package/dist/types/compute-engine/types-definitions.d.ts +1 -1
  242. package/dist/types/compute-engine/types-engine.d.ts +18 -1
  243. package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
  244. package/dist/types/compute-engine/types-expression.d.ts +1 -1
  245. package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
  246. package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -1
  247. package/dist/types/compute-engine/types-serialization.d.ts +1 -1
  248. package/dist/types/compute-engine/types.d.ts +1 -1
  249. package/dist/types/compute-engine.d.ts +1 -1
  250. package/dist/types/core.d.ts +1 -1
  251. package/dist/types/interval.d.ts +1 -1
  252. package/dist/types/latex-syntax.d.ts +2 -2
  253. package/dist/types/math-json/symbols.d.ts +1 -1
  254. package/dist/types/math-json/types.d.ts +1 -1
  255. package/dist/types/math-json/utils.d.ts +1 -1
  256. package/dist/types/math-json.d.ts +2 -2
  257. package/dist/types/numerics.d.ts +1 -1
  258. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- /** Compile 0.56.0 */
1
+ /** Compile 0.57.0 */
2
2
  (function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Compile = {}));})(this, (function (exports) { 'use strict';
3
3
  var Compile = (() => {
4
4
  var __defProp = Object.defineProperty;
@@ -5211,6 +5211,64 @@ var Compile = (() => {
5211
5211
  }
5212
5212
 
5213
5213
  // src/compute-engine/latex-syntax/dictionary/definitions-core.ts
5214
+ var COMPONENT_ACCESS_HEADS = {
5215
+ x: "First",
5216
+ y: "Second",
5217
+ z: "Third",
5218
+ real: "Real",
5219
+ re: "Real",
5220
+ imag: "Imaginary",
5221
+ im: "Imaginary",
5222
+ count: "Length",
5223
+ total: "Sum",
5224
+ max: "Max",
5225
+ min: "Min"
5226
+ };
5227
+ function memberHead(name) {
5228
+ return COMPONENT_ACCESS_HEADS[name] ?? null;
5229
+ }
5230
+ function parseComponentAccess(parser, lhs) {
5231
+ parser.skipVisualSpace();
5232
+ if (parser.match("\\operatorname")) {
5233
+ const name = parser.parseStringGroup();
5234
+ if (name === null) return null;
5235
+ const head = memberHead(name.trim());
5236
+ if (head === null) return null;
5237
+ return [head, lhs];
5238
+ }
5239
+ const tok = parser.peek;
5240
+ if (typeof tok === "string" && tok.startsWith("\\")) {
5241
+ const bare = tok.slice(1);
5242
+ const head = memberHead(bare);
5243
+ if (head !== null) {
5244
+ parser.nextToken();
5245
+ return [head, lhs];
5246
+ }
5247
+ return null;
5248
+ }
5249
+ if (typeof tok === "string" && /^[a-zA-Z]$/.test(tok)) {
5250
+ const head = memberHead(tok);
5251
+ if (head === null) return null;
5252
+ parser.nextToken();
5253
+ return [head, lhs];
5254
+ }
5255
+ return null;
5256
+ }
5257
+ function parseWhenRestriction(parser, lhs, close) {
5258
+ parser.addBoundary(close);
5259
+ parser.skipVisualSpace();
5260
+ const cond = parser.parseExpression({ minPrec: 0 });
5261
+ if (cond === null) {
5262
+ parser.removeBoundary();
5263
+ return null;
5264
+ }
5265
+ parser.skipVisualSpace();
5266
+ if (!parser.matchBoundary()) {
5267
+ parser.removeBoundary();
5268
+ return null;
5269
+ }
5270
+ return ["When", lhs, cond];
5271
+ }
5214
5272
  function parseSequence(parser, terminator, lhs, prec, sep) {
5215
5273
  if (terminator && terminator.minPrec >= prec) return null;
5216
5274
  const result = lhs ? [lhs] : ["Nothing"];
@@ -5682,6 +5740,15 @@ var Compile = (() => {
5682
5740
  }
5683
5741
  },
5684
5742
  { name: "LatexTokens", serialize: serializeLatexTokens },
5743
+ // Component-access postfix: expr.member (C3)
5744
+ // The '.' trigger is consumed before the parse function is called.
5745
+ // Precedence 850 > 810 (At/indexing) so .x chains tightly.
5746
+ {
5747
+ kind: "postfix",
5748
+ precedence: 850,
5749
+ latexTrigger: ["."],
5750
+ parse: parseComponentAccess
5751
+ },
5685
5752
  {
5686
5753
  name: "At",
5687
5754
  kind: "postfix",
@@ -5702,6 +5769,29 @@ var Compile = (() => {
5702
5769
  latexTrigger: ["\\left", "\\lbrack"],
5703
5770
  parse: parseAt("\\right", "\\rbrack")
5704
5771
  },
5772
+ // When-restriction: `expr\left\{cond\right\}` → `When(expr, cond)` (D3)
5773
+ {
5774
+ name: "When",
5775
+ kind: "postfix",
5776
+ precedence: 800,
5777
+ latexTrigger: ["\\left", "\\{"],
5778
+ parse: (parser, lhs) => parseWhenRestriction(parser, lhs, ["\\right", "\\}"]),
5779
+ serialize: (serializer, expr) => {
5780
+ const e = operand(expr, 1);
5781
+ const cond = operand(expr, 2);
5782
+ if (!e || !cond) return "";
5783
+ const clauses = operator(cond) === "And" ? operands(cond) ?? [] : [cond];
5784
+ const inner = clauses.map((c) => `\\left\\{${serializer.serialize(c)}\\right\\}`).join("");
5785
+ return `${serializer.serialize(e)}${inner}`;
5786
+ }
5787
+ },
5788
+ // When-restriction: bare `expr\{cond\}` → `When(expr, cond)`
5789
+ {
5790
+ kind: "postfix",
5791
+ precedence: 800,
5792
+ latexTrigger: ["\\{"],
5793
+ parse: (parser, lhs) => parseWhenRestriction(parser, lhs, ["\\}"])
5794
+ },
5705
5795
  {
5706
5796
  kind: "postfix",
5707
5797
  latexTrigger: ["_"],
@@ -5784,6 +5874,29 @@ var Compile = (() => {
5784
5874
  return "";
5785
5875
  }
5786
5876
  },
5877
+ // Additional triggers for Range: `...`, `\ldots`, and `\dots` are
5878
+ // equivalent to `..` when used as infix operators (e.g. `[1...9]`).
5879
+ // No `name` field here — names must be unique per the dictionary rules;
5880
+ // the first Range entry owns the name. When there is no LHS the symbol
5881
+ // entries near the top of the file still fire (ContinuationPlaceholder).
5882
+ {
5883
+ latexTrigger: [".", ".", "."],
5884
+ kind: "infix",
5885
+ precedence: 800,
5886
+ parse: parseRange
5887
+ },
5888
+ {
5889
+ latexTrigger: ["\\ldots"],
5890
+ kind: "infix",
5891
+ precedence: 800,
5892
+ parse: parseRange
5893
+ },
5894
+ {
5895
+ latexTrigger: ["\\dots"],
5896
+ kind: "infix",
5897
+ precedence: 800,
5898
+ parse: parseRange
5899
+ },
5787
5900
  {
5788
5901
  latexTrigger: [";"],
5789
5902
  kind: "infix",
@@ -5968,13 +6081,24 @@ var Compile = (() => {
5968
6081
  const args = operands(expr);
5969
6082
  if (!args || args.length < 2) return "";
5970
6083
  const body = args[0];
5971
- const indexing = args[1];
5972
- if (operator(indexing) === "Element") {
5973
- const index = operand(indexing, 1);
5974
- const range2 = operand(indexing, 2);
5975
- if (operator(range2) === "Range") {
5976
- const lo = operand(range2, 1);
5977
- const hi = operand(range2, 2);
6084
+ const elements = args.slice(1);
6085
+ const allElements = elements.every((e) => operator(e) === "Element");
6086
+ if (!allElements) {
6087
+ return joinLatex([
6088
+ "\\operatorname{Loop}(",
6089
+ serializer.serialize(body),
6090
+ ", ",
6091
+ serializer.serialize(elements[0]),
6092
+ ")"
6093
+ ]);
6094
+ }
6095
+ if (elements.length === 1) {
6096
+ const elem = elements[0];
6097
+ const index = operand(elem, 1);
6098
+ const coll = operand(elem, 2);
6099
+ if (operator(coll) === "Range") {
6100
+ const lo = operand(coll, 1);
6101
+ const hi = operand(coll, 2);
5978
6102
  return joinLatex([
5979
6103
  "\\text{for }",
5980
6104
  serializer.serialize(index),
@@ -5986,13 +6110,27 @@ var Compile = (() => {
5986
6110
  serializer.serialize(body)
5987
6111
  ]);
5988
6112
  }
6113
+ return joinLatex([
6114
+ serializer.serialize(body),
6115
+ " \\operatorname{for} ",
6116
+ serializer.serialize(index),
6117
+ " = ",
6118
+ serializer.serialize(coll)
6119
+ ]);
5989
6120
  }
6121
+ const bindings = elements.map((elem) => {
6122
+ const name = operand(elem, 1);
6123
+ const coll = operand(elem, 2);
6124
+ return joinLatex([
6125
+ serializer.serialize(name),
6126
+ " = ",
6127
+ serializer.serialize(coll)
6128
+ ]);
6129
+ }).join(", ");
5990
6130
  return joinLatex([
5991
- "\\operatorname{Loop}(",
5992
6131
  serializer.serialize(body),
5993
- ", ",
5994
- serializer.serialize(indexing),
5995
- ")"
6132
+ " \\operatorname{for} ",
6133
+ bindings
5996
6134
  ]);
5997
6135
  }
5998
6136
  },
@@ -6025,6 +6163,18 @@ var Compile = (() => {
6025
6163
  precedence: 245,
6026
6164
  parse: (parser, until) => parseForExpression(parser, until)
6027
6165
  },
6166
+ // \operatorname{for} as postfix infix (list comprehension):
6167
+ // `body \operatorname{for} x = L_1, y = L_2`
6168
+ // Precedence 19 — just below comma (20) so the body is allowed to use
6169
+ // any operator (including comma sequencing) up to the keyword, and the
6170
+ // bindings can be comma-separated below us.
6171
+ {
6172
+ symbolTrigger: "for",
6173
+ kind: "infix",
6174
+ associativity: "none",
6175
+ precedence: 19,
6176
+ parse: (parser, lhs, until) => parseForComprehension(parser, lhs, until)
6177
+ },
6028
6178
  // \operatorname{break}
6029
6179
  {
6030
6180
  symbolTrigger: "break",
@@ -6229,7 +6379,10 @@ var Compile = (() => {
6229
6379
  if (!sym2 || !parser.getSymbolType(sym2).matches("function")) return null;
6230
6380
  parser.addBoundary([")"]);
6231
6381
  const expr = parser.parseExpression(until);
6232
- if (!parser.matchBoundary()) return null;
6382
+ if (!parser.matchBoundary()) {
6383
+ parser.removeBoundary();
6384
+ return null;
6385
+ }
6233
6386
  if (!parser.match("<}>")) return null;
6234
6387
  return ["Derivative", lhs, expr];
6235
6388
  }
@@ -6670,7 +6823,12 @@ var Compile = (() => {
6670
6823
  if (isEmptySequence(body)) return ["List"];
6671
6824
  const h = operator(body);
6672
6825
  if (h === "Range" || h === "Linspace") return body;
6673
- if (h === "Sequence") return ["List", ...operands(body)];
6826
+ if (h === "Sequence") {
6827
+ const elems = operands(body);
6828
+ const inferred = tryInferRangeFromElements(elems, parser);
6829
+ if (inferred) return inferred;
6830
+ return ["List", ...elems];
6831
+ }
6674
6832
  if (h === "Delimiter") {
6675
6833
  const delim = stringValue(operand(body, 2)) ?? "...";
6676
6834
  if (delim === ";" || delim === ".;.") {
@@ -6683,12 +6841,37 @@ var Compile = (() => {
6683
6841
  }
6684
6842
  if (delim === "," || delim === ".,.") {
6685
6843
  body = operand(body, 1);
6686
- if (operator(body) === "Sequence") return ["List", ...operands(body)];
6844
+ if (operator(body) === "Sequence") {
6845
+ const elems = operands(body);
6846
+ const inferred = tryInferRangeFromElements(elems, parser);
6847
+ if (inferred) return inferred;
6848
+ return ["List", ...elems];
6849
+ }
6687
6850
  return ["List", body ?? "Nothing"];
6688
6851
  }
6689
6852
  }
6690
6853
  return ["List", body];
6691
6854
  }
6855
+ function tryInferRangeFromElements(elems, parser) {
6856
+ if (elems.length < 4) return null;
6857
+ const penultimate = elems[elems.length - 2];
6858
+ if (symbol(penultimate) !== "ContinuationPlaceholder") return null;
6859
+ const samples = elems.slice(0, -2);
6860
+ const endExpr = elems[elems.length - 1];
6861
+ if (samples.length < 2) return null;
6862
+ const sampleNums = samples.map(machineValue);
6863
+ if (sampleNums.some((n) => n === null)) return null;
6864
+ const nums = sampleNums;
6865
+ const step = nums[nums.length - 1] - nums[nums.length - 2];
6866
+ const tol = parser.options.tolerance;
6867
+ if (Math.abs(step) < tol)
6868
+ return parser.error("degenerate-range-step", parser.index);
6869
+ for (let i = 1; i < nums.length; i++) {
6870
+ if (Math.abs(nums[i] - nums[i - 1] - step) > tol)
6871
+ return parser.error("inconsistent-range-samples", parser.index);
6872
+ }
6873
+ return ["Range", nums[0], endExpr, step];
6874
+ }
6692
6875
  function serializeList(serializer, expr) {
6693
6876
  if (nops(expr) > 1 && operands(expr).every((x) => {
6694
6877
  const op = operator(x);
@@ -6940,6 +7123,35 @@ var Compile = (() => {
6940
7123
  ["Element", index, ["Range", lower, upper]]
6941
7124
  ];
6942
7125
  }
7126
+ function parseForComprehension(parser, lhs, until) {
7127
+ const bindingTerminator = {
7128
+ minPrec: 21,
7129
+ // Above comma (20) and ; (19), so `x = L_1` is captured whole
7130
+ condition: (p) => {
7131
+ if (until?.condition?.(p)) return true;
7132
+ const saved = p.index;
7133
+ p.skipVisualSpace();
7134
+ const isComma = p.peek === ",";
7135
+ p.index = saved;
7136
+ return isComma;
7137
+ }
7138
+ };
7139
+ const elements = [];
7140
+ do {
7141
+ parser.skipVisualSpace();
7142
+ const binding = parser.parseExpression(bindingTerminator);
7143
+ if (binding === null) break;
7144
+ const op = operator(binding);
7145
+ if (op !== "Equal" && op !== "Assign") return null;
7146
+ const name = operand(binding, 1);
7147
+ const list = operand(binding, 2);
7148
+ if (!name || !list) return null;
7149
+ elements.push(["Element", name, list]);
7150
+ parser.skipVisualSpace();
7151
+ } while (parser.match(","));
7152
+ if (elements.length === 0) return null;
7153
+ return ["Loop", lhs, ...elements];
7154
+ }
6943
7155
  function parseWhereExpression(parser, lhs, until) {
6944
7156
  const bindingTerminator = {
6945
7157
  minPrec: 21,
@@ -12836,7 +13048,11 @@ ${lines.join("\n")}`;
12836
13048
  //
12837
13049
  Range: {
12838
13050
  complexity: 8200,
12839
- signature: "(number, number?, step: number?) -> indexed_collection<integer>",
13051
+ signature: "(number, number?, step: number?) -> indexed_collection<number>",
13052
+ type: (ops) => {
13053
+ const allInt = ops.every((op) => op.isInteger);
13054
+ return allInt ? parseType("indexed_collection<integer>") : parseType("indexed_collection<number>");
13055
+ },
12840
13056
  canonical: (ops, { engine: ce }) => {
12841
13057
  if (ops.length === 0) return null;
12842
13058
  if (ops.length === 1) return ce._fn("Range", [ce.One, ops[0].canonical]);
@@ -12860,19 +13076,26 @@ ${lines.join("\n")}`;
12860
13076
  const [lower, upper, step] = range(expr);
12861
13077
  if (step === 0) return 0;
12862
13078
  if (!isFinite(lower) || !isFinite(upper)) return Infinity;
12863
- return 1 + Math.max(0, Math.floor((upper - lower) / step));
13079
+ return Math.max(0, Math.floor((upper - lower) / step) + 1);
12864
13080
  },
12865
13081
  contains: (expr, target) => {
12866
- if (!target.type.matches("integer")) return false;
12867
13082
  const t = target.re;
13083
+ if (!isFinite(t)) return false;
12868
13084
  const [lower, upper, step] = range(expr);
12869
13085
  if (step === 0) return false;
12870
- if (step > 0) return t >= lower && t <= upper;
12871
- return t <= lower && t >= upper;
13086
+ if (step > 0) {
13087
+ if (t < lower || t > upper) return false;
13088
+ } else {
13089
+ if (t > lower || t < upper) return false;
13090
+ }
13091
+ const k = (t - lower) / step;
13092
+ const tol = expr.engine.tolerance;
13093
+ const kRounded = Math.round(k);
13094
+ return kRounded >= 0 && Math.abs(k - kRounded) < tol;
12872
13095
  },
12873
13096
  iterator: (expr) => {
12874
13097
  const [lower, upper, step] = range(expr);
12875
- const maxCount = step === 0 ? 0 : Math.floor((upper - lower) / step) + 1;
13098
+ const maxCount = step === 0 ? 0 : Math.max(0, Math.floor((upper - lower) / step) + 1);
12876
13099
  let index = 1;
12877
13100
  return {
12878
13101
  next: () => {
@@ -12890,7 +13113,9 @@ ${lines.join("\n")}`;
12890
13113
  at: (expr, index) => {
12891
13114
  if (typeof index !== "number") return void 0;
12892
13115
  const [lower, upper, step] = range(expr);
12893
- if (index < 1 || index > 1 + (upper - lower) / step) return void 0;
13116
+ if (step === 0) return void 0;
13117
+ const maxCount = Math.max(0, Math.floor((upper - lower) / step) + 1);
13118
+ if (index < 1 || index > maxCount) return void 0;
12894
13119
  return expr.engine.number(lower + step * (index - 1));
12895
13120
  },
12896
13121
  indexWhere: void 0,
@@ -12915,7 +13140,13 @@ ${lines.join("\n")}`;
12915
13140
  if (step > 0) return lower <= upper ? "positive" : "negative";
12916
13141
  return lower >= upper ? "positive" : "negative";
12917
13142
  },
12918
- elttype: (_expr) => "finite_integer"
13143
+ elttype: (expr) => {
13144
+ if (!isFunction2(expr)) return "finite_integer";
13145
+ for (let i = 1; i <= expr.nops; i++) {
13146
+ if (!expr[`op${i}`].isInteger) return "finite_real";
13147
+ }
13148
+ return "finite_integer";
13149
+ }
12919
13150
  }
12920
13151
  },
12921
13152
  Interval: {
@@ -13513,15 +13744,45 @@ ${lines.join("\n")}`;
13513
13744
  },
13514
13745
  First: {
13515
13746
  complexity: 8200,
13516
- signature: "(collection) -> any",
13747
+ signature: "(any) -> any",
13517
13748
  type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
13518
- evaluate: ([xs], { engine: ce }) => xs.at(1) ?? ce.Nothing
13749
+ evaluate: ([xs], { engine: ce }) => {
13750
+ if (!xs.isCollection)
13751
+ return ce.error([
13752
+ "incompatible-type",
13753
+ `'collection'`,
13754
+ xs.type.toString()
13755
+ ]);
13756
+ return xs.at(1) ?? ce.Nothing;
13757
+ }
13519
13758
  },
13520
13759
  Second: {
13521
13760
  complexity: 8200,
13522
- signature: "(collection) -> any",
13761
+ signature: "(any) -> any",
13523
13762
  type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
13524
- evaluate: ([xs], { engine: ce }) => xs.at(2) ?? ce.Nothing
13763
+ evaluate: ([xs], { engine: ce }) => {
13764
+ if (!xs.isCollection)
13765
+ return ce.error([
13766
+ "incompatible-type",
13767
+ `'collection'`,
13768
+ xs.type.toString()
13769
+ ]);
13770
+ return xs.at(2) ?? ce.Nothing;
13771
+ }
13772
+ },
13773
+ Third: {
13774
+ complexity: 8200,
13775
+ signature: "(any) -> any",
13776
+ type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
13777
+ evaluate: ([xs], { engine: ce }) => {
13778
+ if (!xs.isCollection)
13779
+ return ce.error([
13780
+ "incompatible-type",
13781
+ `'collection'`,
13782
+ xs.type.toString()
13783
+ ]);
13784
+ return xs.at(3) ?? ce.Nothing;
13785
+ }
13525
13786
  },
13526
13787
  Last: {
13527
13788
  complexity: 8200,
@@ -14500,17 +14761,14 @@ ${lines.join("\n")}`;
14500
14761
  if (!isFunction2(expr)) return [1, 0, 0];
14501
14762
  if (expr.nops === 0) return [1, 0, 0];
14502
14763
  let op1 = expr.op1.re;
14503
- if (!isFinite(op1)) op1 = 1;
14504
- else op1 = Math.round(op1);
14764
+ if (!isFinite(op1) && !op1) op1 = 1;
14505
14765
  if (expr.nops === 1) return [1, op1, 1];
14506
14766
  let op2 = expr.op2.re;
14507
14767
  if (!isFinite(op2) && !op2) op2 = 1;
14508
- else if (isFinite(op2)) op2 = Math.round(op2);
14509
- if (expr.nops === 2) return [op1, op2, op2 > op1 ? 1 : -1];
14768
+ if (expr.nops === 2) return [op1, op2, op2 >= op1 ? 1 : -1];
14510
14769
  let op3 = expr.op3.re;
14511
- if (!isFinite(op3)) op3 = 1;
14512
- else op3 = Math.abs(Math.round(op3));
14513
- return [op1, op2, op1 < op2 ? op3 : -op3];
14770
+ if (!isFinite(op3) && !op3) op3 = 1;
14771
+ return [op1, op2, op3];
14514
14772
  }
14515
14773
  function canonicalList(ops, { engine: ce }) {
14516
14774
  const op1 = ops[0];
@@ -14859,6 +15117,23 @@ ${lines.join("\n")}`;
14859
15117
  };
14860
15118
  return compilePair(0);
14861
15119
  }
15120
+ if (h === "When") {
15121
+ if (args.length !== 2)
15122
+ throw new Error("When: expected exactly 2 arguments (expr, cond)");
15123
+ const fn2 = target.functions?.(h);
15124
+ if (fn2) {
15125
+ if (typeof fn2 === "function") {
15126
+ return fn2(args, (expr) => _BaseCompiler.compile(expr, target), target);
15127
+ }
15128
+ return `${fn2}(${args.map((x) => _BaseCompiler.compile(x, target)).join(", ")})`;
15129
+ }
15130
+ if (isSymbol2(args[1], "True"))
15131
+ return `(${_BaseCompiler.compile(args[0], target)})`;
15132
+ if (isSymbol2(args[1], "False")) return "NaN";
15133
+ const val = _BaseCompiler.compile(args[0], target);
15134
+ const cond = _BaseCompiler.compile(args[1], target);
15135
+ return `((${cond}) ? (${val}) : NaN)`;
15136
+ }
14862
15137
  if (h === "Block") {
14863
15138
  return _BaseCompiler.compileBlock(args, target);
14864
15139
  }
@@ -14933,17 +15208,91 @@ ${lines.join("\n")}`;
14933
15208
  )}${target.ws("\n")}})()`;
14934
15209
  }
14935
15210
  /**
14936
- * Compile a Loop expression with Element(index, Range(lo, hi)) indexing.
14937
- * Generates: (() => { for (let i = lo; i <= hi; i++) { body } })()
15211
+ * Compile a Loop expression.
15212
+ *
15213
+ * Two forms are supported:
15214
+ *
15215
+ * 1. **Imperative / single-Element form** (existing behaviour):
15216
+ * `Loop(body, Element(i, Range(lo, hi)))`
15217
+ * Generates a raw `for (let i = lo; i <= hi; i++) { body }` loop wrapped
15218
+ * in an IIFE. The loop counter is always a plain number. For targets
15219
+ * that wrap numeric values (e.g. interval-js uses `_IA.point()`),
15220
+ * references to the loop index inside the body are re-wrapped via
15221
+ * `target.number`. `break` / `continue` / `return` are preserved.
15222
+ *
15223
+ * 2. **Comprehension / variadic-Element form** (new):
15224
+ * `Loop(body, Element(x, coll1), Element(y, coll2), …)`
15225
+ * When two or more `Element` clauses are present — or when the single
15226
+ * Element's collection is not a `Range` — the loop is compiled as a
15227
+ * comprehension that collects results into an array. Each clause
15228
+ * produces a `for (const name of collection)` loop, nested
15229
+ * outermost-to-innermost, and the innermost body pushes into `result`.
15230
+ *
15231
+ * Example output (JS):
15232
+ * ```js
15233
+ * (() => { const result = [];
15234
+ * for (const x of [1,2]) { for (const y of [3,4]) { result.push(body); } }
15235
+ * return result; })()
15236
+ * ```
14938
15237
  *
14939
- * The loop counter is always a raw number. For targets that wrap numeric
14940
- * values (e.g. interval-js wraps with `_IA.point()`), references to the
14941
- * loop index inside the body are wrapped via `target.number`.
15238
+ * GLSL: multi-Element comprehension is not trivially representable in
15239
+ * GLSL (no dynamic arrays, no push). A compile-time error is thrown.
15240
+ * TODO(E3-GLSL): support GLSL multi-Element via a pre-declared fixed-size
15241
+ * array or by unrolling when bounds are known at compile time.
14942
15242
  */
14943
15243
  static compileForLoop(args, target) {
14944
15244
  if (!args[0]) throw new Error("Loop: no body");
14945
15245
  if (!args[1]) throw new Error("Loop: no indexing set");
14946
- const indexing = args[1];
15246
+ const body = args[0];
15247
+ const elements = args.slice(1);
15248
+ const useComprehension = elements.length > 1 || elements.length === 1 && isFunction2(elements[0], "Element") && !_BaseCompiler.isLegacyCompatibleRange(elements[0].ops[1]);
15249
+ if (useComprehension) {
15250
+ const lang = target.language ?? "";
15251
+ if (lang === "glsl" || lang === "wgsl") {
15252
+ throw new Error(
15253
+ `${lang.toUpperCase()}: multi-Element Loop comprehension is not yet supported. TODO(E3-GLSL): unroll or use a fixed-size array.`
15254
+ );
15255
+ }
15256
+ const narrowedElements = [];
15257
+ for (let i = 0; i < elements.length; i++) {
15258
+ const elem = elements[i];
15259
+ if (!isFunction2(elem, "Element"))
15260
+ throw new Error(
15261
+ `Loop: argument ${i + 1} must be an Element clause, got ${elem.operator ?? "?"}`
15262
+ );
15263
+ if (!isSymbol2(elem.ops[0]))
15264
+ throw new Error(
15265
+ `Loop: Element index (argument ${i + 1}) must be a symbol`
15266
+ );
15267
+ narrowedElements.push(elem);
15268
+ }
15269
+ const loopVarSet = new Set(
15270
+ narrowedElements.map(
15271
+ (e) => e.ops[0].symbol
15272
+ )
15273
+ );
15274
+ const needsWrap2 = target.number(0) !== "0";
15275
+ const bodyTarget2 = needsWrap2 ? {
15276
+ ...target,
15277
+ var: (id) => loopVarSet.has(id) ? target.number(0).replace("0", id) : target.var(id)
15278
+ } : target;
15279
+ const bodyCode = _BaseCompiler.compile(body, bodyTarget2);
15280
+ let inner = `result.push(${bodyCode});`;
15281
+ for (let i = narrowedElements.length - 1; i >= 0; i--) {
15282
+ const elem = narrowedElements[i];
15283
+ const name = elem.ops[0].symbol;
15284
+ const collExpr = elem.ops[1];
15285
+ let collection;
15286
+ if (isFunction2(collExpr, "Range")) {
15287
+ collection = _BaseCompiler.compileRangeIterable(collExpr, bodyTarget2);
15288
+ } else {
15289
+ collection = _BaseCompiler.compile(collExpr, bodyTarget2);
15290
+ }
15291
+ inner = `for (const ${name} of ${collection}) { ${inner} }`;
15292
+ }
15293
+ return `(() => { const result = []; ${inner} return result; })()`;
15294
+ }
15295
+ const indexing = elements[0];
14947
15296
  if (!isFunction2(indexing, "Element"))
14948
15297
  throw new Error("Loop: expected Element(index, Range(lo, hi))");
14949
15298
  const indexExpr = indexing.ops[0];
@@ -14961,13 +15310,72 @@ ${lines.join("\n")}`;
14961
15310
  ...target,
14962
15311
  var: (id) => id === index ? needsWrap ? target.number(0).replace("0", index) : index : target.var(id)
14963
15312
  };
14964
- const bodyStmts = _BaseCompiler.compileLoopBody(args[0], bodyTarget);
15313
+ const bodyStmts = _BaseCompiler.compileLoopBody(body, bodyTarget);
14965
15314
  return `(() => {${target.ws(
14966
15315
  "\n"
14967
15316
  )}for (let ${index} = ${lower}; ${index} <= ${upper}; ${index}++) {${target.ws(
14968
15317
  "\n"
14969
15318
  )}${bodyStmts}${target.ws("\n")}}${target.ws("\n")}})()`;
14970
15319
  }
15320
+ /**
15321
+ * Returns `true` when the given collection expression is a `Range` whose
15322
+ * runtime semantics match the legacy imperative for-loop shape
15323
+ * `for (let i = lo; i <= hi; i++)`.
15324
+ *
15325
+ * Concretely: integer-ascending bounds and step omitted-or-1. When bounds
15326
+ * are not statically numeric we accept the Range (the historical
15327
+ * behaviour) — runtime mismatch in the descending-unknown-bounds case is
15328
+ * left as a known limitation; callers can force the iterable path by
15329
+ * supplying an explicit step.
15330
+ */
15331
+ static isLegacyCompatibleRange(coll) {
15332
+ if (!isFunction2(coll, "Range")) return false;
15333
+ if (coll.ops.length >= 3) {
15334
+ const stepExpr = coll.ops[2];
15335
+ if (!isNumber(stepExpr) || stepExpr.re !== 1) return false;
15336
+ }
15337
+ const lo = coll.ops[0];
15338
+ const hi = coll.ops[1];
15339
+ if (isNumber(lo) && !Number.isInteger(lo.re)) return false;
15340
+ if (isNumber(hi) && !Number.isInteger(hi.re)) return false;
15341
+ if (isNumber(lo) && isNumber(hi) && lo.re > hi.re) return false;
15342
+ return true;
15343
+ }
15344
+ /**
15345
+ * Compile a `Range(lo, hi)` or `Range(lo, hi, step)` expression into a JS
15346
+ * iterable expression. Mirrors the runtime semantics in
15347
+ * `library/collections.ts` Range:
15348
+ * count = step === 0 ? 0 : max(0, floor((hi - lo) / step) + 1)
15349
+ * element = lo + step * k (0-indexed)
15350
+ * Default step is 1 when omitted. Bounds and step may be fractional.
15351
+ *
15352
+ * Only used from the comprehension path in `compileForLoop`.
15353
+ * Caller must have already verified `isFunction(rangeExpr, 'Range')`.
15354
+ */
15355
+ static compileRangeIterable(rangeExpr, target) {
15356
+ const loExpr = rangeExpr.ops[0];
15357
+ const hiExpr = rangeExpr.ops[1];
15358
+ const stepExpr = rangeExpr.ops[2];
15359
+ if (isNumber(loExpr) && isNumber(hiExpr) && (stepExpr === void 0 || isNumber(stepExpr))) {
15360
+ const lo2 = loExpr.re;
15361
+ const hi2 = hiExpr.re;
15362
+ const step2 = stepExpr === void 0 ? hi2 >= lo2 ? 1 : -1 : stepExpr.re;
15363
+ if (step2 === 0) return "[]";
15364
+ const len = Math.max(0, Math.floor((hi2 - lo2) / step2) + 1);
15365
+ if (step2 === 1) {
15366
+ if (lo2 === 0) return `Array.from({length:${len}},(_,k)=>k)`;
15367
+ return `Array.from({length:${len}},(_,k)=>${lo2}+k)`;
15368
+ }
15369
+ return `Array.from({length:${len}},(_,k)=>${lo2}+(${step2})*k)`;
15370
+ }
15371
+ const lo = _BaseCompiler.compile(loExpr, target);
15372
+ const hi = _BaseCompiler.compile(hiExpr, target);
15373
+ if (stepExpr === void 0) {
15374
+ return `((_lo,_hi)=>{const _st=_hi>=_lo?1:-1;return Array.from({length:Math.max(0,Math.floor((_hi-_lo)/_st)+1)},(_,k)=>_lo+_st*k);})(${lo},${hi})`;
15375
+ }
15376
+ const step = _BaseCompiler.compile(stepExpr, target);
15377
+ return `((_lo,_hi,_st)=>_st===0?[]:Array.from({length:Math.max(0,Math.floor((_hi-_lo)/_st)+1)},(_,k)=>_lo+_st*k))(${lo},${hi},${step})`;
15378
+ }
14971
15379
  /**
14972
15380
  * Compile a loop body expression as statements (not wrapped in IIFE).
14973
15381
  * Handles Break, Continue, Return as statements, and If as if-else when
@@ -25534,7 +25942,7 @@ ${code}`;
25534
25942
  }
25535
25943
 
25536
25944
  // src/compile.ts
25537
- var version = "0.56.0";
25945
+ var version = "0.57.0";
25538
25946
  return __toCommonJS(compile_exports);
25539
25947
  })();
25540
25948
  /*! Bundled license information: