numbl 0.4.0 → 0.4.1
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-cli/cli.js +768 -120
- package/dist-lib/graphics/types.d.ts +40 -1
- package/dist-lib/lib.js +767 -119
- package/dist-lib/numbl-core/interpreter/interpreter.d.ts +1 -1
- package/dist-lib/numbl-core/interpreter/interpreterFunctions.d.ts +13 -1
- package/dist-lib/numbl-core/runtime/plotUtils.d.ts +28 -2
- package/dist-lib/numbl-core/runtime/runtimePlot.d.ts +5 -0
- package/dist-lib/numbl-core/runtime/types.d.ts +6 -3
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-plot-viewer/assets/index-DfxsWeyf.js +4426 -0
- package/dist-plot-viewer/index.html +1 -1
- package/dist-site-viewer/assets/index-C5c2lKAx.js +4748 -0
- package/dist-site-viewer/assets/{numbl-worker-VkVtodCX.js → numbl-worker-CkoM4MUa.js} +121 -121
- package/dist-site-viewer/index.html +1 -1
- package/package.json +1 -1
- package/dist-plot-viewer/assets/index-COAM8o1E.js +0 -4426
- package/dist-site-viewer/assets/index-CgBUy7v7.js +0 -4748
package/dist-lib/lib.js
CHANGED
|
@@ -287,10 +287,12 @@ var RuntimeClassInstanceArray = class extends Refcounted {
|
|
|
287
287
|
kind = "class_instance_array";
|
|
288
288
|
className;
|
|
289
289
|
elements;
|
|
290
|
-
|
|
290
|
+
shape;
|
|
291
|
+
constructor(className, elements, shape) {
|
|
291
292
|
super();
|
|
292
293
|
this.className = className;
|
|
293
294
|
this.elements = elements;
|
|
295
|
+
this.shape = shape ?? [1, elements.length];
|
|
294
296
|
for (const el of elements) incref(el);
|
|
295
297
|
}
|
|
296
298
|
_destroy(rt) {
|
|
@@ -797,7 +799,7 @@ function displayValue(v) {
|
|
|
797
799
|
case "dictionary":
|
|
798
800
|
return formatDictionary(v);
|
|
799
801
|
case "class_instance_array":
|
|
800
|
-
return `
|
|
802
|
+
return ` ${v.shape[0]}x${v.shape[1]} ${v.className} array`;
|
|
801
803
|
}
|
|
802
804
|
}
|
|
803
805
|
var formatStructArray = (v) => {
|
|
@@ -20391,10 +20393,11 @@ function sparseElemMul(a, b) {
|
|
|
20391
20393
|
}
|
|
20392
20394
|
function sparseElemMulDense(S, D) {
|
|
20393
20395
|
const [dRows, dCols] = tensorSize2D(D);
|
|
20394
|
-
if (S.m
|
|
20396
|
+
if (!(dRows === S.m || dRows === 1) || !(dCols === S.n || dCols === 1))
|
|
20395
20397
|
throw new RuntimeError(
|
|
20396
20398
|
`Matrix dimensions must agree: [${S.m},${S.n}] vs [${dRows},${dCols}]`
|
|
20397
20399
|
);
|
|
20400
|
+
const denseIdx = (row, col) => (dCols === 1 ? 0 : col) * dRows + (dRows === 1 ? 0 : row);
|
|
20398
20401
|
const hasImag = isComplexSparse(S) || D.imag !== void 0;
|
|
20399
20402
|
const irList = [];
|
|
20400
20403
|
const prList = [];
|
|
@@ -20404,7 +20407,7 @@ function sparseElemMulDense(S, D) {
|
|
|
20404
20407
|
jc[col] = irList.length;
|
|
20405
20408
|
for (let k = S.jc[col]; k < S.jc[col + 1]; k++) {
|
|
20406
20409
|
const row = S.ir[k];
|
|
20407
|
-
const idx = col
|
|
20410
|
+
const idx = denseIdx(row, col);
|
|
20408
20411
|
const aRe = S.pr[k], aIm = S.pi ? S.pi[k] : 0;
|
|
20409
20412
|
const bRe = D.data[idx], bIm = D.imag ? D.imag[idx] : 0;
|
|
20410
20413
|
const re = aRe * bRe - aIm * bIm;
|
|
@@ -22513,12 +22516,24 @@ function transposeCore(v, conjugate) {
|
|
|
22513
22516
|
if (v._isLogical) t._isLogical = true;
|
|
22514
22517
|
return t;
|
|
22515
22518
|
}
|
|
22519
|
+
function transposeClassInstanceArray(v) {
|
|
22520
|
+
const [r, c] = v.shape;
|
|
22521
|
+
const out = new Array(v.elements.length);
|
|
22522
|
+
for (let i = 0; i < r; i++) {
|
|
22523
|
+
for (let j = 0; j < c; j++) {
|
|
22524
|
+
out[i * c + j] = v.elements[j * r + i];
|
|
22525
|
+
}
|
|
22526
|
+
}
|
|
22527
|
+
return new RuntimeClassInstanceArray(v.className, out, [c, r]);
|
|
22528
|
+
}
|
|
22516
22529
|
function mTranspose(v) {
|
|
22517
22530
|
if (isRuntimeSparseMatrix(v)) return sparseTranspose(v);
|
|
22518
22531
|
if (isRuntimeComplexNumber(v)) return v;
|
|
22519
22532
|
if (isRuntimeNumber(v) || isRuntimeLogical(v)) return v;
|
|
22520
22533
|
if (isRuntimeCell(v)) return transposeCellArray(v);
|
|
22521
22534
|
if (isRuntimeChar(v)) return v;
|
|
22535
|
+
if (isRuntimeClassInstance(v)) return v;
|
|
22536
|
+
if (isRuntimeClassInstanceArray(v)) return transposeClassInstanceArray(v);
|
|
22522
22537
|
if (!isRuntimeTensor(v))
|
|
22523
22538
|
throw new RuntimeError("Cannot transpose non-numeric value");
|
|
22524
22539
|
return transposeCore(v, false);
|
|
@@ -22529,6 +22544,8 @@ function mConjugateTranspose(v) {
|
|
|
22529
22544
|
if (isRuntimeNumber(v) || isRuntimeLogical(v)) return v;
|
|
22530
22545
|
if (isRuntimeCell(v)) return transposeCellArray(v);
|
|
22531
22546
|
if (isRuntimeChar(v)) return v;
|
|
22547
|
+
if (isRuntimeClassInstance(v)) return v;
|
|
22548
|
+
if (isRuntimeClassInstanceArray(v)) return transposeClassInstanceArray(v);
|
|
22532
22549
|
if (!isRuntimeTensor(v))
|
|
22533
22550
|
throw new RuntimeError("Cannot transpose non-numeric value");
|
|
22534
22551
|
return transposeCore(v, true);
|
|
@@ -25213,6 +25230,60 @@ function cellCatAlongDim(values, dimIdx) {
|
|
|
25213
25230
|
}
|
|
25214
25231
|
|
|
25215
25232
|
// src/numbl-core/runtime/struct-access.ts
|
|
25233
|
+
function handlePropToRuntime(v) {
|
|
25234
|
+
if (typeof v === "number") return RTV.num(v);
|
|
25235
|
+
if (typeof v === "boolean") return RTV.logical(v);
|
|
25236
|
+
if (typeof v === "string") return RTV.char(v);
|
|
25237
|
+
if (Array.isArray(v)) {
|
|
25238
|
+
const data = allocFloat64Array(v);
|
|
25239
|
+
return RTV.tensor(data, [1, v.length]);
|
|
25240
|
+
}
|
|
25241
|
+
return v;
|
|
25242
|
+
}
|
|
25243
|
+
var HANDLE_DEFAULTS = {
|
|
25244
|
+
quiver3: {
|
|
25245
|
+
LineWidth: 0.5,
|
|
25246
|
+
LineStyle: "-",
|
|
25247
|
+
ShowArrowHead: true,
|
|
25248
|
+
AutoScale: true,
|
|
25249
|
+
AutoScaleFactor: 0.9,
|
|
25250
|
+
Marker: "none",
|
|
25251
|
+
Color: [0, 0.447, 0.741]
|
|
25252
|
+
}
|
|
25253
|
+
};
|
|
25254
|
+
function resolveHandleKey(trace, field) {
|
|
25255
|
+
if (field in trace) return field;
|
|
25256
|
+
const camel = field.charAt(0).toLowerCase() + field.slice(1);
|
|
25257
|
+
if (camel in trace) return camel;
|
|
25258
|
+
if (field.endsWith("Data")) {
|
|
25259
|
+
const base = field.slice(0, -4);
|
|
25260
|
+
const short = base.charAt(0).toLowerCase() + base.slice(1);
|
|
25261
|
+
if (short in trace) return short;
|
|
25262
|
+
}
|
|
25263
|
+
return null;
|
|
25264
|
+
}
|
|
25265
|
+
function runtimeToHandleValue(value, current) {
|
|
25266
|
+
if (typeof current === "boolean") {
|
|
25267
|
+
if (typeof value === "boolean") return value;
|
|
25268
|
+
if (typeof value === "number") return value !== 0;
|
|
25269
|
+
if (isRuntimeString(value) || isRuntimeChar(value)) {
|
|
25270
|
+
const s = (isRuntimeChar(value) ? value.value : value).toLowerCase();
|
|
25271
|
+
return !(s === "off" || s === "false" || s === "0");
|
|
25272
|
+
}
|
|
25273
|
+
return true;
|
|
25274
|
+
}
|
|
25275
|
+
if (typeof current === "string") {
|
|
25276
|
+
return isRuntimeChar(value) ? value.value : isRuntimeString(value) ? value : String(value);
|
|
25277
|
+
}
|
|
25278
|
+
if (typeof current === "number" || current === void 0) {
|
|
25279
|
+
if (typeof value === "number") return value;
|
|
25280
|
+
if (isRuntimeNumber(value)) return value;
|
|
25281
|
+
}
|
|
25282
|
+
if (Array.isArray(current) && isRuntimeTensor(value)) {
|
|
25283
|
+
return Array.from(value.data);
|
|
25284
|
+
}
|
|
25285
|
+
return value;
|
|
25286
|
+
}
|
|
25216
25287
|
function getRTValueField(base, field) {
|
|
25217
25288
|
if (isRuntimeStruct(base) || isRuntimeClassInstance(base)) {
|
|
25218
25289
|
const val = base.fields.get(field);
|
|
@@ -25236,6 +25307,15 @@ function getRTValueField(base, field) {
|
|
|
25236
25307
|
});
|
|
25237
25308
|
return horzcat(...values);
|
|
25238
25309
|
}
|
|
25310
|
+
if (isRuntimeGraphicsHandle(base)) {
|
|
25311
|
+
const key = resolveHandleKey(base._trace, field);
|
|
25312
|
+
if (key !== null) return handlePropToRuntime(base._trace[key]);
|
|
25313
|
+
const dflt = HANDLE_DEFAULTS[base._traceType]?.[field];
|
|
25314
|
+
if (dflt !== void 0) return handlePropToRuntime(dflt);
|
|
25315
|
+
throw new RuntimeError(
|
|
25316
|
+
`No property '${field}' on ${base._traceType} handle`
|
|
25317
|
+
);
|
|
25318
|
+
}
|
|
25239
25319
|
throw new RuntimeError(`Cannot access field ${field} on ${kstr(base)}`);
|
|
25240
25320
|
}
|
|
25241
25321
|
function setRTValueField(base, field, value, rt) {
|
|
@@ -25280,6 +25360,12 @@ function setRTValueField(base, field, value, rt) {
|
|
|
25280
25360
|
`Cannot assign field '${field}' on a non-scalar struct array without indexing`
|
|
25281
25361
|
);
|
|
25282
25362
|
}
|
|
25363
|
+
if (isRuntimeGraphicsHandle(base)) {
|
|
25364
|
+
const key = resolveHandleKey(base._trace, field) ?? field.charAt(0).toLowerCase() + field.slice(1);
|
|
25365
|
+
const current = base._trace[key] ?? HANDLE_DEFAULTS[base._traceType]?.[field];
|
|
25366
|
+
base._trace[key] = runtimeToHandleValue(value, current);
|
|
25367
|
+
return base;
|
|
25368
|
+
}
|
|
25283
25369
|
if (isRuntimeNumber(base) && base === 0) {
|
|
25284
25370
|
return RTV.struct(/* @__PURE__ */ new Map([[field, value]]));
|
|
25285
25371
|
}
|
|
@@ -31218,7 +31304,7 @@ function getShape(v) {
|
|
|
31218
31304
|
if (isRuntimeSparseMatrix(v)) return [v.m, v.n];
|
|
31219
31305
|
if (isRuntimeCell(v)) return v.shape;
|
|
31220
31306
|
if (isRuntimeStructArray(v)) return [1, v.elements.length];
|
|
31221
|
-
if (isRuntimeClassInstanceArray(v)) return [
|
|
31307
|
+
if (isRuntimeClassInstanceArray(v)) return [...v.shape];
|
|
31222
31308
|
return [1, 1];
|
|
31223
31309
|
}
|
|
31224
31310
|
defineBuiltin({
|
|
@@ -31396,7 +31482,8 @@ defineBuiltin({
|
|
|
31396
31482
|
}
|
|
31397
31483
|
if (isRuntimeString(v)) return 1;
|
|
31398
31484
|
if (isRuntimeStructArray(v)) return v.elements.length;
|
|
31399
|
-
if (isRuntimeClassInstanceArray(v))
|
|
31485
|
+
if (isRuntimeClassInstanceArray(v))
|
|
31486
|
+
return v.elements.length === 0 ? 0 : Math.max(...v.shape);
|
|
31400
31487
|
return 1;
|
|
31401
31488
|
}
|
|
31402
31489
|
}
|
|
@@ -31509,8 +31596,15 @@ defineBuiltin({
|
|
|
31509
31596
|
if (isRuntimeClassInstanceArray(v)) return mkChar(v.className);
|
|
31510
31597
|
if (isRuntimeFunction(v)) return mkChar("function_handle");
|
|
31511
31598
|
if (isRuntimeDummyHandle(v)) return mkChar("dummy_handle");
|
|
31512
|
-
if (isRuntimeGraphicsHandle(v))
|
|
31513
|
-
|
|
31599
|
+
if (isRuntimeGraphicsHandle(v)) {
|
|
31600
|
+
const handleClass = {
|
|
31601
|
+
contour: "matlab.graphics.chart.primitive.Contour",
|
|
31602
|
+
quiver3: "matlab.graphics.chart.primitive.Quiver"
|
|
31603
|
+
};
|
|
31604
|
+
return mkChar(
|
|
31605
|
+
handleClass[v._traceType] ?? "matlab.graphics.primitive.Surface"
|
|
31606
|
+
);
|
|
31607
|
+
}
|
|
31514
31608
|
return mkChar("unknown");
|
|
31515
31609
|
}
|
|
31516
31610
|
}
|
|
@@ -36551,6 +36645,7 @@ defineBuiltin({
|
|
|
36551
36645
|
const blocks = args.map((a) => {
|
|
36552
36646
|
if (isRuntimeNumber(a))
|
|
36553
36647
|
return RTV.tensor(allocFloat64Array([a]), [1, 1]);
|
|
36648
|
+
if (isRuntimeSparseMatrix(a)) return sparseToDense(a);
|
|
36554
36649
|
if (!isRuntimeTensor(a))
|
|
36555
36650
|
throw new RuntimeError("blkdiag: arguments must be numeric");
|
|
36556
36651
|
return a;
|
|
@@ -37919,6 +38014,21 @@ defineBuiltin({
|
|
|
37919
38014
|
const shape = reps.length >= 2 ? reps : [reps[0], reps[0]];
|
|
37920
38015
|
return RTV.tensor(data, shape, imag2);
|
|
37921
38016
|
}
|
|
38017
|
+
if (isRuntimeCell(v)) {
|
|
38018
|
+
const srcShape2 = v.shape.length >= 2 ? v.shape : [1, v.shape[0] ?? v.data.length];
|
|
38019
|
+
const [sm, sn] = [srcShape2[0], srcShape2[1]];
|
|
38020
|
+
const r0 = reps[0] ?? 1;
|
|
38021
|
+
const r1 = reps.length >= 2 ? reps[1] : reps[0] ?? 1;
|
|
38022
|
+
const om = sm * r0;
|
|
38023
|
+
const on = sn * r1;
|
|
38024
|
+
const out2 = new Array(om * on);
|
|
38025
|
+
for (let J = 0; J < on; J++) {
|
|
38026
|
+
for (let I = 0; I < om; I++) {
|
|
38027
|
+
out2[I + J * om] = v.data[I % sm + J % sn * sm];
|
|
38028
|
+
}
|
|
38029
|
+
}
|
|
38030
|
+
return RTV.cell(out2, [om, on]);
|
|
38031
|
+
}
|
|
37922
38032
|
if (!isRuntimeTensor(v))
|
|
37923
38033
|
throw new RuntimeError("repmat: first argument must be numeric");
|
|
37924
38034
|
if (reps.every((r) => r === 1)) {
|
|
@@ -43992,6 +44102,13 @@ for (const name of ["groot", "gcf", "gca", "shg", "newplot"]) {
|
|
|
43992
44102
|
})
|
|
43993
44103
|
});
|
|
43994
44104
|
}
|
|
44105
|
+
registerIBuiltin({
|
|
44106
|
+
name: "camlight",
|
|
44107
|
+
resolve: () => ({
|
|
44108
|
+
outputTypes: [{ kind: "unknown" }],
|
|
44109
|
+
apply: (_args, nargout) => nargout >= 1 ? RTV.dummyHandle() : void 0
|
|
44110
|
+
})
|
|
44111
|
+
});
|
|
43995
44112
|
registerIBuiltin({
|
|
43996
44113
|
name: "get",
|
|
43997
44114
|
resolve: () => ({
|
|
@@ -44146,7 +44263,6 @@ registerIBuiltin({
|
|
|
44146
44263
|
})
|
|
44147
44264
|
});
|
|
44148
44265
|
for (const cm of [
|
|
44149
|
-
"parula",
|
|
44150
44266
|
"jet",
|
|
44151
44267
|
"hsv",
|
|
44152
44268
|
"hot",
|
|
@@ -44168,6 +44284,44 @@ for (const cm of [
|
|
|
44168
44284
|
})
|
|
44169
44285
|
});
|
|
44170
44286
|
}
|
|
44287
|
+
var PARULA_ANCHORS = [
|
|
44288
|
+
[0.2422, 0.1504, 0.6603],
|
|
44289
|
+
[0.278, 0.3556, 0.9777],
|
|
44290
|
+
[0.1085, 0.5267, 0.8943],
|
|
44291
|
+
[0.0469, 0.6353, 0.7861],
|
|
44292
|
+
[0.2161, 0.7269, 0.6499],
|
|
44293
|
+
[0.5044, 0.7993, 0.4519],
|
|
44294
|
+
[0.8328, 0.8056, 0.2008],
|
|
44295
|
+
[0.9871, 0.8092, 0.1432],
|
|
44296
|
+
[0.9763, 0.9831, 0.0538]
|
|
44297
|
+
];
|
|
44298
|
+
function parulaColormap(m) {
|
|
44299
|
+
const data = allocFloat64Array(m * 3);
|
|
44300
|
+
const last = PARULA_ANCHORS.length - 1;
|
|
44301
|
+
for (let i = 0; i < m; i++) {
|
|
44302
|
+
const t = m <= 1 ? 0 : i / (m - 1) * last;
|
|
44303
|
+
const k = Math.min(last - 1, Math.floor(t));
|
|
44304
|
+
const f = t - k;
|
|
44305
|
+
const a = PARULA_ANCHORS[k];
|
|
44306
|
+
const b = PARULA_ANCHORS[Math.min(last, k + 1)];
|
|
44307
|
+
for (let c = 0; c < 3; c++) {
|
|
44308
|
+
data[c * m + i] = a[c] + f * (b[c] - a[c]);
|
|
44309
|
+
}
|
|
44310
|
+
}
|
|
44311
|
+
return RTV.tensor(data, [m, 3]);
|
|
44312
|
+
}
|
|
44313
|
+
registerIBuiltin({
|
|
44314
|
+
name: "parula",
|
|
44315
|
+
resolve: () => ({
|
|
44316
|
+
outputTypes: [{ kind: "unknown" }],
|
|
44317
|
+
apply: (args) => {
|
|
44318
|
+
if (args.length >= 1 && (isRuntimeNumber(args[0]) || isRuntimeTensor(args[0]))) {
|
|
44319
|
+
return parulaColormap(Math.max(0, Math.round(toNumber(args[0]))));
|
|
44320
|
+
}
|
|
44321
|
+
return RTV.char("parula");
|
|
44322
|
+
}
|
|
44323
|
+
})
|
|
44324
|
+
});
|
|
44171
44325
|
var appdataStore = /* @__PURE__ */ new Map();
|
|
44172
44326
|
function resetAppdataStore() {
|
|
44173
44327
|
const rt = getCurrentRuntime();
|
|
@@ -46222,6 +46376,10 @@ var H = {
|
|
|
46222
46376
|
signatures: ["nexttile", "nexttile(IDX)"],
|
|
46223
46377
|
description: "Advance to the next tile in the current tiled layout, or move to tile IDX. Auto-creates a flow layout if none exists."
|
|
46224
46378
|
},
|
|
46379
|
+
surface: {
|
|
46380
|
+
signatures: ["surface(X,Y,Z)", "surface(Z)", "surface(X,Y,Z,C)"],
|
|
46381
|
+
description: "Primitive surface plot. Like surf, but adds to the current axes without clearing existing objects (does not respect hold)."
|
|
46382
|
+
},
|
|
46225
46383
|
title: {
|
|
46226
46384
|
signatures: ["title(TXT)"],
|
|
46227
46385
|
description: "Set title of current axes."
|
|
@@ -46258,6 +46416,10 @@ var H = {
|
|
|
46258
46416
|
signatures: ["clf"],
|
|
46259
46417
|
description: "Clear current figure."
|
|
46260
46418
|
},
|
|
46419
|
+
cla: {
|
|
46420
|
+
signatures: ["cla", "cla(ax)", "cla reset", "cla(ax,'reset')"],
|
|
46421
|
+
description: "Clear current axes. With 'reset', also reset axes properties to defaults."
|
|
46422
|
+
},
|
|
46261
46423
|
sgtitle: {
|
|
46262
46424
|
signatures: ["sgtitle(TXT)"],
|
|
46263
46425
|
description: "Set super-title for subplot grid."
|
|
@@ -46310,6 +46472,10 @@ var H = {
|
|
|
46310
46472
|
signatures: ["shg"],
|
|
46311
46473
|
description: "Show current figure."
|
|
46312
46474
|
},
|
|
46475
|
+
camlight: {
|
|
46476
|
+
signatures: ["camlight", "camlight(position)", "cl = camlight(___)"],
|
|
46477
|
+
description: "Create a light in camera coordinates. Stub in numbl (no lighting model): accepts all arguments and returns a placeholder handle."
|
|
46478
|
+
},
|
|
46313
46479
|
newplot: {
|
|
46314
46480
|
signatures: ["newplot"],
|
|
46315
46481
|
description: "Prepare axes for new plot."
|
|
@@ -47434,6 +47600,12 @@ function parseContourArgs(args, filled) {
|
|
|
47434
47600
|
let rows;
|
|
47435
47601
|
let cols;
|
|
47436
47602
|
let nLevels = 10;
|
|
47603
|
+
let levels;
|
|
47604
|
+
const applyLevelArg = (arg) => {
|
|
47605
|
+
const vals = toNumberArray(arg);
|
|
47606
|
+
if (vals.length <= 1) nLevels = vals.length === 1 ? vals[0] : nLevels;
|
|
47607
|
+
else levels = vals;
|
|
47608
|
+
};
|
|
47437
47609
|
if (numericCount === 1) {
|
|
47438
47610
|
const info = getMatrixInfo(args[pos++]);
|
|
47439
47611
|
rows = info.rows;
|
|
@@ -47447,8 +47619,7 @@ function parseContourArgs(args, filled) {
|
|
|
47447
47619
|
rows = info.rows;
|
|
47448
47620
|
cols = info.cols;
|
|
47449
47621
|
zData = info.data;
|
|
47450
|
-
|
|
47451
|
-
pos++;
|
|
47622
|
+
applyLevelArg(args[pos++]);
|
|
47452
47623
|
const gen = generateMeshgrid(rows, cols);
|
|
47453
47624
|
xData = gen.x;
|
|
47454
47625
|
yData = gen.y;
|
|
@@ -47469,15 +47640,144 @@ function parseContourArgs(args, filled) {
|
|
|
47469
47640
|
rows = zInfo.rows;
|
|
47470
47641
|
cols = zInfo.cols;
|
|
47471
47642
|
zData = zInfo.data;
|
|
47472
|
-
|
|
47473
|
-
pos++;
|
|
47643
|
+
applyLevelArg(args[pos++]);
|
|
47474
47644
|
const expanded = expandXY(x, y, rows, cols);
|
|
47475
47645
|
xData = expanded.x;
|
|
47476
47646
|
yData = expanded.y;
|
|
47477
47647
|
} else {
|
|
47478
47648
|
throw new Error("contour requires at least 1 argument");
|
|
47479
47649
|
}
|
|
47480
|
-
|
|
47650
|
+
let lineWidth;
|
|
47651
|
+
let lineStyle;
|
|
47652
|
+
let lineColor;
|
|
47653
|
+
for (; pos + 1 < args.length; pos += 2) {
|
|
47654
|
+
if (!isStringArg(args[pos])) break;
|
|
47655
|
+
const name = getStringValue(args[pos]).toLowerCase();
|
|
47656
|
+
const val = args[pos + 1];
|
|
47657
|
+
switch (name) {
|
|
47658
|
+
case "linewidth":
|
|
47659
|
+
lineWidth = toNumber(val);
|
|
47660
|
+
break;
|
|
47661
|
+
case "linestyle":
|
|
47662
|
+
lineStyle = getStringValue(val);
|
|
47663
|
+
break;
|
|
47664
|
+
case "linecolor":
|
|
47665
|
+
case "color":
|
|
47666
|
+
lineColor = isStringArg(val) ? getStringValue(val) : toNumberArray(val);
|
|
47667
|
+
break;
|
|
47668
|
+
case "levellist":
|
|
47669
|
+
case "levels": {
|
|
47670
|
+
const vals = toNumberArray(val);
|
|
47671
|
+
if (vals.length >= 1) levels = vals;
|
|
47672
|
+
break;
|
|
47673
|
+
}
|
|
47674
|
+
}
|
|
47675
|
+
}
|
|
47676
|
+
if (levels) nLevels = levels.length;
|
|
47677
|
+
return {
|
|
47678
|
+
x: xData,
|
|
47679
|
+
y: yData,
|
|
47680
|
+
z: zData,
|
|
47681
|
+
rows,
|
|
47682
|
+
cols,
|
|
47683
|
+
nLevels,
|
|
47684
|
+
...levels ? { levels } : {},
|
|
47685
|
+
...lineWidth !== void 0 ? { lineWidth } : {},
|
|
47686
|
+
...lineStyle !== void 0 ? { lineStyle } : {},
|
|
47687
|
+
...lineColor !== void 0 ? { lineColor } : {},
|
|
47688
|
+
filled
|
|
47689
|
+
};
|
|
47690
|
+
}
|
|
47691
|
+
function marchingSquaresCell(z00, z10, z01, z11, x00, y00, x10, y10, x01, y01, x11, y11, level) {
|
|
47692
|
+
const code = (z00 >= level ? 1 : 0) | (z10 >= level ? 2 : 0) | (z01 >= level ? 4 : 0) | (z11 >= level ? 8 : 0);
|
|
47693
|
+
if (code === 0 || code === 15) return [];
|
|
47694
|
+
const lerp = (a, b, za, zb) => a + (level - za) / (zb - za || 1) * (b - a);
|
|
47695
|
+
const bx = lerp(x00, x10, z00, z10), by = lerp(y00, y10, z00, z10);
|
|
47696
|
+
const rx = lerp(x10, x11, z10, z11), ry = lerp(y10, y11, z10, z11);
|
|
47697
|
+
const tx = lerp(x01, x11, z01, z11), ty = lerp(y01, y11, z01, z11);
|
|
47698
|
+
const lx = lerp(x00, x01, z00, z01), ly = lerp(y00, y01, z00, z01);
|
|
47699
|
+
const segs = [];
|
|
47700
|
+
switch (code) {
|
|
47701
|
+
case 1:
|
|
47702
|
+
case 14:
|
|
47703
|
+
segs.push([bx, by, lx, ly]);
|
|
47704
|
+
break;
|
|
47705
|
+
case 2:
|
|
47706
|
+
case 13:
|
|
47707
|
+
segs.push([bx, by, rx, ry]);
|
|
47708
|
+
break;
|
|
47709
|
+
case 3:
|
|
47710
|
+
case 12:
|
|
47711
|
+
segs.push([lx, ly, rx, ry]);
|
|
47712
|
+
break;
|
|
47713
|
+
case 4:
|
|
47714
|
+
case 11:
|
|
47715
|
+
segs.push([lx, ly, tx, ty]);
|
|
47716
|
+
break;
|
|
47717
|
+
case 5:
|
|
47718
|
+
case 10:
|
|
47719
|
+
segs.push([bx, by, tx, ty]);
|
|
47720
|
+
break;
|
|
47721
|
+
case 6:
|
|
47722
|
+
case 9:
|
|
47723
|
+
segs.push([bx, by, lx, ly]);
|
|
47724
|
+
segs.push([tx, ty, rx, ry]);
|
|
47725
|
+
break;
|
|
47726
|
+
case 7:
|
|
47727
|
+
case 8:
|
|
47728
|
+
segs.push([tx, ty, rx, ry]);
|
|
47729
|
+
break;
|
|
47730
|
+
}
|
|
47731
|
+
return segs;
|
|
47732
|
+
}
|
|
47733
|
+
function computeContourMatrix(trace) {
|
|
47734
|
+
const { x, y, z, rows, cols } = trace;
|
|
47735
|
+
const at = (a, i, j) => a[j * rows + i];
|
|
47736
|
+
let zMin = Infinity;
|
|
47737
|
+
let zMax = -Infinity;
|
|
47738
|
+
for (const v of z) {
|
|
47739
|
+
if (Number.isFinite(v)) {
|
|
47740
|
+
if (v < zMin) zMin = v;
|
|
47741
|
+
if (v > zMax) zMax = v;
|
|
47742
|
+
}
|
|
47743
|
+
}
|
|
47744
|
+
let levelList;
|
|
47745
|
+
if (trace.levels && trace.levels.length > 0) {
|
|
47746
|
+
levelList = trace.levels.filter((v) => Number.isFinite(v));
|
|
47747
|
+
} else {
|
|
47748
|
+
const n = Math.max(1, Math.round(trace.nLevels));
|
|
47749
|
+
levelList = [];
|
|
47750
|
+
if (Number.isFinite(zMin) && Number.isFinite(zMax) && zMax > zMin) {
|
|
47751
|
+
const step = (zMax - zMin) / (n + 1);
|
|
47752
|
+
for (let k = 1; k <= n; k++) levelList.push(zMin + k * step);
|
|
47753
|
+
}
|
|
47754
|
+
}
|
|
47755
|
+
const data = [];
|
|
47756
|
+
for (const level of levelList) {
|
|
47757
|
+
for (let j = 0; j < cols - 1; j++) {
|
|
47758
|
+
for (let i = 0; i < rows - 1; i++) {
|
|
47759
|
+
const segs = marchingSquaresCell(
|
|
47760
|
+
at(z, i, j),
|
|
47761
|
+
at(z, i + 1, j),
|
|
47762
|
+
at(z, i, j + 1),
|
|
47763
|
+
at(z, i + 1, j + 1),
|
|
47764
|
+
at(x, i, j),
|
|
47765
|
+
at(y, i, j),
|
|
47766
|
+
at(x, i + 1, j),
|
|
47767
|
+
at(y, i + 1, j),
|
|
47768
|
+
at(x, i, j + 1),
|
|
47769
|
+
at(y, i, j + 1),
|
|
47770
|
+
at(x, i + 1, j + 1),
|
|
47771
|
+
at(y, i + 1, j + 1),
|
|
47772
|
+
level
|
|
47773
|
+
);
|
|
47774
|
+
for (const [x1, y1, x2, y2] of segs) {
|
|
47775
|
+
data.push(level, 2, x1, y1, x2, y2);
|
|
47776
|
+
}
|
|
47777
|
+
}
|
|
47778
|
+
}
|
|
47779
|
+
}
|
|
47780
|
+
return { data, n: data.length / 2, levelList };
|
|
47481
47781
|
}
|
|
47482
47782
|
function parseMeshArgs(args) {
|
|
47483
47783
|
const trace = parseSurfArgs(args);
|
|
@@ -48425,6 +48725,213 @@ function computeQuiverAutoScale(x, y, u, v, rows, cols, factor) {
|
|
|
48425
48725
|
if (maxMag === 0) return 1;
|
|
48426
48726
|
return factor * spacing / maxMag;
|
|
48427
48727
|
}
|
|
48728
|
+
function parseQuiver3Args(args) {
|
|
48729
|
+
if (args.length < 4) throw new Error("quiver3 requires at least 4 arguments");
|
|
48730
|
+
let numericCount = 0;
|
|
48731
|
+
for (let i = 0; i < args.length; i++) {
|
|
48732
|
+
if (isNumericArg(args[i])) numericCount++;
|
|
48733
|
+
else break;
|
|
48734
|
+
}
|
|
48735
|
+
let pos = 0;
|
|
48736
|
+
let xData;
|
|
48737
|
+
let yData;
|
|
48738
|
+
let zData;
|
|
48739
|
+
let uData;
|
|
48740
|
+
let vData;
|
|
48741
|
+
let wData;
|
|
48742
|
+
let rows;
|
|
48743
|
+
let cols;
|
|
48744
|
+
const arity = numericCount >= 6 ? 6 : 4;
|
|
48745
|
+
if (arity === 4) {
|
|
48746
|
+
const zInfo = getMatrixInfo(args[pos++]);
|
|
48747
|
+
rows = zInfo.rows;
|
|
48748
|
+
cols = zInfo.cols;
|
|
48749
|
+
zData = zInfo.data;
|
|
48750
|
+
uData = getMatrixInfo(args[pos++]).data;
|
|
48751
|
+
vData = getMatrixInfo(args[pos++]).data;
|
|
48752
|
+
wData = getMatrixInfo(args[pos++]).data;
|
|
48753
|
+
const n = zData.length;
|
|
48754
|
+
if (rows === 1 || cols === 1) {
|
|
48755
|
+
xData = new Array(n);
|
|
48756
|
+
yData = new Array(n);
|
|
48757
|
+
for (let i = 0; i < n; i++) {
|
|
48758
|
+
xData[i] = i + 1;
|
|
48759
|
+
yData[i] = 1;
|
|
48760
|
+
}
|
|
48761
|
+
} else {
|
|
48762
|
+
const gen = generateMeshgrid(rows, n / rows);
|
|
48763
|
+
xData = gen.x;
|
|
48764
|
+
yData = gen.y;
|
|
48765
|
+
}
|
|
48766
|
+
} else {
|
|
48767
|
+
const X = args[pos++];
|
|
48768
|
+
const Y = args[pos++];
|
|
48769
|
+
const zInfo = getMatrixInfo(args[pos++]);
|
|
48770
|
+
rows = zInfo.rows;
|
|
48771
|
+
cols = zInfo.cols;
|
|
48772
|
+
zData = zInfo.data;
|
|
48773
|
+
uData = getMatrixInfo(args[pos++]).data;
|
|
48774
|
+
vData = getMatrixInfo(args[pos++]).data;
|
|
48775
|
+
wData = getMatrixInfo(args[pos++]).data;
|
|
48776
|
+
const n = uData.length;
|
|
48777
|
+
const xFlat = toNumberArray(X);
|
|
48778
|
+
const yFlat = toNumberArray(Y);
|
|
48779
|
+
if (xFlat.length === n && yFlat.length === n) {
|
|
48780
|
+
xData = xFlat;
|
|
48781
|
+
yData = yFlat;
|
|
48782
|
+
} else {
|
|
48783
|
+
const expanded = expandXY(X, Y, rows, cols);
|
|
48784
|
+
xData = expanded.x;
|
|
48785
|
+
yData = expanded.y;
|
|
48786
|
+
}
|
|
48787
|
+
}
|
|
48788
|
+
let autoScale = true;
|
|
48789
|
+
let autoScaleFactor = 0.9;
|
|
48790
|
+
let reportedASF = 0.9;
|
|
48791
|
+
if (pos < args.length && isNumericArg(args[pos]) && !isStringArg(args[pos])) {
|
|
48792
|
+
const s = toNumber(args[pos]);
|
|
48793
|
+
if (s === 0) {
|
|
48794
|
+
autoScale = false;
|
|
48795
|
+
} else {
|
|
48796
|
+
autoScaleFactor = s * 0.9;
|
|
48797
|
+
reportedASF = s;
|
|
48798
|
+
}
|
|
48799
|
+
pos++;
|
|
48800
|
+
}
|
|
48801
|
+
const trace = {
|
|
48802
|
+
x: xData,
|
|
48803
|
+
y: yData,
|
|
48804
|
+
z: zData,
|
|
48805
|
+
u: uData,
|
|
48806
|
+
v: vData,
|
|
48807
|
+
w: wData,
|
|
48808
|
+
showArrowHead: true
|
|
48809
|
+
};
|
|
48810
|
+
while (pos < args.length && isStringArg(args[pos]) && !isQuiverNameValueKey(args[pos])) {
|
|
48811
|
+
const s = getStringIfString(args[pos]);
|
|
48812
|
+
if (s === void 0) break;
|
|
48813
|
+
if (s === "off") {
|
|
48814
|
+
autoScale = false;
|
|
48815
|
+
pos++;
|
|
48816
|
+
continue;
|
|
48817
|
+
}
|
|
48818
|
+
if (s === "filled") {
|
|
48819
|
+
trace.markerFilled = true;
|
|
48820
|
+
pos++;
|
|
48821
|
+
continue;
|
|
48822
|
+
}
|
|
48823
|
+
const spec = parseLineSpec(s);
|
|
48824
|
+
if (spec) {
|
|
48825
|
+
if (spec.color) trace.color = COLOR_SHORT[spec.color];
|
|
48826
|
+
if (spec.lineStyle) trace.lineStyle = spec.lineStyle;
|
|
48827
|
+
if (spec.marker) {
|
|
48828
|
+
trace.marker = spec.marker;
|
|
48829
|
+
trace.showArrowHead = false;
|
|
48830
|
+
}
|
|
48831
|
+
pos++;
|
|
48832
|
+
continue;
|
|
48833
|
+
}
|
|
48834
|
+
const c = resolveColor(s);
|
|
48835
|
+
if (c) {
|
|
48836
|
+
trace.color = c;
|
|
48837
|
+
pos++;
|
|
48838
|
+
continue;
|
|
48839
|
+
}
|
|
48840
|
+
break;
|
|
48841
|
+
}
|
|
48842
|
+
while (pos < args.length) {
|
|
48843
|
+
const key = isQuiverNameValueKey(args[pos]);
|
|
48844
|
+
if (!key) break;
|
|
48845
|
+
pos++;
|
|
48846
|
+
if (pos >= args.length) break;
|
|
48847
|
+
const value = args[pos++];
|
|
48848
|
+
switch (key) {
|
|
48849
|
+
case "color": {
|
|
48850
|
+
const c = resolveColor(value);
|
|
48851
|
+
if (c) trace.color = c;
|
|
48852
|
+
break;
|
|
48853
|
+
}
|
|
48854
|
+
case "linestyle":
|
|
48855
|
+
trace.lineStyle = getStringValue(value);
|
|
48856
|
+
break;
|
|
48857
|
+
case "linewidth":
|
|
48858
|
+
trace.lineWidth = typeof value === "number" ? value : toNumber(value);
|
|
48859
|
+
break;
|
|
48860
|
+
case "marker": {
|
|
48861
|
+
const s = getStringValue(value);
|
|
48862
|
+
trace.marker = s === "none" ? void 0 : s;
|
|
48863
|
+
break;
|
|
48864
|
+
}
|
|
48865
|
+
case "showarrowhead": {
|
|
48866
|
+
const s = getStringValue(value).toLowerCase();
|
|
48867
|
+
trace.showArrowHead = !(s === "off" || s === "false" || s === "0");
|
|
48868
|
+
break;
|
|
48869
|
+
}
|
|
48870
|
+
case "autoscale": {
|
|
48871
|
+
const s = getStringValue(value).toLowerCase();
|
|
48872
|
+
autoScale = !(s === "off" || s === "false" || s === "0");
|
|
48873
|
+
break;
|
|
48874
|
+
}
|
|
48875
|
+
case "autoscalefactor": {
|
|
48876
|
+
const n = typeof value === "number" ? value : toNumber(value);
|
|
48877
|
+
autoScaleFactor = n * 0.9;
|
|
48878
|
+
reportedASF = n;
|
|
48879
|
+
break;
|
|
48880
|
+
}
|
|
48881
|
+
}
|
|
48882
|
+
}
|
|
48883
|
+
trace.autoScale = autoScale;
|
|
48884
|
+
trace.autoScaleFactor = reportedASF;
|
|
48885
|
+
if (autoScale) {
|
|
48886
|
+
const factor = computeQuiver3AutoScale(
|
|
48887
|
+
xData,
|
|
48888
|
+
yData,
|
|
48889
|
+
zData,
|
|
48890
|
+
uData,
|
|
48891
|
+
vData,
|
|
48892
|
+
wData,
|
|
48893
|
+
autoScaleFactor
|
|
48894
|
+
);
|
|
48895
|
+
if (factor !== 1) {
|
|
48896
|
+
trace.u = uData.map((x) => x * factor);
|
|
48897
|
+
trace.v = vData.map((x) => x * factor);
|
|
48898
|
+
trace.w = wData.map((x) => x * factor);
|
|
48899
|
+
}
|
|
48900
|
+
}
|
|
48901
|
+
return trace;
|
|
48902
|
+
}
|
|
48903
|
+
function computeQuiver3AutoScale(x, y, z, u, v, w, factor) {
|
|
48904
|
+
const n = u.length;
|
|
48905
|
+
if (n === 0) return 1;
|
|
48906
|
+
const range2 = (a) => {
|
|
48907
|
+
let lo = Infinity;
|
|
48908
|
+
let hi = -Infinity;
|
|
48909
|
+
for (const t of a) {
|
|
48910
|
+
if (isFinite(t)) {
|
|
48911
|
+
if (t < lo) lo = t;
|
|
48912
|
+
if (t > hi) hi = t;
|
|
48913
|
+
}
|
|
48914
|
+
}
|
|
48915
|
+
return hi > lo ? hi - lo : 0;
|
|
48916
|
+
};
|
|
48917
|
+
const xr = range2(x);
|
|
48918
|
+
const yr = range2(y);
|
|
48919
|
+
const zr = range2(z);
|
|
48920
|
+
const dims = [xr, yr, zr].filter((d) => d > 0);
|
|
48921
|
+
let spacing;
|
|
48922
|
+
if (dims.length === 3) spacing = Math.cbrt(xr * yr * zr / n);
|
|
48923
|
+
else if (dims.length === 2) spacing = Math.sqrt(dims[0] * dims[1] / n);
|
|
48924
|
+
else if (dims.length === 1) spacing = dims[0] / Math.max(1, n - 1);
|
|
48925
|
+
else spacing = 1;
|
|
48926
|
+
spacing = spacing || 1;
|
|
48927
|
+
let maxMag = 0;
|
|
48928
|
+
for (let i = 0; i < n; i++) {
|
|
48929
|
+
const m = Math.sqrt(u[i] * u[i] + v[i] * v[i] + w[i] * w[i]);
|
|
48930
|
+
if (isFinite(m) && m > maxMag) maxMag = m;
|
|
48931
|
+
}
|
|
48932
|
+
if (maxMag === 0) return 1;
|
|
48933
|
+
return factor * spacing / maxMag;
|
|
48934
|
+
}
|
|
48428
48935
|
|
|
48429
48936
|
// src/numbl-core/runtime/syncChannel.ts
|
|
48430
48937
|
var syncSleepWarned = false;
|
|
@@ -48516,6 +49023,9 @@ function plotInstr(plotInstructions, instr) {
|
|
|
48516
49023
|
case "clf":
|
|
48517
49024
|
plotInstructions.push({ type: instr.type });
|
|
48518
49025
|
break;
|
|
49026
|
+
case "cla":
|
|
49027
|
+
plotInstructions.push({ type: "cla", reset: instr.reset });
|
|
49028
|
+
break;
|
|
48519
49029
|
case "set_subplot":
|
|
48520
49030
|
plotInstructions.push({
|
|
48521
49031
|
type: "set_subplot",
|
|
@@ -48600,6 +49110,10 @@ function surfCall(plotInstructions, args) {
|
|
|
48600
49110
|
const trace = parseSurfArgs(args);
|
|
48601
49111
|
plotInstructions.push({ type: "surf", trace });
|
|
48602
49112
|
}
|
|
49113
|
+
function surfaceCall(plotInstructions, args) {
|
|
49114
|
+
const trace = parseSurfArgs(args);
|
|
49115
|
+
plotInstructions.push({ type: "surface", trace });
|
|
49116
|
+
}
|
|
48603
49117
|
function imagescCall(plotInstructions, args) {
|
|
48604
49118
|
const trace = parseImagescArgs(args);
|
|
48605
49119
|
plotInstructions.push({ type: "imagesc", trace });
|
|
@@ -48852,6 +49366,10 @@ function quiverCall(plotInstructions, args) {
|
|
|
48852
49366
|
plotInstructions.push({ type: "quiver", traces });
|
|
48853
49367
|
}
|
|
48854
49368
|
}
|
|
49369
|
+
function quiver3Call(plotInstructions, args) {
|
|
49370
|
+
const trace = parseQuiver3Args(args);
|
|
49371
|
+
plotInstructions.push({ type: "quiver3", trace });
|
|
49372
|
+
}
|
|
48855
49373
|
function legendCall(plotInstructions, args) {
|
|
48856
49374
|
const labels = [];
|
|
48857
49375
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -49100,6 +49618,9 @@ function dispatchPlotBuiltin(name, args, instructions, state) {
|
|
|
49100
49618
|
case "surf":
|
|
49101
49619
|
surfCall(instructions, args);
|
|
49102
49620
|
return true;
|
|
49621
|
+
case "surface":
|
|
49622
|
+
surfaceCall(instructions, args);
|
|
49623
|
+
return true;
|
|
49103
49624
|
case "scatter":
|
|
49104
49625
|
scatterCall(instructions, args);
|
|
49105
49626
|
return true;
|
|
@@ -49179,6 +49700,9 @@ function dispatchPlotBuiltin(name, args, instructions, state) {
|
|
|
49179
49700
|
case "quiver":
|
|
49180
49701
|
quiverCall(instructions, args);
|
|
49181
49702
|
return true;
|
|
49703
|
+
case "quiver3":
|
|
49704
|
+
quiver3Call(instructions, args);
|
|
49705
|
+
return true;
|
|
49182
49706
|
case "view":
|
|
49183
49707
|
viewCall(instructions, args);
|
|
49184
49708
|
return true;
|
|
@@ -49244,6 +49768,18 @@ function dispatchPlotBuiltin(name, args, instructions, state) {
|
|
|
49244
49768
|
case "clf":
|
|
49245
49769
|
plotInstr(instructions, { type: "clf" });
|
|
49246
49770
|
return true;
|
|
49771
|
+
case "cla": {
|
|
49772
|
+
let reset = false;
|
|
49773
|
+
for (const a of args) {
|
|
49774
|
+
try {
|
|
49775
|
+
if (toString(a).toLowerCase().replace(/^["']|["']$/g, "") === "reset")
|
|
49776
|
+
reset = true;
|
|
49777
|
+
} catch {
|
|
49778
|
+
}
|
|
49779
|
+
}
|
|
49780
|
+
plotInstr(instructions, { type: "cla", reset });
|
|
49781
|
+
return true;
|
|
49782
|
+
}
|
|
49247
49783
|
case "shading": {
|
|
49248
49784
|
if (args.length > 0) {
|
|
49249
49785
|
plotInstr(instructions, { type: "set_shading", shading: args[0] });
|
|
@@ -49421,6 +49957,7 @@ var PLOT_DISPATCH_NAMES = [
|
|
|
49421
49957
|
"plot",
|
|
49422
49958
|
"plot3",
|
|
49423
49959
|
"surf",
|
|
49960
|
+
"surface",
|
|
49424
49961
|
"scatter",
|
|
49425
49962
|
"imagesc",
|
|
49426
49963
|
"pcolor",
|
|
@@ -49448,6 +49985,7 @@ var PLOT_DISPATCH_NAMES = [
|
|
|
49448
49985
|
"donutchart",
|
|
49449
49986
|
"heatmap",
|
|
49450
49987
|
"quiver",
|
|
49988
|
+
"quiver3",
|
|
49451
49989
|
"view",
|
|
49452
49990
|
"legend",
|
|
49453
49991
|
"figure",
|
|
@@ -49463,6 +50001,7 @@ var PLOT_DISPATCH_NAMES = [
|
|
|
49463
50001
|
"grid",
|
|
49464
50002
|
"close",
|
|
49465
50003
|
"clf",
|
|
50004
|
+
"cla",
|
|
49466
50005
|
"shading",
|
|
49467
50006
|
"colorbar",
|
|
49468
50007
|
"colormap",
|
|
@@ -49986,6 +50525,7 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
49986
50525
|
"plot",
|
|
49987
50526
|
"plot3",
|
|
49988
50527
|
"surf",
|
|
50528
|
+
"surface",
|
|
49989
50529
|
"scatter",
|
|
49990
50530
|
"imagesc",
|
|
49991
50531
|
"pcolor",
|
|
@@ -50015,6 +50555,7 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
50015
50555
|
"donutchart",
|
|
50016
50556
|
"heatmap",
|
|
50017
50557
|
"quiver",
|
|
50558
|
+
"quiver3",
|
|
50018
50559
|
"streamline",
|
|
50019
50560
|
"stream2",
|
|
50020
50561
|
"ishold",
|
|
@@ -50032,6 +50573,7 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
50032
50573
|
"sgtitle",
|
|
50033
50574
|
"shading",
|
|
50034
50575
|
"clf",
|
|
50576
|
+
"cla",
|
|
50035
50577
|
"colormap",
|
|
50036
50578
|
"view",
|
|
50037
50579
|
"zlabel",
|
|
@@ -50924,13 +51466,21 @@ function registerSpecialBuiltins(rt) {
|
|
|
50924
51466
|
}
|
|
50925
51467
|
});
|
|
50926
51468
|
registerSpecialVoid("delete", (args) => {
|
|
50927
|
-
const io = requireFileIO();
|
|
50928
|
-
if (!io.deleteFile)
|
|
50929
|
-
throw new RuntimeError("delete is not available in this environment");
|
|
50930
51469
|
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
50931
51470
|
if (margs.length < 1)
|
|
50932
51471
|
throw new RuntimeError("delete requires at least 1 argument");
|
|
50933
51472
|
for (const arg of margs) {
|
|
51473
|
+
if (isRuntimeGraphicsHandle(arg)) {
|
|
51474
|
+
const instr = arg._trace.__instruction;
|
|
51475
|
+
if (instr) {
|
|
51476
|
+
const idx = rt.plotInstructions.indexOf(instr);
|
|
51477
|
+
if (idx >= 0) rt.plotInstructions.splice(idx, 1);
|
|
51478
|
+
}
|
|
51479
|
+
continue;
|
|
51480
|
+
}
|
|
51481
|
+
const io = requireFileIO();
|
|
51482
|
+
if (!io.deleteFile)
|
|
51483
|
+
throw new RuntimeError("delete is not available in this environment");
|
|
50934
51484
|
io.deleteFile(toString(arg));
|
|
50935
51485
|
}
|
|
50936
51486
|
});
|
|
@@ -51399,7 +51949,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
51399
51949
|
return nargout >= 1 ? RTV.num(1) : void 0;
|
|
51400
51950
|
});
|
|
51401
51951
|
}
|
|
51402
|
-
const PLOT_VOID = ["hold", "grid", "shading"];
|
|
51952
|
+
const PLOT_VOID = ["hold", "grid", "shading", "cla"];
|
|
51403
51953
|
for (const name of PLOT_VOID) {
|
|
51404
51954
|
registerSpecialVoid(name, (args) => {
|
|
51405
51955
|
dispatchPlotBuiltin(
|
|
@@ -52240,7 +52790,8 @@ var PLOT_DISPATCH_NAMES_JIT = /* @__PURE__ */ new Set([
|
|
|
52240
52790
|
"piechart",
|
|
52241
52791
|
"donutchart",
|
|
52242
52792
|
"heatmap",
|
|
52243
|
-
"quiver"
|
|
52793
|
+
"quiver",
|
|
52794
|
+
"quiver3"
|
|
52244
52795
|
]);
|
|
52245
52796
|
function dispatchPlotCall(rt, name, args) {
|
|
52246
52797
|
if (PLOT_DISPATCH_NAMES_JIT.has(name)) {
|
|
@@ -53223,45 +53774,70 @@ function classInstanceParenIndex(rt, mv, base, indices, nargout, skipSubsref) {
|
|
|
53223
53774
|
}
|
|
53224
53775
|
throw new RuntimeError(`Index exceeds class instance dimensions`);
|
|
53225
53776
|
}
|
|
53777
|
+
function resolveObjSubscript(raw, dimSize) {
|
|
53778
|
+
if (raw === COLON_SENTINEL) {
|
|
53779
|
+
return Array.from({ length: dimSize }, (_, i) => i);
|
|
53780
|
+
}
|
|
53781
|
+
if (typeof raw === "number") return [Math.round(raw) - 1];
|
|
53782
|
+
const rv = ensureRuntimeValue(raw);
|
|
53783
|
+
if (isRuntimeNumber(rv)) return [Math.round(toNumber(rv)) - 1];
|
|
53784
|
+
if (isRuntimeLogical(rv)) return rv ? [0] : [];
|
|
53785
|
+
if (isRuntimeTensor(rv)) {
|
|
53786
|
+
if (rv._isLogical) {
|
|
53787
|
+
const out = [];
|
|
53788
|
+
for (let k = 0; k < rv.data.length; k++) if (rv.data[k]) out.push(k);
|
|
53789
|
+
return out;
|
|
53790
|
+
}
|
|
53791
|
+
return Array.from(rv.data, (x) => Math.round(x) - 1);
|
|
53792
|
+
}
|
|
53793
|
+
throw new RuntimeError("Invalid index type for class instance array");
|
|
53794
|
+
}
|
|
53795
|
+
function makeObjResult(className, elements, shape) {
|
|
53796
|
+
if (elements.length === 1) return elements[0];
|
|
53797
|
+
return {
|
|
53798
|
+
kind: "class_instance_array",
|
|
53799
|
+
className,
|
|
53800
|
+
elements,
|
|
53801
|
+
shape
|
|
53802
|
+
};
|
|
53803
|
+
}
|
|
53226
53804
|
function classInstanceArrayParenIndex(mv, indices) {
|
|
53805
|
+
const [rows, cols] = mv.shape;
|
|
53806
|
+
const total = mv.elements.length;
|
|
53807
|
+
if (indices.length === 2) {
|
|
53808
|
+
const ri = resolveObjSubscript(indices[0], rows);
|
|
53809
|
+
const ci = resolveObjSubscript(indices[1], cols);
|
|
53810
|
+
const selected2 = [];
|
|
53811
|
+
for (const j of ci) {
|
|
53812
|
+
if (j < 0 || j >= cols)
|
|
53813
|
+
throw new RuntimeError("Index exceeds array bounds");
|
|
53814
|
+
for (const i of ri) {
|
|
53815
|
+
if (i < 0 || i >= rows)
|
|
53816
|
+
throw new RuntimeError("Index exceeds array bounds");
|
|
53817
|
+
selected2.push(mv.elements[j * rows + i]);
|
|
53818
|
+
}
|
|
53819
|
+
}
|
|
53820
|
+
return makeObjResult(mv.className, selected2, [ri.length, ci.length]);
|
|
53821
|
+
}
|
|
53227
53822
|
if (indices.length !== 1) {
|
|
53228
53823
|
throw new RuntimeError(
|
|
53229
|
-
"Class instance arrays
|
|
53824
|
+
"Class instance arrays support one- or two-subscript indexing"
|
|
53230
53825
|
);
|
|
53231
53826
|
}
|
|
53232
53827
|
const idx = indices[0];
|
|
53233
53828
|
if (idx === COLON_SENTINEL) {
|
|
53234
|
-
return mv;
|
|
53829
|
+
return makeObjResult(mv.className, mv.elements.slice(), [total, 1]);
|
|
53235
53830
|
}
|
|
53236
|
-
|
|
53237
|
-
|
|
53238
|
-
|
|
53831
|
+
const linear = resolveObjSubscript(idx, total);
|
|
53832
|
+
const selected = [];
|
|
53833
|
+
for (const i of linear) {
|
|
53834
|
+
if (i < 0 || i >= total)
|
|
53239
53835
|
throw new RuntimeError("Index exceeds array bounds");
|
|
53240
|
-
|
|
53241
|
-
}
|
|
53242
|
-
const rv = ensureRuntimeValue(idx);
|
|
53243
|
-
if (isRuntimeLogical(rv)) {
|
|
53244
|
-
const i = rv ? 0 : -1;
|
|
53245
|
-
if (i < 0 || i >= mv.elements.length)
|
|
53246
|
-
throw new RuntimeError("Index exceeds array bounds");
|
|
53247
|
-
return mv.elements[i];
|
|
53248
|
-
}
|
|
53249
|
-
if (isRuntimeTensor(rv)) {
|
|
53250
|
-
const selected = [];
|
|
53251
|
-
for (let k = 0; k < rv.data.length; k++) {
|
|
53252
|
-
const i = Math.round(rv.data[k]) - 1;
|
|
53253
|
-
if (i < 0 || i >= mv.elements.length)
|
|
53254
|
-
throw new RuntimeError("Index exceeds array bounds");
|
|
53255
|
-
selected.push(mv.elements[i]);
|
|
53256
|
-
}
|
|
53257
|
-
if (selected.length === 1) return selected[0];
|
|
53258
|
-
return {
|
|
53259
|
-
kind: "class_instance_array",
|
|
53260
|
-
className: mv.className,
|
|
53261
|
-
elements: selected
|
|
53262
|
-
};
|
|
53836
|
+
selected.push(mv.elements[i]);
|
|
53263
53837
|
}
|
|
53264
|
-
|
|
53838
|
+
const isColumn = cols === 1 && rows !== 1;
|
|
53839
|
+
const shape = isColumn ? [selected.length, 1] : [1, selected.length];
|
|
53840
|
+
return makeObjResult(mv.className, selected, shape);
|
|
53265
53841
|
}
|
|
53266
53842
|
function resolveIndicesForClassInstance(rt, mv, base, indices) {
|
|
53267
53843
|
const numIndices = indices.length;
|
|
@@ -53958,6 +54534,43 @@ var Runtime = class _Runtime {
|
|
|
53958
54534
|
return RTV.dummyHandle();
|
|
53959
54535
|
}
|
|
53960
54536
|
};
|
|
54537
|
+
const contourOverride = (filled) => (_nargout, args) => {
|
|
54538
|
+
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
54539
|
+
contourCall(this.plotInstructions, margs, filled);
|
|
54540
|
+
if (_nargout < 1) return void 0;
|
|
54541
|
+
const last = this.plotInstructions[this.plotInstructions.length - 1];
|
|
54542
|
+
if (!last || last.type !== "contour") return RTV.dummyHandle();
|
|
54543
|
+
const trace = last.trace;
|
|
54544
|
+
const cm = computeContourMatrix(trace);
|
|
54545
|
+
const C = RTV.tensor(allocFloat64Array(cm.data), [2, cm.n]);
|
|
54546
|
+
if (_nargout < 2) return C;
|
|
54547
|
+
const H2 = RTV.graphicsHandle(
|
|
54548
|
+
{
|
|
54549
|
+
LineWidth: trace.lineWidth ?? 0.5,
|
|
54550
|
+
LineStyle: trace.lineStyle ?? "-",
|
|
54551
|
+
LineColor: trace.lineColor ?? "flat",
|
|
54552
|
+
LevelList: cm.levelList,
|
|
54553
|
+
__instruction: last
|
|
54554
|
+
},
|
|
54555
|
+
"contour"
|
|
54556
|
+
);
|
|
54557
|
+
return [C, H2];
|
|
54558
|
+
};
|
|
54559
|
+
this.builtins["contour"] = contourOverride(false);
|
|
54560
|
+
this.builtins["contourf"] = contourOverride(true);
|
|
54561
|
+
this.builtins["quiver3"] = (_nargout, args) => {
|
|
54562
|
+
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
54563
|
+
quiver3Call(this.plotInstructions, margs);
|
|
54564
|
+
if (_nargout < 1) return void 0;
|
|
54565
|
+
const last = this.plotInstructions[this.plotInstructions.length - 1];
|
|
54566
|
+
if (last && last.type === "quiver3") {
|
|
54567
|
+
return RTV.graphicsHandle(
|
|
54568
|
+
last.trace,
|
|
54569
|
+
"quiver3"
|
|
54570
|
+
);
|
|
54571
|
+
}
|
|
54572
|
+
return RTV.dummyHandle();
|
|
54573
|
+
};
|
|
53961
54574
|
this.builtins["fplot"] = (_nargout, args) => {
|
|
53962
54575
|
fplotCall(this, this.plotInstructions, args.map(ensureRuntimeValue));
|
|
53963
54576
|
};
|
|
@@ -54505,14 +55118,15 @@ var Runtime = class _Runtime {
|
|
|
54505
55118
|
transpose(v) {
|
|
54506
55119
|
if (typeof v !== "number") {
|
|
54507
55120
|
const mv = ensureRuntimeValue(v);
|
|
54508
|
-
if (isRuntimeClassInstance(mv)
|
|
55121
|
+
if (isRuntimeClassInstance(mv) || isRuntimeClassInstanceArray(mv))
|
|
55122
|
+
return this.dispatch("transpose", 1, [v]);
|
|
54509
55123
|
}
|
|
54510
55124
|
return transpose(v);
|
|
54511
55125
|
}
|
|
54512
55126
|
ctranspose(v) {
|
|
54513
55127
|
if (typeof v !== "number") {
|
|
54514
55128
|
const mv = ensureRuntimeValue(v);
|
|
54515
|
-
if (isRuntimeClassInstance(mv))
|
|
55129
|
+
if (isRuntimeClassInstance(mv) || isRuntimeClassInstanceArray(mv))
|
|
54516
55130
|
return this.dispatch("ctranspose", 1, [v]);
|
|
54517
55131
|
}
|
|
54518
55132
|
return ctranspose(v);
|
|
@@ -54596,7 +55210,9 @@ var Runtime = class _Runtime {
|
|
|
54596
55210
|
const mvals = flat.map(
|
|
54597
55211
|
(e) => typeof e === "number" ? null : ensureRuntimeValue(e)
|
|
54598
55212
|
);
|
|
54599
|
-
if (mvals.some(
|
|
55213
|
+
if (mvals.some(
|
|
55214
|
+
(v) => v && (isRuntimeClassInstance(v) || isRuntimeClassInstanceArray(v))
|
|
55215
|
+
)) {
|
|
54600
55216
|
if (this._classHasMethod(mvals, "horzcat")) {
|
|
54601
55217
|
return this.dispatch("horzcat", 1, flat);
|
|
54602
55218
|
}
|
|
@@ -54609,7 +55225,9 @@ var Runtime = class _Runtime {
|
|
|
54609
55225
|
const mvals = rows.map(
|
|
54610
55226
|
(r) => typeof r === "number" ? null : ensureRuntimeValue(r)
|
|
54611
55227
|
);
|
|
54612
|
-
if (mvals.some(
|
|
55228
|
+
if (mvals.some(
|
|
55229
|
+
(v) => v && (isRuntimeClassInstance(v) || isRuntimeClassInstanceArray(v))
|
|
55230
|
+
)) {
|
|
54613
55231
|
if (this._classHasMethod(mvals, "vertcat")) {
|
|
54614
55232
|
return this.dispatch("vertcat", 1, rows);
|
|
54615
55233
|
}
|
|
@@ -54621,7 +55239,7 @@ var Runtime = class _Runtime {
|
|
|
54621
55239
|
_classHasMethod(mvals, methodName) {
|
|
54622
55240
|
if (!this.resolveClassMethod) return false;
|
|
54623
55241
|
for (const v of mvals) {
|
|
54624
|
-
if (v && isRuntimeClassInstance(v)) {
|
|
55242
|
+
if (v && (isRuntimeClassInstance(v) || isRuntimeClassInstanceArray(v))) {
|
|
54625
55243
|
if (this.resolveClassMethod(v.className, methodName) !== null) {
|
|
54626
55244
|
return true;
|
|
54627
55245
|
}
|
|
@@ -54932,31 +55550,66 @@ function buildStackField(e) {
|
|
|
54932
55550
|
}
|
|
54933
55551
|
return RTV.structArray(fieldNames, elements);
|
|
54934
55552
|
}
|
|
54935
|
-
function
|
|
54936
|
-
const
|
|
54937
|
-
|
|
54938
|
-
|
|
54939
|
-
|
|
54940
|
-
|
|
54941
|
-
|
|
54942
|
-
|
|
54943
|
-
|
|
55553
|
+
function asObjArrayParts(item) {
|
|
55554
|
+
const rv = ensureRuntimeValue(item);
|
|
55555
|
+
if (isRuntimeClassInstance(rv))
|
|
55556
|
+
return { rows: 1, cols: 1, elements: [rv], className: rv.className };
|
|
55557
|
+
if (isRuntimeClassInstanceArray(rv))
|
|
55558
|
+
return {
|
|
55559
|
+
rows: rv.shape[0],
|
|
55560
|
+
cols: rv.shape[1],
|
|
55561
|
+
elements: rv.elements,
|
|
55562
|
+
className: rv.className
|
|
55563
|
+
};
|
|
55564
|
+
if (isRuntimeTensor(rv) && rv.data.length === 0) return null;
|
|
55565
|
+
throw new RuntimeError(`Cannot concatenate ${kstr(rv)} with class instances`);
|
|
55566
|
+
}
|
|
55567
|
+
function objColumn(p2, j) {
|
|
55568
|
+
return p2.elements.slice(j * p2.rows, j * p2.rows + p2.rows);
|
|
55569
|
+
}
|
|
55570
|
+
function defaultClassInstanceHorzcat(items) {
|
|
55571
|
+
const parts = items.map(asObjArrayParts).filter((p2) => p2 !== null && p2.elements.length > 0);
|
|
55572
|
+
if (parts.length === 0)
|
|
55573
|
+
throw new RuntimeError("Cannot concatenate empty class instances");
|
|
55574
|
+
const rows = parts[0].rows;
|
|
55575
|
+
let cols = 0;
|
|
55576
|
+
const elements = [];
|
|
55577
|
+
for (const p2 of parts) {
|
|
55578
|
+
if (p2.rows !== rows)
|
|
54944
55579
|
throw new RuntimeError(
|
|
54945
|
-
|
|
55580
|
+
"Dimensions of arrays being concatenated are not consistent"
|
|
54946
55581
|
);
|
|
54947
|
-
|
|
55582
|
+
elements.push(...p2.elements);
|
|
55583
|
+
cols += p2.cols;
|
|
54948
55584
|
}
|
|
54949
|
-
return out;
|
|
54950
|
-
}
|
|
54951
|
-
function defaultClassInstanceHorzcat(items) {
|
|
54952
|
-
const elements = collectClassInstances(items);
|
|
54953
55585
|
if (elements.length === 1) return elements[0];
|
|
54954
|
-
return new RuntimeClassInstanceArray(
|
|
55586
|
+
return new RuntimeClassInstanceArray(parts[0].className, elements, [
|
|
55587
|
+
rows,
|
|
55588
|
+
cols
|
|
55589
|
+
]);
|
|
54955
55590
|
}
|
|
54956
55591
|
function defaultClassInstanceVertcat(rows) {
|
|
54957
|
-
const
|
|
55592
|
+
const parts = rows.map(asObjArrayParts).filter((p2) => p2 !== null && p2.elements.length > 0);
|
|
55593
|
+
if (parts.length === 0)
|
|
55594
|
+
throw new RuntimeError("Cannot concatenate empty class instances");
|
|
55595
|
+
const cols = parts[0].cols;
|
|
55596
|
+
let totalRows = 0;
|
|
55597
|
+
for (const p2 of parts) {
|
|
55598
|
+
if (p2.cols !== cols)
|
|
55599
|
+
throw new RuntimeError(
|
|
55600
|
+
"Dimensions of arrays being concatenated are not consistent"
|
|
55601
|
+
);
|
|
55602
|
+
totalRows += p2.rows;
|
|
55603
|
+
}
|
|
55604
|
+
const elements = [];
|
|
55605
|
+
for (let j = 0; j < cols; j++) {
|
|
55606
|
+
for (const p2 of parts) elements.push(...objColumn(p2, j));
|
|
55607
|
+
}
|
|
54958
55608
|
if (elements.length === 1) return elements[0];
|
|
54959
|
-
return new RuntimeClassInstanceArray(
|
|
55609
|
+
return new RuntimeClassInstanceArray(parts[0].className, elements, [
|
|
55610
|
+
totalRows,
|
|
55611
|
+
cols
|
|
55612
|
+
]);
|
|
54960
55613
|
}
|
|
54961
55614
|
|
|
54962
55615
|
// src/numbl-core/jsUserFunctions.ts
|
|
@@ -58647,16 +59300,27 @@ function callUserFunction(fn, args, nargout, narginOverride) {
|
|
|
58647
59300
|
const fnEnv = new Environment();
|
|
58648
59301
|
fnEnv.rt = this.rt;
|
|
58649
59302
|
fnEnv.persistentFuncId = `${this.currentFile}:${fn.name}`;
|
|
58650
|
-
const processedArgs = this.processArgumentsBlocks(fn, sharedArgs);
|
|
58651
59303
|
const hasVarargin = fn.params.length > 0 && fn.params[fn.params.length - 1] === "varargin";
|
|
58652
59304
|
const regularParams = hasVarargin ? fn.params.slice(0, -1) : fn.params;
|
|
58653
|
-
|
|
58654
|
-
|
|
58655
|
-
|
|
59305
|
+
let numPositional = regularParams.length;
|
|
59306
|
+
const inputBlocks = (fn.argumentsBlocks ?? []).filter(
|
|
59307
|
+
(b) => b.kind !== "Output"
|
|
59308
|
+
);
|
|
59309
|
+
for (const block of inputBlocks) {
|
|
59310
|
+
for (const e of block.entries) {
|
|
59311
|
+
const dot2 = e.name.indexOf(".");
|
|
59312
|
+
if (dot2 < 0) continue;
|
|
59313
|
+
const idx = fn.params.indexOf(e.name.slice(0, dot2));
|
|
59314
|
+
if (idx >= 0 && idx < numPositional) numPositional = idx;
|
|
59315
|
+
}
|
|
59316
|
+
}
|
|
59317
|
+
for (let i = 0; i < numPositional && i < regularParams.length; i++) {
|
|
59318
|
+
if (i < sharedArgs.length && sharedArgs[i] !== void 0) {
|
|
59319
|
+
fnEnv.set(regularParams[i], ensureRuntimeValue(sharedArgs[i]));
|
|
58656
59320
|
}
|
|
58657
59321
|
}
|
|
58658
59322
|
if (hasVarargin) {
|
|
58659
|
-
const extraArgs =
|
|
59323
|
+
const extraArgs = sharedArgs.slice(regularParams.length).map((a) => ensureRuntimeValue(a));
|
|
58660
59324
|
fnEnv.set("varargin", RTV.cell(extraArgs, [1, extraArgs.length]));
|
|
58661
59325
|
}
|
|
58662
59326
|
fnEnv.set("$nargin", narginOverride ?? args.length);
|
|
@@ -58676,6 +59340,7 @@ function callUserFunction(fn, args, nargout, narginOverride) {
|
|
|
58676
59340
|
this.rt.pushCallFrame(fn.name);
|
|
58677
59341
|
this.rt.pushCleanupScope();
|
|
58678
59342
|
try {
|
|
59343
|
+
this.processArgumentsBlocks(fn, sharedArgs);
|
|
58679
59344
|
this.execStmts(fn.body);
|
|
58680
59345
|
if (fnEnv.persistentFuncId) {
|
|
58681
59346
|
for (const name of fnEnv.persistentNames) {
|
|
@@ -58919,12 +59584,13 @@ function findExternalMethod(classInfo, methodName) {
|
|
|
58919
59584
|
return null;
|
|
58920
59585
|
}
|
|
58921
59586
|
const ast = this.ctx.getCachedAST(mf.fileName);
|
|
59587
|
+
let primary = null;
|
|
58922
59588
|
for (const stmt of ast.body) {
|
|
58923
|
-
if (stmt.type
|
|
58924
|
-
|
|
58925
|
-
|
|
59589
|
+
if (stmt.type !== "Function") continue;
|
|
59590
|
+
if (stmt.name === methodName) return funcDefFromStmt(stmt);
|
|
59591
|
+
if (!primary) primary = funcDefFromStmt(stmt);
|
|
58926
59592
|
}
|
|
58927
|
-
return
|
|
59593
|
+
return primary;
|
|
58928
59594
|
}
|
|
58929
59595
|
function collectClassProperties(classInfo) {
|
|
58930
59596
|
const propertyNames = [...classInfo.propertyNames];
|
|
@@ -58998,7 +59664,7 @@ function evalInLocalScope(codeArg, fileName) {
|
|
|
58998
59664
|
}
|
|
58999
59665
|
function processArgumentsBlocks(fn, args) {
|
|
59000
59666
|
const argBlocks = fn.argumentsBlocks;
|
|
59001
|
-
if (!argBlocks || argBlocks.length === 0) return
|
|
59667
|
+
if (!argBlocks || argBlocks.length === 0) return;
|
|
59002
59668
|
for (const block of argBlocks) {
|
|
59003
59669
|
if (block.kind === "Output") continue;
|
|
59004
59670
|
const entries = block.entries;
|
|
@@ -59019,48 +59685,27 @@ function processArgumentsBlocks(fn, args) {
|
|
|
59019
59685
|
}
|
|
59020
59686
|
return true;
|
|
59021
59687
|
});
|
|
59022
|
-
|
|
59023
|
-
const
|
|
59024
|
-
|
|
59025
|
-
|
|
59026
|
-
|
|
59027
|
-
|
|
59028
|
-
|
|
59029
|
-
|
|
59030
|
-
|
|
59031
|
-
defaults[field] = this.evalExpr(defaultExpr);
|
|
59032
|
-
} catch {
|
|
59033
|
-
}
|
|
59034
|
-
}
|
|
59035
|
-
}
|
|
59036
|
-
const struct = this.rt.buildNameValueStruct(nvArgs, defaults);
|
|
59037
|
-
const paramIdx = fn.params.indexOf(paramName);
|
|
59038
|
-
const targetIdx = paramIdx >= 0 ? paramIdx : nvParamIndex;
|
|
59039
|
-
processedArgs2.length = Math.max(processedArgs2.length, targetIdx + 1);
|
|
59040
|
-
processedArgs2[targetIdx] = struct;
|
|
59041
|
-
}
|
|
59042
|
-
for (let i = 0; i < regularEntries.length; i++) {
|
|
59043
|
-
if (processedArgs2[i] === void 0 && regularEntries[i].defaultValue) {
|
|
59044
|
-
try {
|
|
59045
|
-
processedArgs2[i] = this.evalExpr(regularEntries[i].defaultValue);
|
|
59046
|
-
} catch {
|
|
59047
|
-
}
|
|
59048
|
-
}
|
|
59688
|
+
for (const entry of regularEntries) {
|
|
59689
|
+
const pIdx = fn.params.indexOf(entry.name);
|
|
59690
|
+
if (pIdx < 0) continue;
|
|
59691
|
+
const provided = pIdx < args.length && args[pIdx] !== void 0;
|
|
59692
|
+
if (!provided && entry.defaultValue) {
|
|
59693
|
+
this.env.set(
|
|
59694
|
+
entry.name,
|
|
59695
|
+
ensureRuntimeValue(this.evalExpr(entry.defaultValue))
|
|
59696
|
+
);
|
|
59049
59697
|
}
|
|
59050
|
-
return processedArgs2;
|
|
59051
59698
|
}
|
|
59052
|
-
const
|
|
59053
|
-
|
|
59054
|
-
|
|
59055
|
-
|
|
59056
|
-
|
|
59057
|
-
|
|
59058
|
-
}
|
|
59699
|
+
for (const [paramName, fields] of nvGroups) {
|
|
59700
|
+
const pIdx = fn.params.indexOf(paramName);
|
|
59701
|
+
const nvArgs = args.slice(pIdx >= 0 ? pIdx : args.length);
|
|
59702
|
+
const defaults = {};
|
|
59703
|
+
for (const { field, defaultExpr } of fields) {
|
|
59704
|
+
if (defaultExpr) defaults[field] = this.evalExpr(defaultExpr);
|
|
59059
59705
|
}
|
|
59706
|
+
this.env.set(paramName, this.rt.buildNameValueStruct(nvArgs, defaults));
|
|
59060
59707
|
}
|
|
59061
|
-
return processedArgs;
|
|
59062
59708
|
}
|
|
59063
|
-
return args;
|
|
59064
59709
|
}
|
|
59065
59710
|
|
|
59066
59711
|
// src/numbl-core/interpreter/interpreter.ts
|
|
@@ -86363,15 +87008,18 @@ var Workspace = class _Workspace {
|
|
|
86363
87008
|
);
|
|
86364
87009
|
}
|
|
86365
87010
|
let primary = null;
|
|
87011
|
+
let firstFn = null;
|
|
86366
87012
|
for (const stmt of ast.body) {
|
|
86367
87013
|
if (stmt.type !== "Function") continue;
|
|
87014
|
+
if (!firstFn) firstFn = stmt;
|
|
86368
87015
|
if (stmt.name === methodName) {
|
|
86369
87016
|
primary = stmt;
|
|
86370
87017
|
}
|
|
86371
87018
|
}
|
|
87019
|
+
primary ??= firstFn;
|
|
86372
87020
|
if (!primary) {
|
|
86373
87021
|
throw new UnsupportedConstruct(
|
|
86374
|
-
`external method file '${mf.fileName}' has no function
|
|
87022
|
+
`external method file '${mf.fileName}' has no function`,
|
|
86375
87023
|
info.ast.span
|
|
86376
87024
|
);
|
|
86377
87025
|
}
|