@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.
- package/dist/compile.esm.js +450 -42
- package/dist/compile.min.esm.js +57 -57
- package/dist/compile.min.umd.cjs +58 -58
- package/dist/compile.umd.cjs +450 -42
- package/dist/compute-engine.esm.js +677 -49
- package/dist/compute-engine.min.esm.js +62 -62
- package/dist/compute-engine.min.umd.cjs +62 -62
- package/dist/compute-engine.umd.cjs +677 -49
- package/dist/core.esm.js +676 -48
- package/dist/core.min.esm.js +61 -61
- package/dist/core.min.umd.cjs +61 -61
- package/dist/core.umd.cjs +676 -48
- package/dist/interval.esm.js +228 -16
- package/dist/interval.min.esm.js +6 -6
- package/dist/interval.min.umd.cjs +6 -6
- package/dist/interval.umd.cjs +228 -16
- package/dist/latex-syntax.esm.js +269 -16
- package/dist/latex-syntax.min.esm.js +6 -6
- package/dist/latex-syntax.min.umd.cjs +6 -6
- package/dist/latex-syntax.umd.cjs +269 -16
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/math-json.min.umd.cjs +2 -2
- package/dist/math-json.umd.cjs +2 -2
- package/dist/numerics.esm.js +2 -2
- package/dist/numerics.min.esm.js +2 -2
- package/dist/numerics.min.umd.cjs +2 -2
- package/dist/numerics.umd.cjs +2 -2
- package/dist/types/big-decimal/big-decimal.d.ts +1 -1
- package/dist/types/big-decimal/index.d.ts +1 -1
- package/dist/types/big-decimal/transcendentals.d.ts +1 -1
- package/dist/types/big-decimal/utils.d.ts +1 -1
- package/dist/types/common/ansi-codes.d.ts +1 -1
- package/dist/types/common/configuration-change.d.ts +1 -1
- package/dist/types/common/fuzzy-string-match.d.ts +1 -1
- package/dist/types/common/grapheme-splitter.d.ts +1 -1
- package/dist/types/common/interruptible.d.ts +1 -1
- package/dist/types/common/one-of.d.ts +1 -1
- package/dist/types/common/signals.d.ts +1 -1
- package/dist/types/common/type/ast-nodes.d.ts +1 -1
- package/dist/types/common/type/boxed-type.d.ts +1 -1
- package/dist/types/common/type/lexer.d.ts +1 -1
- package/dist/types/common/type/parse.d.ts +1 -1
- package/dist/types/common/type/parser.d.ts +1 -1
- package/dist/types/common/type/primitive.d.ts +1 -1
- package/dist/types/common/type/reduce.d.ts +1 -1
- package/dist/types/common/type/serialize.d.ts +1 -1
- package/dist/types/common/type/subtype.d.ts +1 -1
- package/dist/types/common/type/type-builder.d.ts +1 -1
- package/dist/types/common/type/types.d.ts +1 -1
- package/dist/types/common/type/utils.d.ts +1 -1
- package/dist/types/common/utils.d.ts +1 -1
- package/dist/types/compile.d.ts +1 -1
- package/dist/types/compute-engine/assume.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +6 -1
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
- package/dist/types/compute-engine/collection-utils.d.ts +1 -1
- package/dist/types/compute-engine/compilation/base-compiler.d.ts +55 -6
- package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
- package/dist/types/compute-engine/compilation/constant-folding.d.ts +1 -1
- package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/gpu-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/types.d.ts +1 -1
- package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
- package/dist/types/compute-engine/cost-function.d.ts +1 -1
- package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
- package/dist/types/compute-engine/engine-cache.d.ts +1 -1
- package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
- package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
- package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
- package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
- package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
- package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
- package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
- package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
- package/dist/types/compute-engine/engine-scope.d.ts +1 -1
- package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
- package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
- package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
- package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
- package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/free-functions.d.ts +1 -1
- package/dist/types/compute-engine/function-utils.d.ts +1 -1
- package/dist/types/compute-engine/global-types.d.ts +1 -1
- package/dist/types/compute-engine/index.d.ts +3 -2
- package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
- package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
- package/dist/types/compute-engine/interval/index.d.ts +1 -1
- package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
- package/dist/types/compute-engine/interval/types.d.ts +1 -1
- package/dist/types/compute-engine/interval/util.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/types.d.ts +40 -1
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
- package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/calculus.d.ts +1 -1
- package/dist/types/compute-engine/library/collections.d.ts +5 -3
- package/dist/types/compute-engine/library/colors.d.ts +1 -1
- package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
- package/dist/types/compute-engine/library/complex.d.ts +1 -1
- package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
- package/dist/types/compute-engine/library/core.d.ts +1 -1
- package/dist/types/compute-engine/library/fractals.d.ts +1 -1
- package/dist/types/compute-engine/library/library.d.ts +1 -1
- package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
- package/dist/types/compute-engine/library/logic.d.ts +1 -1
- package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
- package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
- package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
- package/dist/types/compute-engine/library/sets.d.ts +1 -1
- package/dist/types/compute-engine/library/statistics.d.ts +1 -1
- package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
- package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/library/units.d.ts +1 -1
- package/dist/types/compute-engine/library/utils.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
- package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
- package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/oeis.d.ts +1 -1
- package/dist/types/compute-engine/sequence.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
- package/dist/types/compute-engine/types-definitions.d.ts +1 -1
- package/dist/types/compute-engine/types-engine.d.ts +18 -1
- package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-expression.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types.d.ts +1 -1
- package/dist/types/compute-engine.d.ts +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/interval.d.ts +1 -1
- package/dist/types/latex-syntax.d.ts +2 -2
- package/dist/types/math-json/symbols.d.ts +1 -1
- package/dist/types/math-json/types.d.ts +1 -1
- package/dist/types/math-json/utils.d.ts +1 -1
- package/dist/types/math-json.d.ts +2 -2
- package/dist/types/numerics.d.ts +1 -1
- package/package.json +1 -1
package/dist/compile.umd.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compile 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
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
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
|
-
|
|
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())
|
|
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")
|
|
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")
|
|
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<
|
|
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
|
|
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)
|
|
12871
|
-
|
|
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 (
|
|
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: (
|
|
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: "(
|
|
13747
|
+
signature: "(any) -> any",
|
|
13517
13748
|
type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
|
|
13518
|
-
evaluate: ([xs], { engine: ce }) =>
|
|
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: "(
|
|
13761
|
+
signature: "(any) -> any",
|
|
13523
13762
|
type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
|
|
13524
|
-
evaluate: ([xs], { engine: ce }) =>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
14937
|
-
*
|
|
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
|
-
*
|
|
14940
|
-
*
|
|
14941
|
-
*
|
|
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
|
|
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(
|
|
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.
|
|
25945
|
+
var version = "0.57.0";
|
|
25538
25946
|
return __toCommonJS(compile_exports);
|
|
25539
25947
|
})();
|
|
25540
25948
|
/*! Bundled license information:
|