@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.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compute Engine 0.
|
|
1
|
+
/** Compute Engine 0.57.0 */
|
|
2
2
|
|
|
3
3
|
// src/compute-engine/numerics/richardson.ts
|
|
4
4
|
function extrapolate(f, x0, options = {}) {
|
|
@@ -5178,6 +5178,64 @@ function parseQuantifier(kind) {
|
|
|
5178
5178
|
}
|
|
5179
5179
|
|
|
5180
5180
|
// src/compute-engine/latex-syntax/dictionary/definitions-core.ts
|
|
5181
|
+
var COMPONENT_ACCESS_HEADS = {
|
|
5182
|
+
x: "First",
|
|
5183
|
+
y: "Second",
|
|
5184
|
+
z: "Third",
|
|
5185
|
+
real: "Real",
|
|
5186
|
+
re: "Real",
|
|
5187
|
+
imag: "Imaginary",
|
|
5188
|
+
im: "Imaginary",
|
|
5189
|
+
count: "Length",
|
|
5190
|
+
total: "Sum",
|
|
5191
|
+
max: "Max",
|
|
5192
|
+
min: "Min"
|
|
5193
|
+
};
|
|
5194
|
+
function memberHead(name) {
|
|
5195
|
+
return COMPONENT_ACCESS_HEADS[name] ?? null;
|
|
5196
|
+
}
|
|
5197
|
+
function parseComponentAccess(parser, lhs) {
|
|
5198
|
+
parser.skipVisualSpace();
|
|
5199
|
+
if (parser.match("\\operatorname")) {
|
|
5200
|
+
const name = parser.parseStringGroup();
|
|
5201
|
+
if (name === null) return null;
|
|
5202
|
+
const head = memberHead(name.trim());
|
|
5203
|
+
if (head === null) return null;
|
|
5204
|
+
return [head, lhs];
|
|
5205
|
+
}
|
|
5206
|
+
const tok = parser.peek;
|
|
5207
|
+
if (typeof tok === "string" && tok.startsWith("\\")) {
|
|
5208
|
+
const bare = tok.slice(1);
|
|
5209
|
+
const head = memberHead(bare);
|
|
5210
|
+
if (head !== null) {
|
|
5211
|
+
parser.nextToken();
|
|
5212
|
+
return [head, lhs];
|
|
5213
|
+
}
|
|
5214
|
+
return null;
|
|
5215
|
+
}
|
|
5216
|
+
if (typeof tok === "string" && /^[a-zA-Z]$/.test(tok)) {
|
|
5217
|
+
const head = memberHead(tok);
|
|
5218
|
+
if (head === null) return null;
|
|
5219
|
+
parser.nextToken();
|
|
5220
|
+
return [head, lhs];
|
|
5221
|
+
}
|
|
5222
|
+
return null;
|
|
5223
|
+
}
|
|
5224
|
+
function parseWhenRestriction(parser, lhs, close) {
|
|
5225
|
+
parser.addBoundary(close);
|
|
5226
|
+
parser.skipVisualSpace();
|
|
5227
|
+
const cond = parser.parseExpression({ minPrec: 0 });
|
|
5228
|
+
if (cond === null) {
|
|
5229
|
+
parser.removeBoundary();
|
|
5230
|
+
return null;
|
|
5231
|
+
}
|
|
5232
|
+
parser.skipVisualSpace();
|
|
5233
|
+
if (!parser.matchBoundary()) {
|
|
5234
|
+
parser.removeBoundary();
|
|
5235
|
+
return null;
|
|
5236
|
+
}
|
|
5237
|
+
return ["When", lhs, cond];
|
|
5238
|
+
}
|
|
5181
5239
|
function parseSequence(parser, terminator, lhs, prec, sep) {
|
|
5182
5240
|
if (terminator && terminator.minPrec >= prec) return null;
|
|
5183
5241
|
const result = lhs ? [lhs] : ["Nothing"];
|
|
@@ -5649,6 +5707,15 @@ var DEFINITIONS_CORE = [
|
|
|
5649
5707
|
}
|
|
5650
5708
|
},
|
|
5651
5709
|
{ name: "LatexTokens", serialize: serializeLatexTokens },
|
|
5710
|
+
// Component-access postfix: expr.member (C3)
|
|
5711
|
+
// The '.' trigger is consumed before the parse function is called.
|
|
5712
|
+
// Precedence 850 > 810 (At/indexing) so .x chains tightly.
|
|
5713
|
+
{
|
|
5714
|
+
kind: "postfix",
|
|
5715
|
+
precedence: 850,
|
|
5716
|
+
latexTrigger: ["."],
|
|
5717
|
+
parse: parseComponentAccess
|
|
5718
|
+
},
|
|
5652
5719
|
{
|
|
5653
5720
|
name: "At",
|
|
5654
5721
|
kind: "postfix",
|
|
@@ -5669,6 +5736,29 @@ var DEFINITIONS_CORE = [
|
|
|
5669
5736
|
latexTrigger: ["\\left", "\\lbrack"],
|
|
5670
5737
|
parse: parseAt("\\right", "\\rbrack")
|
|
5671
5738
|
},
|
|
5739
|
+
// When-restriction: `expr\left\{cond\right\}` → `When(expr, cond)` (D3)
|
|
5740
|
+
{
|
|
5741
|
+
name: "When",
|
|
5742
|
+
kind: "postfix",
|
|
5743
|
+
precedence: 800,
|
|
5744
|
+
latexTrigger: ["\\left", "\\{"],
|
|
5745
|
+
parse: (parser, lhs) => parseWhenRestriction(parser, lhs, ["\\right", "\\}"]),
|
|
5746
|
+
serialize: (serializer, expr) => {
|
|
5747
|
+
const e = operand(expr, 1);
|
|
5748
|
+
const cond = operand(expr, 2);
|
|
5749
|
+
if (!e || !cond) return "";
|
|
5750
|
+
const clauses = operator(cond) === "And" ? operands(cond) ?? [] : [cond];
|
|
5751
|
+
const inner = clauses.map((c) => `\\left\\{${serializer.serialize(c)}\\right\\}`).join("");
|
|
5752
|
+
return `${serializer.serialize(e)}${inner}`;
|
|
5753
|
+
}
|
|
5754
|
+
},
|
|
5755
|
+
// When-restriction: bare `expr\{cond\}` → `When(expr, cond)`
|
|
5756
|
+
{
|
|
5757
|
+
kind: "postfix",
|
|
5758
|
+
precedence: 800,
|
|
5759
|
+
latexTrigger: ["\\{"],
|
|
5760
|
+
parse: (parser, lhs) => parseWhenRestriction(parser, lhs, ["\\}"])
|
|
5761
|
+
},
|
|
5672
5762
|
{
|
|
5673
5763
|
kind: "postfix",
|
|
5674
5764
|
latexTrigger: ["_"],
|
|
@@ -5751,6 +5841,29 @@ var DEFINITIONS_CORE = [
|
|
|
5751
5841
|
return "";
|
|
5752
5842
|
}
|
|
5753
5843
|
},
|
|
5844
|
+
// Additional triggers for Range: `...`, `\ldots`, and `\dots` are
|
|
5845
|
+
// equivalent to `..` when used as infix operators (e.g. `[1...9]`).
|
|
5846
|
+
// No `name` field here — names must be unique per the dictionary rules;
|
|
5847
|
+
// the first Range entry owns the name. When there is no LHS the symbol
|
|
5848
|
+
// entries near the top of the file still fire (ContinuationPlaceholder).
|
|
5849
|
+
{
|
|
5850
|
+
latexTrigger: [".", ".", "."],
|
|
5851
|
+
kind: "infix",
|
|
5852
|
+
precedence: 800,
|
|
5853
|
+
parse: parseRange
|
|
5854
|
+
},
|
|
5855
|
+
{
|
|
5856
|
+
latexTrigger: ["\\ldots"],
|
|
5857
|
+
kind: "infix",
|
|
5858
|
+
precedence: 800,
|
|
5859
|
+
parse: parseRange
|
|
5860
|
+
},
|
|
5861
|
+
{
|
|
5862
|
+
latexTrigger: ["\\dots"],
|
|
5863
|
+
kind: "infix",
|
|
5864
|
+
precedence: 800,
|
|
5865
|
+
parse: parseRange
|
|
5866
|
+
},
|
|
5754
5867
|
{
|
|
5755
5868
|
latexTrigger: [";"],
|
|
5756
5869
|
kind: "infix",
|
|
@@ -5935,13 +6048,24 @@ var DEFINITIONS_CORE = [
|
|
|
5935
6048
|
const args = operands(expr);
|
|
5936
6049
|
if (!args || args.length < 2) return "";
|
|
5937
6050
|
const body = args[0];
|
|
5938
|
-
const
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
6051
|
+
const elements = args.slice(1);
|
|
6052
|
+
const allElements = elements.every((e) => operator(e) === "Element");
|
|
6053
|
+
if (!allElements) {
|
|
6054
|
+
return joinLatex([
|
|
6055
|
+
"\\operatorname{Loop}(",
|
|
6056
|
+
serializer.serialize(body),
|
|
6057
|
+
", ",
|
|
6058
|
+
serializer.serialize(elements[0]),
|
|
6059
|
+
")"
|
|
6060
|
+
]);
|
|
6061
|
+
}
|
|
6062
|
+
if (elements.length === 1) {
|
|
6063
|
+
const elem = elements[0];
|
|
6064
|
+
const index = operand(elem, 1);
|
|
6065
|
+
const coll = operand(elem, 2);
|
|
6066
|
+
if (operator(coll) === "Range") {
|
|
6067
|
+
const lo = operand(coll, 1);
|
|
6068
|
+
const hi = operand(coll, 2);
|
|
5945
6069
|
return joinLatex([
|
|
5946
6070
|
"\\text{for }",
|
|
5947
6071
|
serializer.serialize(index),
|
|
@@ -5953,13 +6077,27 @@ var DEFINITIONS_CORE = [
|
|
|
5953
6077
|
serializer.serialize(body)
|
|
5954
6078
|
]);
|
|
5955
6079
|
}
|
|
6080
|
+
return joinLatex([
|
|
6081
|
+
serializer.serialize(body),
|
|
6082
|
+
" \\operatorname{for} ",
|
|
6083
|
+
serializer.serialize(index),
|
|
6084
|
+
" = ",
|
|
6085
|
+
serializer.serialize(coll)
|
|
6086
|
+
]);
|
|
5956
6087
|
}
|
|
6088
|
+
const bindings = elements.map((elem) => {
|
|
6089
|
+
const name = operand(elem, 1);
|
|
6090
|
+
const coll = operand(elem, 2);
|
|
6091
|
+
return joinLatex([
|
|
6092
|
+
serializer.serialize(name),
|
|
6093
|
+
" = ",
|
|
6094
|
+
serializer.serialize(coll)
|
|
6095
|
+
]);
|
|
6096
|
+
}).join(", ");
|
|
5957
6097
|
return joinLatex([
|
|
5958
|
-
"\\operatorname{Loop}(",
|
|
5959
6098
|
serializer.serialize(body),
|
|
5960
|
-
"
|
|
5961
|
-
|
|
5962
|
-
")"
|
|
6099
|
+
" \\operatorname{for} ",
|
|
6100
|
+
bindings
|
|
5963
6101
|
]);
|
|
5964
6102
|
}
|
|
5965
6103
|
},
|
|
@@ -5992,6 +6130,18 @@ var DEFINITIONS_CORE = [
|
|
|
5992
6130
|
precedence: 245,
|
|
5993
6131
|
parse: (parser, until) => parseForExpression(parser, until)
|
|
5994
6132
|
},
|
|
6133
|
+
// \operatorname{for} as postfix infix (list comprehension):
|
|
6134
|
+
// `body \operatorname{for} x = L_1, y = L_2`
|
|
6135
|
+
// Precedence 19 — just below comma (20) so the body is allowed to use
|
|
6136
|
+
// any operator (including comma sequencing) up to the keyword, and the
|
|
6137
|
+
// bindings can be comma-separated below us.
|
|
6138
|
+
{
|
|
6139
|
+
symbolTrigger: "for",
|
|
6140
|
+
kind: "infix",
|
|
6141
|
+
associativity: "none",
|
|
6142
|
+
precedence: 19,
|
|
6143
|
+
parse: (parser, lhs, until) => parseForComprehension(parser, lhs, until)
|
|
6144
|
+
},
|
|
5995
6145
|
// \operatorname{break}
|
|
5996
6146
|
{
|
|
5997
6147
|
symbolTrigger: "break",
|
|
@@ -6196,7 +6346,10 @@ var DEFINITIONS_CORE = [
|
|
|
6196
6346
|
if (!sym2 || !parser.getSymbolType(sym2).matches("function")) return null;
|
|
6197
6347
|
parser.addBoundary([")"]);
|
|
6198
6348
|
const expr = parser.parseExpression(until);
|
|
6199
|
-
if (!parser.matchBoundary())
|
|
6349
|
+
if (!parser.matchBoundary()) {
|
|
6350
|
+
parser.removeBoundary();
|
|
6351
|
+
return null;
|
|
6352
|
+
}
|
|
6200
6353
|
if (!parser.match("<}>")) return null;
|
|
6201
6354
|
return ["Derivative", lhs, expr];
|
|
6202
6355
|
}
|
|
@@ -6637,7 +6790,12 @@ function parseBrackets(parser, body) {
|
|
|
6637
6790
|
if (isEmptySequence(body)) return ["List"];
|
|
6638
6791
|
const h = operator(body);
|
|
6639
6792
|
if (h === "Range" || h === "Linspace") return body;
|
|
6640
|
-
if (h === "Sequence")
|
|
6793
|
+
if (h === "Sequence") {
|
|
6794
|
+
const elems = operands(body);
|
|
6795
|
+
const inferred = tryInferRangeFromElements(elems, parser);
|
|
6796
|
+
if (inferred) return inferred;
|
|
6797
|
+
return ["List", ...elems];
|
|
6798
|
+
}
|
|
6641
6799
|
if (h === "Delimiter") {
|
|
6642
6800
|
const delim = stringValue(operand(body, 2)) ?? "...";
|
|
6643
6801
|
if (delim === ";" || delim === ".;.") {
|
|
@@ -6650,12 +6808,37 @@ function parseBrackets(parser, body) {
|
|
|
6650
6808
|
}
|
|
6651
6809
|
if (delim === "," || delim === ".,.") {
|
|
6652
6810
|
body = operand(body, 1);
|
|
6653
|
-
if (operator(body) === "Sequence")
|
|
6811
|
+
if (operator(body) === "Sequence") {
|
|
6812
|
+
const elems = operands(body);
|
|
6813
|
+
const inferred = tryInferRangeFromElements(elems, parser);
|
|
6814
|
+
if (inferred) return inferred;
|
|
6815
|
+
return ["List", ...elems];
|
|
6816
|
+
}
|
|
6654
6817
|
return ["List", body ?? "Nothing"];
|
|
6655
6818
|
}
|
|
6656
6819
|
}
|
|
6657
6820
|
return ["List", body];
|
|
6658
6821
|
}
|
|
6822
|
+
function tryInferRangeFromElements(elems, parser) {
|
|
6823
|
+
if (elems.length < 4) return null;
|
|
6824
|
+
const penultimate = elems[elems.length - 2];
|
|
6825
|
+
if (symbol(penultimate) !== "ContinuationPlaceholder") return null;
|
|
6826
|
+
const samples = elems.slice(0, -2);
|
|
6827
|
+
const endExpr = elems[elems.length - 1];
|
|
6828
|
+
if (samples.length < 2) return null;
|
|
6829
|
+
const sampleNums = samples.map(machineValue);
|
|
6830
|
+
if (sampleNums.some((n) => n === null)) return null;
|
|
6831
|
+
const nums = sampleNums;
|
|
6832
|
+
const step = nums[nums.length - 1] - nums[nums.length - 2];
|
|
6833
|
+
const tol = parser.options.tolerance;
|
|
6834
|
+
if (Math.abs(step) < tol)
|
|
6835
|
+
return parser.error("degenerate-range-step", parser.index);
|
|
6836
|
+
for (let i = 1; i < nums.length; i++) {
|
|
6837
|
+
if (Math.abs(nums[i] - nums[i - 1] - step) > tol)
|
|
6838
|
+
return parser.error("inconsistent-range-samples", parser.index);
|
|
6839
|
+
}
|
|
6840
|
+
return ["Range", nums[0], endExpr, step];
|
|
6841
|
+
}
|
|
6659
6842
|
function serializeList(serializer, expr) {
|
|
6660
6843
|
if (nops(expr) > 1 && operands(expr).every((x) => {
|
|
6661
6844
|
const op = operator(x);
|
|
@@ -6907,6 +7090,35 @@ function parseForExpression(parser, until) {
|
|
|
6907
7090
|
["Element", index, ["Range", lower, upper]]
|
|
6908
7091
|
];
|
|
6909
7092
|
}
|
|
7093
|
+
function parseForComprehension(parser, lhs, until) {
|
|
7094
|
+
const bindingTerminator = {
|
|
7095
|
+
minPrec: 21,
|
|
7096
|
+
// Above comma (20) and ; (19), so `x = L_1` is captured whole
|
|
7097
|
+
condition: (p) => {
|
|
7098
|
+
if (until?.condition?.(p)) return true;
|
|
7099
|
+
const saved = p.index;
|
|
7100
|
+
p.skipVisualSpace();
|
|
7101
|
+
const isComma = p.peek === ",";
|
|
7102
|
+
p.index = saved;
|
|
7103
|
+
return isComma;
|
|
7104
|
+
}
|
|
7105
|
+
};
|
|
7106
|
+
const elements = [];
|
|
7107
|
+
do {
|
|
7108
|
+
parser.skipVisualSpace();
|
|
7109
|
+
const binding = parser.parseExpression(bindingTerminator);
|
|
7110
|
+
if (binding === null) break;
|
|
7111
|
+
const op = operator(binding);
|
|
7112
|
+
if (op !== "Equal" && op !== "Assign") return null;
|
|
7113
|
+
const name = operand(binding, 1);
|
|
7114
|
+
const list = operand(binding, 2);
|
|
7115
|
+
if (!name || !list) return null;
|
|
7116
|
+
elements.push(["Element", name, list]);
|
|
7117
|
+
parser.skipVisualSpace();
|
|
7118
|
+
} while (parser.match(","));
|
|
7119
|
+
if (elements.length === 0) return null;
|
|
7120
|
+
return ["Loop", lhs, ...elements];
|
|
7121
|
+
}
|
|
6910
7122
|
function parseWhereExpression(parser, lhs, until) {
|
|
6911
7123
|
const bindingTerminator = {
|
|
6912
7124
|
minPrec: 21,
|
|
@@ -12803,7 +13015,11 @@ var COLLECTIONS_LIBRARY = {
|
|
|
12803
13015
|
//
|
|
12804
13016
|
Range: {
|
|
12805
13017
|
complexity: 8200,
|
|
12806
|
-
signature: "(number, number?, step: number?) -> indexed_collection<
|
|
13018
|
+
signature: "(number, number?, step: number?) -> indexed_collection<number>",
|
|
13019
|
+
type: (ops) => {
|
|
13020
|
+
const allInt = ops.every((op) => op.isInteger);
|
|
13021
|
+
return allInt ? parseType("indexed_collection<integer>") : parseType("indexed_collection<number>");
|
|
13022
|
+
},
|
|
12807
13023
|
canonical: (ops, { engine: ce }) => {
|
|
12808
13024
|
if (ops.length === 0) return null;
|
|
12809
13025
|
if (ops.length === 1) return ce._fn("Range", [ce.One, ops[0].canonical]);
|
|
@@ -12827,19 +13043,26 @@ var COLLECTIONS_LIBRARY = {
|
|
|
12827
13043
|
const [lower, upper, step] = range(expr);
|
|
12828
13044
|
if (step === 0) return 0;
|
|
12829
13045
|
if (!isFinite(lower) || !isFinite(upper)) return Infinity;
|
|
12830
|
-
return
|
|
13046
|
+
return Math.max(0, Math.floor((upper - lower) / step) + 1);
|
|
12831
13047
|
},
|
|
12832
13048
|
contains: (expr, target) => {
|
|
12833
|
-
if (!target.type.matches("integer")) return false;
|
|
12834
13049
|
const t = target.re;
|
|
13050
|
+
if (!isFinite(t)) return false;
|
|
12835
13051
|
const [lower, upper, step] = range(expr);
|
|
12836
13052
|
if (step === 0) return false;
|
|
12837
|
-
if (step > 0)
|
|
12838
|
-
|
|
13053
|
+
if (step > 0) {
|
|
13054
|
+
if (t < lower || t > upper) return false;
|
|
13055
|
+
} else {
|
|
13056
|
+
if (t > lower || t < upper) return false;
|
|
13057
|
+
}
|
|
13058
|
+
const k = (t - lower) / step;
|
|
13059
|
+
const tol = expr.engine.tolerance;
|
|
13060
|
+
const kRounded = Math.round(k);
|
|
13061
|
+
return kRounded >= 0 && Math.abs(k - kRounded) < tol;
|
|
12839
13062
|
},
|
|
12840
13063
|
iterator: (expr) => {
|
|
12841
13064
|
const [lower, upper, step] = range(expr);
|
|
12842
|
-
const maxCount = step === 0 ? 0 : Math.floor((upper - lower) / step) + 1;
|
|
13065
|
+
const maxCount = step === 0 ? 0 : Math.max(0, Math.floor((upper - lower) / step) + 1);
|
|
12843
13066
|
let index = 1;
|
|
12844
13067
|
return {
|
|
12845
13068
|
next: () => {
|
|
@@ -12857,7 +13080,9 @@ var COLLECTIONS_LIBRARY = {
|
|
|
12857
13080
|
at: (expr, index) => {
|
|
12858
13081
|
if (typeof index !== "number") return void 0;
|
|
12859
13082
|
const [lower, upper, step] = range(expr);
|
|
12860
|
-
if (
|
|
13083
|
+
if (step === 0) return void 0;
|
|
13084
|
+
const maxCount = Math.max(0, Math.floor((upper - lower) / step) + 1);
|
|
13085
|
+
if (index < 1 || index > maxCount) return void 0;
|
|
12861
13086
|
return expr.engine.number(lower + step * (index - 1));
|
|
12862
13087
|
},
|
|
12863
13088
|
indexWhere: void 0,
|
|
@@ -12882,7 +13107,13 @@ var COLLECTIONS_LIBRARY = {
|
|
|
12882
13107
|
if (step > 0) return lower <= upper ? "positive" : "negative";
|
|
12883
13108
|
return lower >= upper ? "positive" : "negative";
|
|
12884
13109
|
},
|
|
12885
|
-
elttype: (
|
|
13110
|
+
elttype: (expr) => {
|
|
13111
|
+
if (!isFunction2(expr)) return "finite_integer";
|
|
13112
|
+
for (let i = 1; i <= expr.nops; i++) {
|
|
13113
|
+
if (!expr[`op${i}`].isInteger) return "finite_real";
|
|
13114
|
+
}
|
|
13115
|
+
return "finite_integer";
|
|
13116
|
+
}
|
|
12886
13117
|
}
|
|
12887
13118
|
},
|
|
12888
13119
|
Interval: {
|
|
@@ -13480,15 +13711,45 @@ var COLLECTIONS_LIBRARY = {
|
|
|
13480
13711
|
},
|
|
13481
13712
|
First: {
|
|
13482
13713
|
complexity: 8200,
|
|
13483
|
-
signature: "(
|
|
13714
|
+
signature: "(any) -> any",
|
|
13484
13715
|
type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
|
|
13485
|
-
evaluate: ([xs], { engine: ce }) =>
|
|
13716
|
+
evaluate: ([xs], { engine: ce }) => {
|
|
13717
|
+
if (!xs.isCollection)
|
|
13718
|
+
return ce.error([
|
|
13719
|
+
"incompatible-type",
|
|
13720
|
+
`'collection'`,
|
|
13721
|
+
xs.type.toString()
|
|
13722
|
+
]);
|
|
13723
|
+
return xs.at(1) ?? ce.Nothing;
|
|
13724
|
+
}
|
|
13486
13725
|
},
|
|
13487
13726
|
Second: {
|
|
13488
13727
|
complexity: 8200,
|
|
13489
|
-
signature: "(
|
|
13728
|
+
signature: "(any) -> any",
|
|
13490
13729
|
type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
|
|
13491
|
-
evaluate: ([xs], { engine: ce }) =>
|
|
13730
|
+
evaluate: ([xs], { engine: ce }) => {
|
|
13731
|
+
if (!xs.isCollection)
|
|
13732
|
+
return ce.error([
|
|
13733
|
+
"incompatible-type",
|
|
13734
|
+
`'collection'`,
|
|
13735
|
+
xs.type.toString()
|
|
13736
|
+
]);
|
|
13737
|
+
return xs.at(2) ?? ce.Nothing;
|
|
13738
|
+
}
|
|
13739
|
+
},
|
|
13740
|
+
Third: {
|
|
13741
|
+
complexity: 8200,
|
|
13742
|
+
signature: "(any) -> any",
|
|
13743
|
+
type: ([xs]) => xs.operatorDefinition?.collection?.elttype?.(xs) ?? "any",
|
|
13744
|
+
evaluate: ([xs], { engine: ce }) => {
|
|
13745
|
+
if (!xs.isCollection)
|
|
13746
|
+
return ce.error([
|
|
13747
|
+
"incompatible-type",
|
|
13748
|
+
`'collection'`,
|
|
13749
|
+
xs.type.toString()
|
|
13750
|
+
]);
|
|
13751
|
+
return xs.at(3) ?? ce.Nothing;
|
|
13752
|
+
}
|
|
13492
13753
|
},
|
|
13493
13754
|
Last: {
|
|
13494
13755
|
complexity: 8200,
|
|
@@ -14467,17 +14728,14 @@ function range(expr) {
|
|
|
14467
14728
|
if (!isFunction2(expr)) return [1, 0, 0];
|
|
14468
14729
|
if (expr.nops === 0) return [1, 0, 0];
|
|
14469
14730
|
let op1 = expr.op1.re;
|
|
14470
|
-
if (!isFinite(op1)) op1 = 1;
|
|
14471
|
-
else op1 = Math.round(op1);
|
|
14731
|
+
if (!isFinite(op1) && !op1) op1 = 1;
|
|
14472
14732
|
if (expr.nops === 1) return [1, op1, 1];
|
|
14473
14733
|
let op2 = expr.op2.re;
|
|
14474
14734
|
if (!isFinite(op2) && !op2) op2 = 1;
|
|
14475
|
-
|
|
14476
|
-
if (expr.nops === 2) return [op1, op2, op2 > op1 ? 1 : -1];
|
|
14735
|
+
if (expr.nops === 2) return [op1, op2, op2 >= op1 ? 1 : -1];
|
|
14477
14736
|
let op3 = expr.op3.re;
|
|
14478
|
-
if (!isFinite(op3)) op3 = 1;
|
|
14479
|
-
|
|
14480
|
-
return [op1, op2, op1 < op2 ? op3 : -op3];
|
|
14737
|
+
if (!isFinite(op3) && !op3) op3 = 1;
|
|
14738
|
+
return [op1, op2, op3];
|
|
14481
14739
|
}
|
|
14482
14740
|
function canonicalList(ops, { engine: ce }) {
|
|
14483
14741
|
const op1 = ops[0];
|
|
@@ -14826,6 +15084,23 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
14826
15084
|
};
|
|
14827
15085
|
return compilePair(0);
|
|
14828
15086
|
}
|
|
15087
|
+
if (h === "When") {
|
|
15088
|
+
if (args.length !== 2)
|
|
15089
|
+
throw new Error("When: expected exactly 2 arguments (expr, cond)");
|
|
15090
|
+
const fn2 = target.functions?.(h);
|
|
15091
|
+
if (fn2) {
|
|
15092
|
+
if (typeof fn2 === "function") {
|
|
15093
|
+
return fn2(args, (expr) => _BaseCompiler.compile(expr, target), target);
|
|
15094
|
+
}
|
|
15095
|
+
return `${fn2}(${args.map((x) => _BaseCompiler.compile(x, target)).join(", ")})`;
|
|
15096
|
+
}
|
|
15097
|
+
if (isSymbol2(args[1], "True"))
|
|
15098
|
+
return `(${_BaseCompiler.compile(args[0], target)})`;
|
|
15099
|
+
if (isSymbol2(args[1], "False")) return "NaN";
|
|
15100
|
+
const val = _BaseCompiler.compile(args[0], target);
|
|
15101
|
+
const cond = _BaseCompiler.compile(args[1], target);
|
|
15102
|
+
return `((${cond}) ? (${val}) : NaN)`;
|
|
15103
|
+
}
|
|
14829
15104
|
if (h === "Block") {
|
|
14830
15105
|
return _BaseCompiler.compileBlock(args, target);
|
|
14831
15106
|
}
|
|
@@ -14900,17 +15175,91 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
14900
15175
|
)}${target.ws("\n")}})()`;
|
|
14901
15176
|
}
|
|
14902
15177
|
/**
|
|
14903
|
-
* Compile a Loop expression
|
|
14904
|
-
*
|
|
15178
|
+
* Compile a Loop expression.
|
|
15179
|
+
*
|
|
15180
|
+
* Two forms are supported:
|
|
15181
|
+
*
|
|
15182
|
+
* 1. **Imperative / single-Element form** (existing behaviour):
|
|
15183
|
+
* `Loop(body, Element(i, Range(lo, hi)))`
|
|
15184
|
+
* Generates a raw `for (let i = lo; i <= hi; i++) { body }` loop wrapped
|
|
15185
|
+
* in an IIFE. The loop counter is always a plain number. For targets
|
|
15186
|
+
* that wrap numeric values (e.g. interval-js uses `_IA.point()`),
|
|
15187
|
+
* references to the loop index inside the body are re-wrapped via
|
|
15188
|
+
* `target.number`. `break` / `continue` / `return` are preserved.
|
|
15189
|
+
*
|
|
15190
|
+
* 2. **Comprehension / variadic-Element form** (new):
|
|
15191
|
+
* `Loop(body, Element(x, coll1), Element(y, coll2), …)`
|
|
15192
|
+
* When two or more `Element` clauses are present — or when the single
|
|
15193
|
+
* Element's collection is not a `Range` — the loop is compiled as a
|
|
15194
|
+
* comprehension that collects results into an array. Each clause
|
|
15195
|
+
* produces a `for (const name of collection)` loop, nested
|
|
15196
|
+
* outermost-to-innermost, and the innermost body pushes into `result`.
|
|
15197
|
+
*
|
|
15198
|
+
* Example output (JS):
|
|
15199
|
+
* ```js
|
|
15200
|
+
* (() => { const result = [];
|
|
15201
|
+
* for (const x of [1,2]) { for (const y of [3,4]) { result.push(body); } }
|
|
15202
|
+
* return result; })()
|
|
15203
|
+
* ```
|
|
14905
15204
|
*
|
|
14906
|
-
*
|
|
14907
|
-
*
|
|
14908
|
-
*
|
|
15205
|
+
* GLSL: multi-Element comprehension is not trivially representable in
|
|
15206
|
+
* GLSL (no dynamic arrays, no push). A compile-time error is thrown.
|
|
15207
|
+
* TODO(E3-GLSL): support GLSL multi-Element via a pre-declared fixed-size
|
|
15208
|
+
* array or by unrolling when bounds are known at compile time.
|
|
14909
15209
|
*/
|
|
14910
15210
|
static compileForLoop(args, target) {
|
|
14911
15211
|
if (!args[0]) throw new Error("Loop: no body");
|
|
14912
15212
|
if (!args[1]) throw new Error("Loop: no indexing set");
|
|
14913
|
-
const
|
|
15213
|
+
const body = args[0];
|
|
15214
|
+
const elements = args.slice(1);
|
|
15215
|
+
const useComprehension = elements.length > 1 || elements.length === 1 && isFunction2(elements[0], "Element") && !_BaseCompiler.isLegacyCompatibleRange(elements[0].ops[1]);
|
|
15216
|
+
if (useComprehension) {
|
|
15217
|
+
const lang = target.language ?? "";
|
|
15218
|
+
if (lang === "glsl" || lang === "wgsl") {
|
|
15219
|
+
throw new Error(
|
|
15220
|
+
`${lang.toUpperCase()}: multi-Element Loop comprehension is not yet supported. TODO(E3-GLSL): unroll or use a fixed-size array.`
|
|
15221
|
+
);
|
|
15222
|
+
}
|
|
15223
|
+
const narrowedElements = [];
|
|
15224
|
+
for (let i = 0; i < elements.length; i++) {
|
|
15225
|
+
const elem = elements[i];
|
|
15226
|
+
if (!isFunction2(elem, "Element"))
|
|
15227
|
+
throw new Error(
|
|
15228
|
+
`Loop: argument ${i + 1} must be an Element clause, got ${elem.operator ?? "?"}`
|
|
15229
|
+
);
|
|
15230
|
+
if (!isSymbol2(elem.ops[0]))
|
|
15231
|
+
throw new Error(
|
|
15232
|
+
`Loop: Element index (argument ${i + 1}) must be a symbol`
|
|
15233
|
+
);
|
|
15234
|
+
narrowedElements.push(elem);
|
|
15235
|
+
}
|
|
15236
|
+
const loopVarSet = new Set(
|
|
15237
|
+
narrowedElements.map(
|
|
15238
|
+
(e) => e.ops[0].symbol
|
|
15239
|
+
)
|
|
15240
|
+
);
|
|
15241
|
+
const needsWrap2 = target.number(0) !== "0";
|
|
15242
|
+
const bodyTarget2 = needsWrap2 ? {
|
|
15243
|
+
...target,
|
|
15244
|
+
var: (id) => loopVarSet.has(id) ? target.number(0).replace("0", id) : target.var(id)
|
|
15245
|
+
} : target;
|
|
15246
|
+
const bodyCode = _BaseCompiler.compile(body, bodyTarget2);
|
|
15247
|
+
let inner = `result.push(${bodyCode});`;
|
|
15248
|
+
for (let i = narrowedElements.length - 1; i >= 0; i--) {
|
|
15249
|
+
const elem = narrowedElements[i];
|
|
15250
|
+
const name = elem.ops[0].symbol;
|
|
15251
|
+
const collExpr = elem.ops[1];
|
|
15252
|
+
let collection;
|
|
15253
|
+
if (isFunction2(collExpr, "Range")) {
|
|
15254
|
+
collection = _BaseCompiler.compileRangeIterable(collExpr, bodyTarget2);
|
|
15255
|
+
} else {
|
|
15256
|
+
collection = _BaseCompiler.compile(collExpr, bodyTarget2);
|
|
15257
|
+
}
|
|
15258
|
+
inner = `for (const ${name} of ${collection}) { ${inner} }`;
|
|
15259
|
+
}
|
|
15260
|
+
return `(() => { const result = []; ${inner} return result; })()`;
|
|
15261
|
+
}
|
|
15262
|
+
const indexing = elements[0];
|
|
14914
15263
|
if (!isFunction2(indexing, "Element"))
|
|
14915
15264
|
throw new Error("Loop: expected Element(index, Range(lo, hi))");
|
|
14916
15265
|
const indexExpr = indexing.ops[0];
|
|
@@ -14928,13 +15277,72 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
14928
15277
|
...target,
|
|
14929
15278
|
var: (id) => id === index ? needsWrap ? target.number(0).replace("0", index) : index : target.var(id)
|
|
14930
15279
|
};
|
|
14931
|
-
const bodyStmts = _BaseCompiler.compileLoopBody(
|
|
15280
|
+
const bodyStmts = _BaseCompiler.compileLoopBody(body, bodyTarget);
|
|
14932
15281
|
return `(() => {${target.ws(
|
|
14933
15282
|
"\n"
|
|
14934
15283
|
)}for (let ${index} = ${lower}; ${index} <= ${upper}; ${index}++) {${target.ws(
|
|
14935
15284
|
"\n"
|
|
14936
15285
|
)}${bodyStmts}${target.ws("\n")}}${target.ws("\n")}})()`;
|
|
14937
15286
|
}
|
|
15287
|
+
/**
|
|
15288
|
+
* Returns `true` when the given collection expression is a `Range` whose
|
|
15289
|
+
* runtime semantics match the legacy imperative for-loop shape
|
|
15290
|
+
* `for (let i = lo; i <= hi; i++)`.
|
|
15291
|
+
*
|
|
15292
|
+
* Concretely: integer-ascending bounds and step omitted-or-1. When bounds
|
|
15293
|
+
* are not statically numeric we accept the Range (the historical
|
|
15294
|
+
* behaviour) — runtime mismatch in the descending-unknown-bounds case is
|
|
15295
|
+
* left as a known limitation; callers can force the iterable path by
|
|
15296
|
+
* supplying an explicit step.
|
|
15297
|
+
*/
|
|
15298
|
+
static isLegacyCompatibleRange(coll) {
|
|
15299
|
+
if (!isFunction2(coll, "Range")) return false;
|
|
15300
|
+
if (coll.ops.length >= 3) {
|
|
15301
|
+
const stepExpr = coll.ops[2];
|
|
15302
|
+
if (!isNumber(stepExpr) || stepExpr.re !== 1) return false;
|
|
15303
|
+
}
|
|
15304
|
+
const lo = coll.ops[0];
|
|
15305
|
+
const hi = coll.ops[1];
|
|
15306
|
+
if (isNumber(lo) && !Number.isInteger(lo.re)) return false;
|
|
15307
|
+
if (isNumber(hi) && !Number.isInteger(hi.re)) return false;
|
|
15308
|
+
if (isNumber(lo) && isNumber(hi) && lo.re > hi.re) return false;
|
|
15309
|
+
return true;
|
|
15310
|
+
}
|
|
15311
|
+
/**
|
|
15312
|
+
* Compile a `Range(lo, hi)` or `Range(lo, hi, step)` expression into a JS
|
|
15313
|
+
* iterable expression. Mirrors the runtime semantics in
|
|
15314
|
+
* `library/collections.ts` Range:
|
|
15315
|
+
* count = step === 0 ? 0 : max(0, floor((hi - lo) / step) + 1)
|
|
15316
|
+
* element = lo + step * k (0-indexed)
|
|
15317
|
+
* Default step is 1 when omitted. Bounds and step may be fractional.
|
|
15318
|
+
*
|
|
15319
|
+
* Only used from the comprehension path in `compileForLoop`.
|
|
15320
|
+
* Caller must have already verified `isFunction(rangeExpr, 'Range')`.
|
|
15321
|
+
*/
|
|
15322
|
+
static compileRangeIterable(rangeExpr, target) {
|
|
15323
|
+
const loExpr = rangeExpr.ops[0];
|
|
15324
|
+
const hiExpr = rangeExpr.ops[1];
|
|
15325
|
+
const stepExpr = rangeExpr.ops[2];
|
|
15326
|
+
if (isNumber(loExpr) && isNumber(hiExpr) && (stepExpr === void 0 || isNumber(stepExpr))) {
|
|
15327
|
+
const lo2 = loExpr.re;
|
|
15328
|
+
const hi2 = hiExpr.re;
|
|
15329
|
+
const step2 = stepExpr === void 0 ? hi2 >= lo2 ? 1 : -1 : stepExpr.re;
|
|
15330
|
+
if (step2 === 0) return "[]";
|
|
15331
|
+
const len = Math.max(0, Math.floor((hi2 - lo2) / step2) + 1);
|
|
15332
|
+
if (step2 === 1) {
|
|
15333
|
+
if (lo2 === 0) return `Array.from({length:${len}},(_,k)=>k)`;
|
|
15334
|
+
return `Array.from({length:${len}},(_,k)=>${lo2}+k)`;
|
|
15335
|
+
}
|
|
15336
|
+
return `Array.from({length:${len}},(_,k)=>${lo2}+(${step2})*k)`;
|
|
15337
|
+
}
|
|
15338
|
+
const lo = _BaseCompiler.compile(loExpr, target);
|
|
15339
|
+
const hi = _BaseCompiler.compile(hiExpr, target);
|
|
15340
|
+
if (stepExpr === void 0) {
|
|
15341
|
+
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})`;
|
|
15342
|
+
}
|
|
15343
|
+
const step = _BaseCompiler.compile(stepExpr, target);
|
|
15344
|
+
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})`;
|
|
15345
|
+
}
|
|
14938
15346
|
/**
|
|
14939
15347
|
* Compile a loop body expression as statements (not wrapped in IIFE).
|
|
14940
15348
|
* Handles Break, Continue, Return as statements, and If as if-else when
|
|
@@ -25501,7 +25909,7 @@ function compileToIntervalTarget(expr, target) {
|
|
|
25501
25909
|
}
|
|
25502
25910
|
|
|
25503
25911
|
// src/compile.ts
|
|
25504
|
-
var version = "0.
|
|
25912
|
+
var version = "0.57.0";
|
|
25505
25913
|
export {
|
|
25506
25914
|
BaseCompiler,
|
|
25507
25915
|
GLSLTarget,
|