numbl 0.1.2 → 0.1.4
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/README.md +24 -62
- package/binding.gyp +3 -1
- package/dist-cli/cli.js +2109 -893
- package/dist-lib/lib.js +1682 -468
- package/dist-lib/numbl-core/executeCode.d.ts +9 -0
- package/dist-lib/numbl-core/fileIOAdapter.d.ts +14 -2
- package/dist-lib/numbl-core/helpers/prng.d.ts +3 -0
- package/dist-lib/numbl-core/helpers/quadgk.d.ts +32 -0
- package/dist-lib/numbl-core/helpers/string.d.ts +6 -0
- package/dist-lib/numbl-core/interpreter/builtins/index.d.ts +1 -0
- package/dist-lib/numbl-core/interpreter/builtins/logical.d.ts +9 -0
- package/dist-lib/numbl-core/interpreter/builtins/time-system.d.ts +1 -1
- package/dist-lib/numbl-core/interpreter/builtins/types.d.ts +0 -1
- package/dist-lib/numbl-core/interpreter/interpreterSpecialBuiltins.d.ts +3 -0
- package/dist-lib/numbl-core/native/lapack-bridge.d.ts +18 -0
- package/dist-lib/numbl-core/runtime/runtime.d.ts +9 -0
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/native/elemwise.cpp +58 -0
- package/native/numbl_addon.cpp +6 -0
- package/native/numbl_addon_common.h +3 -0
- package/native/randn.cpp +101 -0
- package/native/unary_elemwise.cpp +67 -0
- package/package.json +3 -1
package/dist-cli/cli.js
CHANGED
|
@@ -195,6 +195,179 @@ var kstr = (value) => {
|
|
|
195
195
|
return "unknown";
|
|
196
196
|
};
|
|
197
197
|
|
|
198
|
+
// src/numbl-core/native/lapack-bridge.ts
|
|
199
|
+
var NATIVE_ADDON_EXPECTED_VERSION = 1;
|
|
200
|
+
var _bridge = null;
|
|
201
|
+
function setLapackBridge(bridge) {
|
|
202
|
+
_bridge = bridge;
|
|
203
|
+
}
|
|
204
|
+
function getLapackBridge() {
|
|
205
|
+
return _bridge;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/numbl-core/runtime/constructors.ts
|
|
209
|
+
var RTV = {
|
|
210
|
+
num(value) {
|
|
211
|
+
return value;
|
|
212
|
+
},
|
|
213
|
+
tensor(data, shape, imag) {
|
|
214
|
+
const d = data instanceof FloatXArray ? data : new FloatXArray(data);
|
|
215
|
+
const im2 = imag ? imag instanceof FloatXArray ? imag : new FloatXArray(imag) : void 0;
|
|
216
|
+
const s = [...shape];
|
|
217
|
+
while (s.length > 2 && s[s.length - 1] === 1) s.pop();
|
|
218
|
+
return { kind: "tensor", data: d, imag: im2, shape: s, _rc: 1 };
|
|
219
|
+
},
|
|
220
|
+
/** Fast tensor constructor — data must be FloatXArray, shape already normalized (no trailing singletons). */
|
|
221
|
+
tensorRaw(data, shape) {
|
|
222
|
+
return { kind: "tensor", data, imag: void 0, shape, _rc: 1 };
|
|
223
|
+
},
|
|
224
|
+
/** Create a scalar tensor (1x1) */
|
|
225
|
+
scalar(value) {
|
|
226
|
+
return value;
|
|
227
|
+
},
|
|
228
|
+
/** Create a row vector [1 x n] */
|
|
229
|
+
row(data, imag) {
|
|
230
|
+
const im2 = imag ? new FloatXArray(imag) : void 0;
|
|
231
|
+
return {
|
|
232
|
+
kind: "tensor",
|
|
233
|
+
data: new FloatXArray(data),
|
|
234
|
+
imag: im2,
|
|
235
|
+
shape: [1, data.length],
|
|
236
|
+
_rc: 1
|
|
237
|
+
};
|
|
238
|
+
},
|
|
239
|
+
/** Create a column vector [n x 1] */
|
|
240
|
+
col(data, imag) {
|
|
241
|
+
const im2 = imag ? new FloatXArray(imag) : void 0;
|
|
242
|
+
return {
|
|
243
|
+
kind: "tensor",
|
|
244
|
+
data: new FloatXArray(data),
|
|
245
|
+
imag: im2,
|
|
246
|
+
shape: [data.length, 1],
|
|
247
|
+
_rc: 1
|
|
248
|
+
};
|
|
249
|
+
},
|
|
250
|
+
/** Create a matrix from row-major data */
|
|
251
|
+
matrix(rows, cols, data, imag) {
|
|
252
|
+
const d = data instanceof FloatXArray ? data : new FloatXArray(data);
|
|
253
|
+
const im2 = imag ? imag instanceof FloatXArray ? imag : new FloatXArray(imag) : void 0;
|
|
254
|
+
return { kind: "tensor", data: d, imag: im2, shape: [rows, cols], _rc: 1 };
|
|
255
|
+
},
|
|
256
|
+
string(value) {
|
|
257
|
+
return value;
|
|
258
|
+
},
|
|
259
|
+
char(value) {
|
|
260
|
+
return { kind: "char", value };
|
|
261
|
+
},
|
|
262
|
+
logical(value) {
|
|
263
|
+
return value;
|
|
264
|
+
},
|
|
265
|
+
cell(data, shape) {
|
|
266
|
+
return { kind: "cell", data, shape: [...shape], _rc: 1 };
|
|
267
|
+
},
|
|
268
|
+
struct(fields) {
|
|
269
|
+
const map = fields instanceof Map ? fields : new Map(Object.entries(fields));
|
|
270
|
+
return { kind: "struct", fields: map };
|
|
271
|
+
},
|
|
272
|
+
func(name, impl, captures = []) {
|
|
273
|
+
return { kind: "function", name, impl, captures };
|
|
274
|
+
},
|
|
275
|
+
classInstance(className, propertyNames, isHandleClass2 = false, defaults) {
|
|
276
|
+
const fields = /* @__PURE__ */ new Map();
|
|
277
|
+
for (const name of propertyNames) {
|
|
278
|
+
fields.set(
|
|
279
|
+
name,
|
|
280
|
+
defaults?.get(name) ?? RTV.tensor(new FloatXArray(0), [0, 0])
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
kind: "class_instance",
|
|
285
|
+
className,
|
|
286
|
+
fields,
|
|
287
|
+
isHandleClass: isHandleClass2
|
|
288
|
+
};
|
|
289
|
+
},
|
|
290
|
+
complex(re2, im2) {
|
|
291
|
+
return { kind: "complex_number", re: re2, im: im2 };
|
|
292
|
+
},
|
|
293
|
+
dummyHandle() {
|
|
294
|
+
return { kind: "dummy_handle" };
|
|
295
|
+
},
|
|
296
|
+
structArray(fieldNames, elements) {
|
|
297
|
+
return { kind: "struct_array", fieldNames, elements };
|
|
298
|
+
},
|
|
299
|
+
sparseMatrix(m, n, ir, jc, pr, pi) {
|
|
300
|
+
return { kind: "sparse_matrix", m, n, ir, jc, pr, pi, _rc: 1 };
|
|
301
|
+
},
|
|
302
|
+
dictionary(entries, keyType, valueType) {
|
|
303
|
+
return {
|
|
304
|
+
kind: "dictionary",
|
|
305
|
+
entries: entries ?? /* @__PURE__ */ new Map(),
|
|
306
|
+
keyType,
|
|
307
|
+
valueType
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
var getItemTypeFromRuntimeValue = (value) => {
|
|
312
|
+
if (isRuntimeNumber(value)) {
|
|
313
|
+
return { kind: "Number" };
|
|
314
|
+
}
|
|
315
|
+
if (isRuntimeLogical(value)) {
|
|
316
|
+
return { kind: "Boolean" };
|
|
317
|
+
}
|
|
318
|
+
if (isRuntimeString(value)) {
|
|
319
|
+
return { kind: "String" };
|
|
320
|
+
}
|
|
321
|
+
switch (value.kind) {
|
|
322
|
+
case "complex_number":
|
|
323
|
+
return { kind: "ComplexNumber" };
|
|
324
|
+
case "char":
|
|
325
|
+
return { kind: "Char" };
|
|
326
|
+
case "tensor":
|
|
327
|
+
return {
|
|
328
|
+
kind: "Tensor",
|
|
329
|
+
isComplex: value.imag !== void 0,
|
|
330
|
+
isLogical: value._isLogical || void 0
|
|
331
|
+
};
|
|
332
|
+
case "cell":
|
|
333
|
+
return {
|
|
334
|
+
kind: "Cell",
|
|
335
|
+
elementType: value.data.length > 0 ? getItemTypeFromRuntimeValue(value.data[0]) : { kind: "Unknown" },
|
|
336
|
+
// length: value.shape.reduce((a, b) => a * b, 1),
|
|
337
|
+
length: "unknown"
|
|
338
|
+
// do not include length or we get too many jits
|
|
339
|
+
};
|
|
340
|
+
case "struct": {
|
|
341
|
+
const knownFields = {};
|
|
342
|
+
for (const [k, v] of value.fields) {
|
|
343
|
+
knownFields[k] = getItemTypeFromRuntimeValue(v);
|
|
344
|
+
}
|
|
345
|
+
return { kind: "Struct", knownFields };
|
|
346
|
+
}
|
|
347
|
+
case "function":
|
|
348
|
+
return {
|
|
349
|
+
kind: "Function",
|
|
350
|
+
params: [],
|
|
351
|
+
returns: { kind: "Unknown" }
|
|
352
|
+
};
|
|
353
|
+
case "class_instance":
|
|
354
|
+
return {
|
|
355
|
+
kind: "ClassInstance",
|
|
356
|
+
className: value.className
|
|
357
|
+
};
|
|
358
|
+
case "dummy_handle":
|
|
359
|
+
return { kind: "DummyHandle" };
|
|
360
|
+
case "struct_array":
|
|
361
|
+
return { kind: "Unknown" };
|
|
362
|
+
case "sparse_matrix":
|
|
363
|
+
return { kind: "SparseMatrix", isComplex: value.pi !== void 0 };
|
|
364
|
+
case "dictionary":
|
|
365
|
+
return { kind: "Dictionary" };
|
|
366
|
+
default:
|
|
367
|
+
return { kind: "Unknown" };
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
|
|
198
371
|
// src/numbl-core/interpreter/jit/jitTypes.ts
|
|
199
372
|
function signFromNumber(v) {
|
|
200
373
|
if (v > 0) return "positive";
|
|
@@ -637,169 +810,6 @@ function extractSnippet(source, offset, contextLines = 2) {
|
|
|
637
810
|
return snippetLines.join("\n");
|
|
638
811
|
}
|
|
639
812
|
|
|
640
|
-
// src/numbl-core/runtime/constructors.ts
|
|
641
|
-
var RTV = {
|
|
642
|
-
num(value) {
|
|
643
|
-
return value;
|
|
644
|
-
},
|
|
645
|
-
tensor(data, shape, imag) {
|
|
646
|
-
const d = data instanceof FloatXArray ? data : new FloatXArray(data);
|
|
647
|
-
const im2 = imag ? imag instanceof FloatXArray ? imag : new FloatXArray(imag) : void 0;
|
|
648
|
-
const s = [...shape];
|
|
649
|
-
while (s.length > 2 && s[s.length - 1] === 1) s.pop();
|
|
650
|
-
return { kind: "tensor", data: d, imag: im2, shape: s, _rc: 1 };
|
|
651
|
-
},
|
|
652
|
-
/** Fast tensor constructor — data must be FloatXArray, shape already normalized (no trailing singletons). */
|
|
653
|
-
tensorRaw(data, shape) {
|
|
654
|
-
return { kind: "tensor", data, imag: void 0, shape, _rc: 1 };
|
|
655
|
-
},
|
|
656
|
-
/** Create a scalar tensor (1x1) */
|
|
657
|
-
scalar(value) {
|
|
658
|
-
return value;
|
|
659
|
-
},
|
|
660
|
-
/** Create a row vector [1 x n] */
|
|
661
|
-
row(data, imag) {
|
|
662
|
-
const im2 = imag ? new FloatXArray(imag) : void 0;
|
|
663
|
-
return {
|
|
664
|
-
kind: "tensor",
|
|
665
|
-
data: new FloatXArray(data),
|
|
666
|
-
imag: im2,
|
|
667
|
-
shape: [1, data.length],
|
|
668
|
-
_rc: 1
|
|
669
|
-
};
|
|
670
|
-
},
|
|
671
|
-
/** Create a column vector [n x 1] */
|
|
672
|
-
col(data, imag) {
|
|
673
|
-
const im2 = imag ? new FloatXArray(imag) : void 0;
|
|
674
|
-
return {
|
|
675
|
-
kind: "tensor",
|
|
676
|
-
data: new FloatXArray(data),
|
|
677
|
-
imag: im2,
|
|
678
|
-
shape: [data.length, 1],
|
|
679
|
-
_rc: 1
|
|
680
|
-
};
|
|
681
|
-
},
|
|
682
|
-
/** Create a matrix from row-major data */
|
|
683
|
-
matrix(rows, cols, data, imag) {
|
|
684
|
-
const d = data instanceof FloatXArray ? data : new FloatXArray(data);
|
|
685
|
-
const im2 = imag ? imag instanceof FloatXArray ? imag : new FloatXArray(imag) : void 0;
|
|
686
|
-
return { kind: "tensor", data: d, imag: im2, shape: [rows, cols], _rc: 1 };
|
|
687
|
-
},
|
|
688
|
-
string(value) {
|
|
689
|
-
return value;
|
|
690
|
-
},
|
|
691
|
-
char(value) {
|
|
692
|
-
return { kind: "char", value };
|
|
693
|
-
},
|
|
694
|
-
logical(value) {
|
|
695
|
-
return value;
|
|
696
|
-
},
|
|
697
|
-
cell(data, shape) {
|
|
698
|
-
return { kind: "cell", data, shape: [...shape], _rc: 1 };
|
|
699
|
-
},
|
|
700
|
-
struct(fields) {
|
|
701
|
-
const map = fields instanceof Map ? fields : new Map(Object.entries(fields));
|
|
702
|
-
return { kind: "struct", fields: map };
|
|
703
|
-
},
|
|
704
|
-
func(name, impl, captures = []) {
|
|
705
|
-
return { kind: "function", name, impl, captures };
|
|
706
|
-
},
|
|
707
|
-
classInstance(className, propertyNames, isHandleClass2 = false, defaults) {
|
|
708
|
-
const fields = /* @__PURE__ */ new Map();
|
|
709
|
-
for (const name of propertyNames) {
|
|
710
|
-
fields.set(
|
|
711
|
-
name,
|
|
712
|
-
defaults?.get(name) ?? RTV.tensor(new FloatXArray(0), [0, 0])
|
|
713
|
-
);
|
|
714
|
-
}
|
|
715
|
-
return {
|
|
716
|
-
kind: "class_instance",
|
|
717
|
-
className,
|
|
718
|
-
fields,
|
|
719
|
-
isHandleClass: isHandleClass2
|
|
720
|
-
};
|
|
721
|
-
},
|
|
722
|
-
complex(re2, im2) {
|
|
723
|
-
return { kind: "complex_number", re: re2, im: im2 };
|
|
724
|
-
},
|
|
725
|
-
dummyHandle() {
|
|
726
|
-
return { kind: "dummy_handle" };
|
|
727
|
-
},
|
|
728
|
-
structArray(fieldNames, elements) {
|
|
729
|
-
return { kind: "struct_array", fieldNames, elements };
|
|
730
|
-
},
|
|
731
|
-
sparseMatrix(m, n, ir, jc, pr, pi) {
|
|
732
|
-
return { kind: "sparse_matrix", m, n, ir, jc, pr, pi, _rc: 1 };
|
|
733
|
-
},
|
|
734
|
-
dictionary(entries, keyType, valueType) {
|
|
735
|
-
return {
|
|
736
|
-
kind: "dictionary",
|
|
737
|
-
entries: entries ?? /* @__PURE__ */ new Map(),
|
|
738
|
-
keyType,
|
|
739
|
-
valueType
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
};
|
|
743
|
-
var getItemTypeFromRuntimeValue = (value) => {
|
|
744
|
-
if (isRuntimeNumber(value)) {
|
|
745
|
-
return { kind: "Number" };
|
|
746
|
-
}
|
|
747
|
-
if (isRuntimeLogical(value)) {
|
|
748
|
-
return { kind: "Boolean" };
|
|
749
|
-
}
|
|
750
|
-
if (isRuntimeString(value)) {
|
|
751
|
-
return { kind: "String" };
|
|
752
|
-
}
|
|
753
|
-
switch (value.kind) {
|
|
754
|
-
case "complex_number":
|
|
755
|
-
return { kind: "ComplexNumber" };
|
|
756
|
-
case "char":
|
|
757
|
-
return { kind: "Char" };
|
|
758
|
-
case "tensor":
|
|
759
|
-
return {
|
|
760
|
-
kind: "Tensor",
|
|
761
|
-
isComplex: value.imag !== void 0,
|
|
762
|
-
isLogical: value._isLogical || void 0
|
|
763
|
-
};
|
|
764
|
-
case "cell":
|
|
765
|
-
return {
|
|
766
|
-
kind: "Cell",
|
|
767
|
-
elementType: value.data.length > 0 ? getItemTypeFromRuntimeValue(value.data[0]) : { kind: "Unknown" },
|
|
768
|
-
// length: value.shape.reduce((a, b) => a * b, 1),
|
|
769
|
-
length: "unknown"
|
|
770
|
-
// do not include length or we get too many jits
|
|
771
|
-
};
|
|
772
|
-
case "struct": {
|
|
773
|
-
const knownFields = {};
|
|
774
|
-
for (const [k, v] of value.fields) {
|
|
775
|
-
knownFields[k] = getItemTypeFromRuntimeValue(v);
|
|
776
|
-
}
|
|
777
|
-
return { kind: "Struct", knownFields };
|
|
778
|
-
}
|
|
779
|
-
case "function":
|
|
780
|
-
return {
|
|
781
|
-
kind: "Function",
|
|
782
|
-
params: [],
|
|
783
|
-
returns: { kind: "Unknown" }
|
|
784
|
-
};
|
|
785
|
-
case "class_instance":
|
|
786
|
-
return {
|
|
787
|
-
kind: "ClassInstance",
|
|
788
|
-
className: value.className
|
|
789
|
-
};
|
|
790
|
-
case "dummy_handle":
|
|
791
|
-
return { kind: "DummyHandle" };
|
|
792
|
-
case "struct_array":
|
|
793
|
-
return { kind: "Unknown" };
|
|
794
|
-
case "sparse_matrix":
|
|
795
|
-
return { kind: "SparseMatrix", isComplex: value.pi !== void 0 };
|
|
796
|
-
case "dictionary":
|
|
797
|
-
return { kind: "Dictionary" };
|
|
798
|
-
default:
|
|
799
|
-
return { kind: "Unknown" };
|
|
800
|
-
}
|
|
801
|
-
};
|
|
802
|
-
|
|
803
813
|
// src/numbl-core/runtime/utils.ts
|
|
804
814
|
function tensorSize2D(t) {
|
|
805
815
|
const s = t.shape;
|
|
@@ -1718,6 +1728,28 @@ function binaryNumberOnly(argTypes) {
|
|
|
1718
1728
|
return null;
|
|
1719
1729
|
return [{ kind: "number" }];
|
|
1720
1730
|
}
|
|
1731
|
+
var nativeUnaryOpCode = /* @__PURE__ */ new Map([
|
|
1732
|
+
[Math.exp, 0],
|
|
1733
|
+
[Math.log, 1],
|
|
1734
|
+
[Math.log2, 2],
|
|
1735
|
+
[Math.log10, 3],
|
|
1736
|
+
[Math.sqrt, 4],
|
|
1737
|
+
[Math.abs, 5],
|
|
1738
|
+
[Math.floor, 6],
|
|
1739
|
+
[Math.ceil, 7],
|
|
1740
|
+
[Math.round, 8],
|
|
1741
|
+
[Math.trunc, 9],
|
|
1742
|
+
[Math.sin, 10],
|
|
1743
|
+
[Math.cos, 11],
|
|
1744
|
+
[Math.tan, 12],
|
|
1745
|
+
[Math.asin, 13],
|
|
1746
|
+
[Math.acos, 14],
|
|
1747
|
+
[Math.atan, 15],
|
|
1748
|
+
[Math.sinh, 16],
|
|
1749
|
+
[Math.cosh, 17],
|
|
1750
|
+
[Math.tanh, 18],
|
|
1751
|
+
[Math.sign, 19]
|
|
1752
|
+
]);
|
|
1721
1753
|
function applyUnaryElemwise(v, realFn, complexFn, name) {
|
|
1722
1754
|
if (isRuntimeSparseMatrix(v))
|
|
1723
1755
|
return applyUnaryElemwise(sparseToDense(v), realFn, complexFn, name);
|
|
@@ -1730,6 +1762,14 @@ function applyUnaryElemwise(v, realFn, complexFn, name) {
|
|
|
1730
1762
|
if (isRuntimeTensor(v)) {
|
|
1731
1763
|
const n = v.data.length;
|
|
1732
1764
|
if (!v.imag) {
|
|
1765
|
+
const opCode = nativeUnaryOpCode.get(realFn);
|
|
1766
|
+
if (opCode !== void 0) {
|
|
1767
|
+
const bridge = getLapackBridge();
|
|
1768
|
+
if (bridge?.unaryElemwise && v.data instanceof Float64Array) {
|
|
1769
|
+
const result = bridge.unaryElemwise(v.data, opCode);
|
|
1770
|
+
return RTV.tensorRaw(result, v.shape.slice());
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1733
1773
|
const out = new FloatXArray(n);
|
|
1734
1774
|
for (let i = 0; i < n; i++) out[i] = realFn(v.data[i]);
|
|
1735
1775
|
return makeTensor(out, void 0, v.shape.slice());
|
|
@@ -3618,16 +3658,6 @@ function toString(v) {
|
|
|
3618
3658
|
}
|
|
3619
3659
|
}
|
|
3620
3660
|
|
|
3621
|
-
// src/numbl-core/native/lapack-bridge.ts
|
|
3622
|
-
var NATIVE_ADDON_EXPECTED_VERSION = 1;
|
|
3623
|
-
var _bridge = null;
|
|
3624
|
-
function setLapackBridge(bridge) {
|
|
3625
|
-
_bridge = bridge;
|
|
3626
|
-
}
|
|
3627
|
-
function getLapackBridge() {
|
|
3628
|
-
return _bridge;
|
|
3629
|
-
}
|
|
3630
|
-
|
|
3631
3661
|
// src/ts-lapack/src/utils/xerbla.ts
|
|
3632
3662
|
function xerbla(srname, info) {
|
|
3633
3663
|
throw new Error(
|
|
@@ -20268,6 +20298,7 @@ function extractTensorElement(base, i) {
|
|
|
20268
20298
|
const im2 = base.imag[i];
|
|
20269
20299
|
return im2 === 0 ? RTV.num(base.data[i]) : RTV.complex(base.data[i], im2);
|
|
20270
20300
|
}
|
|
20301
|
+
if (base._isLogical === true) return base.data[i] !== 0;
|
|
20271
20302
|
return RTV.num(base.data[i]);
|
|
20272
20303
|
}
|
|
20273
20304
|
function resolveIndex(idx, dimSize, boundsLimit = dimSize) {
|
|
@@ -20321,17 +20352,35 @@ function growTensor2D(base, newRows, newCols) {
|
|
|
20321
20352
|
}
|
|
20322
20353
|
function assignSlice(base, rowIndices, colIndices, rhs, curRows) {
|
|
20323
20354
|
if (isRuntimeTensor(rhs)) {
|
|
20355
|
+
const nR = rowIndices.length;
|
|
20356
|
+
const nC = colIndices.length;
|
|
20324
20357
|
const [rhsRows, rhsCols] = tensorSize2D(rhs);
|
|
20325
|
-
|
|
20358
|
+
const shapeMatches = rhsRows === nR && rhsCols === nC;
|
|
20359
|
+
const sliceIsVector = nR === 1 || nC === 1;
|
|
20360
|
+
const rhsIsVector = rhsRows === 1 || rhsCols === 1;
|
|
20361
|
+
const countMatches = rhs.data.length === nR * nC;
|
|
20362
|
+
if (!shapeMatches && !(sliceIsVector && rhsIsVector && countMatches)) {
|
|
20326
20363
|
throw new RuntimeError("Subscripted assignment dimension mismatch");
|
|
20327
20364
|
}
|
|
20328
20365
|
if (rhs.imag || base.imag) ensureImag(base);
|
|
20329
|
-
|
|
20330
|
-
for (let
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20366
|
+
if (shapeMatches) {
|
|
20367
|
+
for (let ri = 0; ri < nR; ri++) {
|
|
20368
|
+
for (let ci = 0; ci < nC; ci++) {
|
|
20369
|
+
const dstLi = colMajorIndex(rowIndices[ri], colIndices[ci], curRows);
|
|
20370
|
+
const srcLi = colMajorIndex(ri, ci, rhsRows);
|
|
20371
|
+
base.data[dstLi] = rhs.data[srcLi];
|
|
20372
|
+
if (base.imag) base.imag[dstLi] = rhs.imag ? rhs.imag[srcLi] : 0;
|
|
20373
|
+
}
|
|
20374
|
+
}
|
|
20375
|
+
} else {
|
|
20376
|
+
let k = 0;
|
|
20377
|
+
for (let ci = 0; ci < nC; ci++) {
|
|
20378
|
+
for (let ri = 0; ri < nR; ri++) {
|
|
20379
|
+
const dstLi = colMajorIndex(rowIndices[ri], colIndices[ci], curRows);
|
|
20380
|
+
base.data[dstLi] = rhs.data[k];
|
|
20381
|
+
if (base.imag) base.imag[dstLi] = rhs.imag ? rhs.imag[k] : 0;
|
|
20382
|
+
k++;
|
|
20383
|
+
}
|
|
20335
20384
|
}
|
|
20336
20385
|
}
|
|
20337
20386
|
} else {
|
|
@@ -20668,6 +20717,23 @@ function indexIntoScalar(base, indices) {
|
|
|
20668
20717
|
return RTV.tensor(out, [1, count]);
|
|
20669
20718
|
}
|
|
20670
20719
|
}
|
|
20720
|
+
if (indices.length === 1 && isRuntimeTensor(indices[0])) {
|
|
20721
|
+
const idx = indices[0];
|
|
20722
|
+
for (let i = 0; i < idx.data.length; i++) {
|
|
20723
|
+
const k = Math.round(idx.data[i]);
|
|
20724
|
+
if (k !== 1) throw new RuntimeError("Index exceeds array bounds");
|
|
20725
|
+
}
|
|
20726
|
+
const n = idx.data.length;
|
|
20727
|
+
const scalarRe = isRuntimeNumber(base) ? base : base.re;
|
|
20728
|
+
const data = new FloatXArray(n);
|
|
20729
|
+
data.fill(scalarRe);
|
|
20730
|
+
if (isRuntimeComplexNumber(base) && base.im !== 0) {
|
|
20731
|
+
const im2 = new FloatXArray(n);
|
|
20732
|
+
im2.fill(base.im);
|
|
20733
|
+
return RTV.tensor(data, [...idx.shape], im2);
|
|
20734
|
+
}
|
|
20735
|
+
return RTV.tensor(data, [...idx.shape]);
|
|
20736
|
+
}
|
|
20671
20737
|
for (const idx of indices) {
|
|
20672
20738
|
if (isColonIndex(idx)) continue;
|
|
20673
20739
|
const i = toNumber(idx);
|
|
@@ -20679,6 +20745,22 @@ function indexIntoTensor(base, indices) {
|
|
|
20679
20745
|
if (indices.length === 1) {
|
|
20680
20746
|
return indexIntoTensor1D(base, indices[0]);
|
|
20681
20747
|
}
|
|
20748
|
+
if (base.shape.length > indices.length) {
|
|
20749
|
+
const collapsedShape = [];
|
|
20750
|
+
for (let d = 0; d < indices.length - 1; d++) {
|
|
20751
|
+
collapsedShape.push(base.shape[d]);
|
|
20752
|
+
}
|
|
20753
|
+
let tail = 1;
|
|
20754
|
+
for (let d = indices.length - 1; d < base.shape.length; d++) {
|
|
20755
|
+
tail *= base.shape[d];
|
|
20756
|
+
}
|
|
20757
|
+
collapsedShape.push(tail);
|
|
20758
|
+
const view = { ...base, shape: collapsedShape };
|
|
20759
|
+
if (indices.length === 2) {
|
|
20760
|
+
return indexIntoTensor2D(view, indices[0], indices[1]);
|
|
20761
|
+
}
|
|
20762
|
+
return indexIntoTensorND(view, indices);
|
|
20763
|
+
}
|
|
20682
20764
|
if (indices.length === 2) {
|
|
20683
20765
|
return indexIntoTensor2D(base, indices[0], indices[1]);
|
|
20684
20766
|
}
|
|
@@ -20707,6 +20789,11 @@ function indexIntoTensor1D(base, idx) {
|
|
|
20707
20789
|
}
|
|
20708
20790
|
function indexIntoTensor2D(base, rowIdx, colIdx) {
|
|
20709
20791
|
const [rows, cols] = tensorSize2D(base);
|
|
20792
|
+
const baseLogical = base._isLogical === true;
|
|
20793
|
+
const markLogical = (t) => {
|
|
20794
|
+
if (baseLogical && isRuntimeTensor(t)) t._isLogical = true;
|
|
20795
|
+
return t;
|
|
20796
|
+
};
|
|
20710
20797
|
if (isRuntimeNumber(rowIdx) && isColonIndex(colIdx)) {
|
|
20711
20798
|
const r = Math.round(rowIdx) - 1;
|
|
20712
20799
|
if (r < 0 || r >= rows)
|
|
@@ -20717,7 +20804,7 @@ function indexIntoTensor2D(base, rowIdx, colIdx) {
|
|
|
20717
20804
|
resultData2[ci] = base.data[r + ci * rows];
|
|
20718
20805
|
if (resultImag2 && base.imag) resultImag2[ci] = base.imag[r + ci * rows];
|
|
20719
20806
|
}
|
|
20720
|
-
return RTV.tensor(resultData2, [1, cols], resultImag2);
|
|
20807
|
+
return markLogical(RTV.tensor(resultData2, [1, cols], resultImag2));
|
|
20721
20808
|
}
|
|
20722
20809
|
if (isColonIndex(rowIdx) && isRuntimeNumber(colIdx)) {
|
|
20723
20810
|
const c = Math.round(colIdx) - 1;
|
|
@@ -20729,7 +20816,7 @@ function indexIntoTensor2D(base, rowIdx, colIdx) {
|
|
|
20729
20816
|
const resultImag2 = base.imag ? new FloatXArray(rows) : void 0;
|
|
20730
20817
|
if (resultImag2 && base.imag)
|
|
20731
20818
|
for (let ri = 0; ri < rows; ri++) resultImag2[ri] = base.imag[offset + ri];
|
|
20732
|
-
return RTV.tensor(resultData2, [rows, 1], resultImag2);
|
|
20819
|
+
return markLogical(RTV.tensor(resultData2, [rows, 1], resultImag2));
|
|
20733
20820
|
}
|
|
20734
20821
|
const rowIdxArr = resolveIndex(rowIdx, rows);
|
|
20735
20822
|
const colIdxArr = resolveIndex(colIdx, cols);
|
|
@@ -20751,7 +20838,7 @@ function indexIntoTensor2D(base, rowIdx, colIdx) {
|
|
|
20751
20838
|
}
|
|
20752
20839
|
}
|
|
20753
20840
|
}
|
|
20754
|
-
return RTV.tensor(resultData, [numR, numC], resultImag);
|
|
20841
|
+
return markLogical(RTV.tensor(resultData, [numR, numC], resultImag));
|
|
20755
20842
|
}
|
|
20756
20843
|
function indexIntoTensorND(base, indices) {
|
|
20757
20844
|
const shape = base.shape;
|
|
@@ -20799,7 +20886,13 @@ function indexIntoTensorND(base, indices) {
|
|
|
20799
20886
|
subs[d] = 0;
|
|
20800
20887
|
}
|
|
20801
20888
|
}
|
|
20802
|
-
|
|
20889
|
+
const result = RTV.tensor(
|
|
20890
|
+
resultData,
|
|
20891
|
+
resultShape,
|
|
20892
|
+
resultImag
|
|
20893
|
+
);
|
|
20894
|
+
if (base._isLogical === true) result._isLogical = true;
|
|
20895
|
+
return result;
|
|
20803
20896
|
}
|
|
20804
20897
|
function indexIntoCell(base, indices) {
|
|
20805
20898
|
if (indices.length === 1) {
|
|
@@ -20964,6 +21057,7 @@ function indexIntoLogical(base, indices) {
|
|
|
20964
21057
|
return base;
|
|
20965
21058
|
}
|
|
20966
21059
|
function indexIntoTensorWithTensor(base, idx) {
|
|
21060
|
+
const baseLogical = base._isLogical === true;
|
|
20967
21061
|
if (idx._isLogical) {
|
|
20968
21062
|
const selected = [];
|
|
20969
21063
|
const selectedIm = [];
|
|
@@ -20977,12 +21071,19 @@ function indexIntoTensorWithTensor(base, idx) {
|
|
|
20977
21071
|
if (selected.length === 1) {
|
|
20978
21072
|
if (hasImag2 && selectedIm[0] !== 0)
|
|
20979
21073
|
return RTV.complex(selected[0], selectedIm[0]);
|
|
21074
|
+
if (baseLogical) return selected[0] !== 0;
|
|
20980
21075
|
return RTV.num(selected[0]);
|
|
20981
21076
|
}
|
|
20982
21077
|
const imOut2 = hasImag2 && selectedIm.some((x) => x !== 0) ? new FloatXArray(selectedIm) : void 0;
|
|
20983
21078
|
const isRow = base.shape.length === 2 && base.shape[0] === 1;
|
|
20984
21079
|
const outShape2 = isRow ? [1, selected.length] : [selected.length, 1];
|
|
20985
|
-
|
|
21080
|
+
const result2 = RTV.tensor(
|
|
21081
|
+
new FloatXArray(selected),
|
|
21082
|
+
outShape2,
|
|
21083
|
+
imOut2
|
|
21084
|
+
);
|
|
21085
|
+
if (baseLogical) result2._isLogical = true;
|
|
21086
|
+
return result2;
|
|
20986
21087
|
}
|
|
20987
21088
|
const resultData = [];
|
|
20988
21089
|
const hasImag = base.imag !== void 0;
|
|
@@ -20998,7 +21099,13 @@ function indexIntoTensorWithTensor(base, idx) {
|
|
|
20998
21099
|
const baseIsVector = base.shape.length <= 2 && (base.shape[0] === 1 || base.shape[1] === 1 || base.shape.length === 1);
|
|
20999
21100
|
const outShape = idxIs0x0 ? [0, 0] : baseIsVector ? base.shape[0] === 1 ? [1, resultData.length] : [resultData.length, 1] : idx.shape;
|
|
21000
21101
|
const imOut = hasImag && imIndices.some((x) => x !== 0) ? new FloatXArray(imIndices) : void 0;
|
|
21001
|
-
|
|
21102
|
+
const result = RTV.tensor(
|
|
21103
|
+
new FloatXArray(resultData),
|
|
21104
|
+
outShape,
|
|
21105
|
+
imOut
|
|
21106
|
+
);
|
|
21107
|
+
if (baseLogical) result._isLogical = true;
|
|
21108
|
+
return result;
|
|
21002
21109
|
}
|
|
21003
21110
|
function indexIntoRTValue(base, indices) {
|
|
21004
21111
|
if (isRuntimeNumber(base) || isRuntimeComplexNumber(base)) {
|
|
@@ -21348,10 +21455,18 @@ function storeIntoTensor2D(base, indices, rhs) {
|
|
|
21348
21455
|
return storeIntoTensorColonCol(base, indices[0], rhs, rows, cols);
|
|
21349
21456
|
}
|
|
21350
21457
|
if (rowIsTensor || colIsTensor) {
|
|
21351
|
-
const
|
|
21352
|
-
|
|
21353
|
-
|
|
21354
|
-
|
|
21458
|
+
const isEmpty = base.data.length === 0;
|
|
21459
|
+
let effectiveCols = cols;
|
|
21460
|
+
let effectiveRows = rows;
|
|
21461
|
+
if (isEmpty && isRuntimeTensor(rhs)) {
|
|
21462
|
+
const [rhsRowsG, rhsColsG] = tensorSize2D(rhs);
|
|
21463
|
+
if (rowIsColon && !colIsColon) effectiveRows = rhsRowsG;
|
|
21464
|
+
if (colIsColon && !rowIsColon) effectiveCols = rhsColsG;
|
|
21465
|
+
}
|
|
21466
|
+
const rowIndices = rowIsColon ? Array.from({ length: effectiveRows }, (_, i) => i) : resolveIndex(indices[0], rows, 0);
|
|
21467
|
+
const colIndices = colIsColon ? Array.from({ length: effectiveCols }, (_, i) => i) : resolveIndex(indices[1], cols, 0);
|
|
21468
|
+
const maxRow = rowIndices.length > 0 ? Math.max(...rowIndices) + 1 : effectiveRows;
|
|
21469
|
+
const maxCol = colIndices.length > 0 ? Math.max(...colIndices) + 1 : effectiveCols;
|
|
21355
21470
|
base = growTensor2D(base, maxRow, maxCol);
|
|
21356
21471
|
const [curRows] = tensorSize2D(base);
|
|
21357
21472
|
assignSlice(base, rowIndices, colIndices, rhs, curRows);
|
|
@@ -21779,6 +21894,9 @@ function horzcat(...values) {
|
|
|
21779
21894
|
if (values.some((v) => isRuntimeCell(v))) {
|
|
21780
21895
|
return cellCatAlongDim(values, 1);
|
|
21781
21896
|
}
|
|
21897
|
+
if (values.some((v) => isRuntimeStruct(v) || isRuntimeStructArray(v))) {
|
|
21898
|
+
return structCat(values);
|
|
21899
|
+
}
|
|
21782
21900
|
return catAlongDim(values, 1);
|
|
21783
21901
|
}
|
|
21784
21902
|
function vertcat(...values) {
|
|
@@ -21790,8 +21908,47 @@ function vertcat(...values) {
|
|
|
21790
21908
|
if (values.some((v) => isRuntimeCell(v))) {
|
|
21791
21909
|
return cellCatAlongDim(values, 0);
|
|
21792
21910
|
}
|
|
21911
|
+
if (values.some((v) => isRuntimeStruct(v) || isRuntimeStructArray(v))) {
|
|
21912
|
+
return structCat(values);
|
|
21913
|
+
}
|
|
21793
21914
|
return catAlongDim(values, 0);
|
|
21794
21915
|
}
|
|
21916
|
+
function structCat(values) {
|
|
21917
|
+
const elements = [];
|
|
21918
|
+
let fieldNames = null;
|
|
21919
|
+
for (const v of values) {
|
|
21920
|
+
if (isRuntimeStruct(v)) {
|
|
21921
|
+
const keys = Array.from(v.fields.keys());
|
|
21922
|
+
if (fieldNames === null) fieldNames = keys;
|
|
21923
|
+
else if (!arraysEqual(fieldNames, keys)) {
|
|
21924
|
+
throw new RuntimeError(
|
|
21925
|
+
"Cannot concatenate structs with different field names"
|
|
21926
|
+
);
|
|
21927
|
+
}
|
|
21928
|
+
elements.push(v);
|
|
21929
|
+
} else if (isRuntimeStructArray(v)) {
|
|
21930
|
+
if (fieldNames === null) fieldNames = [...v.fieldNames];
|
|
21931
|
+
else if (!arraysEqual(fieldNames, v.fieldNames)) {
|
|
21932
|
+
throw new RuntimeError(
|
|
21933
|
+
"Cannot concatenate struct arrays with different field names"
|
|
21934
|
+
);
|
|
21935
|
+
}
|
|
21936
|
+
for (const e of v.elements) elements.push(e);
|
|
21937
|
+
} else {
|
|
21938
|
+
if (isRuntimeTensor(v) && v.data.length === 0 && v.shape.every((d) => d === 0)) {
|
|
21939
|
+
continue;
|
|
21940
|
+
}
|
|
21941
|
+
throw new RuntimeError(`Cannot concatenate ${kstr(v)} into struct`);
|
|
21942
|
+
}
|
|
21943
|
+
}
|
|
21944
|
+
if (fieldNames === null) fieldNames = [];
|
|
21945
|
+
return RTV.structArray(fieldNames, elements);
|
|
21946
|
+
}
|
|
21947
|
+
function arraysEqual(a, b) {
|
|
21948
|
+
if (a.length !== b.length) return false;
|
|
21949
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
21950
|
+
return true;
|
|
21951
|
+
}
|
|
21795
21952
|
function toSparseForCat(v) {
|
|
21796
21953
|
if (isRuntimeSparseMatrix(v)) return v;
|
|
21797
21954
|
if (isRuntimeNumber(v)) {
|
|
@@ -22286,6 +22443,258 @@ function coerceToTensor(v, name) {
|
|
|
22286
22443
|
throw new RuntimeError(`${name}: argument must be numeric`);
|
|
22287
22444
|
}
|
|
22288
22445
|
|
|
22446
|
+
// src/numbl-core/helpers/string.ts
|
|
22447
|
+
function numStr(n) {
|
|
22448
|
+
if (n === Infinity) return "Inf";
|
|
22449
|
+
if (n === -Infinity) return "-Inf";
|
|
22450
|
+
if (isNaN(n)) return "NaN";
|
|
22451
|
+
if (n === 0) return "0";
|
|
22452
|
+
const prec = 5;
|
|
22453
|
+
const exp = Math.floor(Math.log10(Math.abs(n)));
|
|
22454
|
+
let s;
|
|
22455
|
+
if (exp < -4 || exp >= prec) {
|
|
22456
|
+
s = n.toExponential(prec - 1);
|
|
22457
|
+
const ePos = s.indexOf("e");
|
|
22458
|
+
let mantissa = s.slice(0, ePos);
|
|
22459
|
+
const expPart0 = s.slice(ePos);
|
|
22460
|
+
if (mantissa.includes(".")) mantissa = mantissa.replace(/\.?0+$/, "");
|
|
22461
|
+
const expPart = expPart0.replace(/([eE][+-])(\d)$/, "$10$2");
|
|
22462
|
+
s = mantissa + expPart;
|
|
22463
|
+
} else {
|
|
22464
|
+
if (Number.isInteger(n)) return String(n);
|
|
22465
|
+
s = n.toPrecision(prec);
|
|
22466
|
+
if (s.includes(".")) s = s.replace(/\.?0+$/, "");
|
|
22467
|
+
}
|
|
22468
|
+
return s;
|
|
22469
|
+
}
|
|
22470
|
+
function num2strScalar(n) {
|
|
22471
|
+
if (n === Infinity) return "Inf";
|
|
22472
|
+
if (n === -Infinity) return "-Inf";
|
|
22473
|
+
if (isNaN(n)) return "NaN";
|
|
22474
|
+
if (n === 0) return "0";
|
|
22475
|
+
if (Number.isInteger(n)) return String(n);
|
|
22476
|
+
const prec = 5;
|
|
22477
|
+
const exp = Math.floor(Math.log10(Math.abs(n)));
|
|
22478
|
+
let s;
|
|
22479
|
+
if (exp < -4 || exp >= prec) {
|
|
22480
|
+
s = n.toExponential(prec - 1);
|
|
22481
|
+
const ePos = s.indexOf("e");
|
|
22482
|
+
let mantissa = s.slice(0, ePos);
|
|
22483
|
+
const expPart0 = s.slice(ePos);
|
|
22484
|
+
if (mantissa.includes(".")) mantissa = mantissa.replace(/\.?0+$/, "");
|
|
22485
|
+
const expPart = expPart0.replace(/([eE][+-])(\d)$/, "$10$2");
|
|
22486
|
+
s = mantissa + expPart;
|
|
22487
|
+
} else {
|
|
22488
|
+
s = n.toPrecision(prec);
|
|
22489
|
+
if (s.includes(".")) s = s.replace(/\.?0+$/, "");
|
|
22490
|
+
}
|
|
22491
|
+
return s;
|
|
22492
|
+
}
|
|
22493
|
+
function applyWidth(spec, str) {
|
|
22494
|
+
const m = spec.match(/^%([-+ #]*)0?(\d+)?/);
|
|
22495
|
+
if (!m) return str;
|
|
22496
|
+
const explicitFlags = m[1] || "";
|
|
22497
|
+
const leftAlign = explicitFlags.includes("-");
|
|
22498
|
+
const afterPercent = spec.slice(1);
|
|
22499
|
+
const flagAndWidth = afterPercent.match(/^([-+ #]*)(0?)(\d+)?/);
|
|
22500
|
+
const zeroFlag = flagAndWidth ? flagAndWidth[2] === "0" : false;
|
|
22501
|
+
const width = flagAndWidth && flagAndWidth[3] ? parseInt(flagAndWidth[3]) : 0;
|
|
22502
|
+
if (width <= str.length) return str;
|
|
22503
|
+
const zeroPad = !leftAlign && zeroFlag;
|
|
22504
|
+
const padLen = width - str.length;
|
|
22505
|
+
if (leftAlign) return str + " ".repeat(padLen);
|
|
22506
|
+
if (zeroPad) {
|
|
22507
|
+
if (str[0] === "-" || str[0] === "+") {
|
|
22508
|
+
return str[0] + "0".repeat(padLen) + str.slice(1);
|
|
22509
|
+
}
|
|
22510
|
+
return "0".repeat(padLen) + str;
|
|
22511
|
+
}
|
|
22512
|
+
return " ".repeat(padLen) + str;
|
|
22513
|
+
}
|
|
22514
|
+
function sprintfFormat(fmt, args) {
|
|
22515
|
+
const flatArgs = [];
|
|
22516
|
+
for (const arg of args) {
|
|
22517
|
+
if (isRuntimeTensor(arg)) {
|
|
22518
|
+
for (let k = 0; k < arg.data.length; k++) {
|
|
22519
|
+
flatArgs.push(arg.data[k]);
|
|
22520
|
+
}
|
|
22521
|
+
} else {
|
|
22522
|
+
flatArgs.push(arg);
|
|
22523
|
+
}
|
|
22524
|
+
}
|
|
22525
|
+
let result = "";
|
|
22526
|
+
let argIdx = 0;
|
|
22527
|
+
do {
|
|
22528
|
+
const startArgIdx = argIdx;
|
|
22529
|
+
let outOfArgs = false;
|
|
22530
|
+
let i = 0;
|
|
22531
|
+
while (i < fmt.length && !outOfArgs) {
|
|
22532
|
+
if (fmt[i] === "%" && i + 1 < fmt.length) {
|
|
22533
|
+
i++;
|
|
22534
|
+
let spec = "%";
|
|
22535
|
+
while (i < fmt.length && !"dfigeEsoxXuc%".includes(fmt[i])) {
|
|
22536
|
+
if (fmt[i] === "*") {
|
|
22537
|
+
if (argIdx >= flatArgs.length) {
|
|
22538
|
+
outOfArgs = true;
|
|
22539
|
+
break;
|
|
22540
|
+
}
|
|
22541
|
+
spec += String(Math.round(toNumber(flatArgs[argIdx++])));
|
|
22542
|
+
i++;
|
|
22543
|
+
} else {
|
|
22544
|
+
spec += fmt[i];
|
|
22545
|
+
i++;
|
|
22546
|
+
}
|
|
22547
|
+
}
|
|
22548
|
+
if (outOfArgs) break;
|
|
22549
|
+
if (i < fmt.length) {
|
|
22550
|
+
const ch = fmt[i];
|
|
22551
|
+
i++;
|
|
22552
|
+
if (ch === "%") {
|
|
22553
|
+
result += "%";
|
|
22554
|
+
} else if (argIdx >= flatArgs.length) {
|
|
22555
|
+
outOfArgs = true;
|
|
22556
|
+
} else if (ch === "d" || ch === "i" || ch === "u") {
|
|
22557
|
+
const raw = toNumber(flatArgs[argIdx++]);
|
|
22558
|
+
const isInt = Number.isInteger(raw);
|
|
22559
|
+
const canPrintAsInt = ch === "u" ? isInt && raw >= 0 : isInt;
|
|
22560
|
+
if (!canPrintAsInt) {
|
|
22561
|
+
let eStr = raw.toExponential(6);
|
|
22562
|
+
eStr = eStr.replace(/e([+-])(\d)$/, "e$10$2");
|
|
22563
|
+
result += applyWidth(spec, eStr);
|
|
22564
|
+
} else {
|
|
22565
|
+
const n = raw;
|
|
22566
|
+
const flags = spec.slice(1);
|
|
22567
|
+
const hasPlus = flags.includes("+");
|
|
22568
|
+
const leftAlign = flags.includes("-");
|
|
22569
|
+
const widthMatch = spec.match(/^%[^0-9]*(\d+)/);
|
|
22570
|
+
const width = widthMatch ? parseInt(widthMatch[1]) : 0;
|
|
22571
|
+
const zeroPad = !leftAlign && /^[-+ ]*0/.test(spec.slice(1));
|
|
22572
|
+
const s = String(Math.abs(n));
|
|
22573
|
+
const sign = n < 0 ? "-" : hasPlus ? "+" : "";
|
|
22574
|
+
if (width > 0) {
|
|
22575
|
+
const padChar = zeroPad ? "0" : " ";
|
|
22576
|
+
const padLen = Math.max(0, width - sign.length - s.length);
|
|
22577
|
+
const pad = padChar.repeat(padLen);
|
|
22578
|
+
result += leftAlign ? sign + s + " ".repeat(padLen) : zeroPad ? sign + pad + s : pad + sign + s;
|
|
22579
|
+
} else {
|
|
22580
|
+
result += sign + s;
|
|
22581
|
+
}
|
|
22582
|
+
}
|
|
22583
|
+
} else if (ch === "f") {
|
|
22584
|
+
const n = toNumber(flatArgs[argIdx++]);
|
|
22585
|
+
if (!isFinite(n) || isNaN(n)) {
|
|
22586
|
+
result += applyWidth(spec, numStr(n));
|
|
22587
|
+
} else {
|
|
22588
|
+
const fFlags = spec.slice(1);
|
|
22589
|
+
const fHasPlus = fFlags.includes("+");
|
|
22590
|
+
const precMatch = spec.match(/\.(\d+)/);
|
|
22591
|
+
const prec = precMatch ? parseInt(precMatch[1]) : 6;
|
|
22592
|
+
const formatted = n.toFixed(prec);
|
|
22593
|
+
const fSign = n < 0 ? "" : fHasPlus ? "+" : "";
|
|
22594
|
+
result += applyWidth(spec, fSign + formatted);
|
|
22595
|
+
}
|
|
22596
|
+
} else if (ch === "e" || ch === "E") {
|
|
22597
|
+
const n = toNumber(flatArgs[argIdx++]);
|
|
22598
|
+
if (!isFinite(n) || isNaN(n)) {
|
|
22599
|
+
result += applyWidth(spec, numStr(n));
|
|
22600
|
+
} else {
|
|
22601
|
+
const precMatch = spec.match(/\.(\d+)/);
|
|
22602
|
+
const prec = precMatch ? parseInt(precMatch[1]) : 6;
|
|
22603
|
+
let eStr = n.toExponential(prec);
|
|
22604
|
+
eStr = eStr.replace(/e([+-])(\d)$/, "e$10$2");
|
|
22605
|
+
if (ch === "E") eStr = eStr.toUpperCase();
|
|
22606
|
+
result += applyWidth(spec, eStr);
|
|
22607
|
+
}
|
|
22608
|
+
} else if (ch === "x" || ch === "X") {
|
|
22609
|
+
const n = Math.round(toNumber(flatArgs[argIdx++]));
|
|
22610
|
+
let s = Math.abs(n).toString(16);
|
|
22611
|
+
if (ch === "X") s = s.toUpperCase();
|
|
22612
|
+
result += applyWidth(spec, s);
|
|
22613
|
+
} else if (ch === "o") {
|
|
22614
|
+
const n = Math.round(toNumber(flatArgs[argIdx++]));
|
|
22615
|
+
result += applyWidth(spec, Math.abs(n).toString(8));
|
|
22616
|
+
} else if (ch === "g" || ch === "G") {
|
|
22617
|
+
const gVal = toNumber(flatArgs[argIdx++]);
|
|
22618
|
+
if (!isFinite(gVal) || isNaN(gVal)) {
|
|
22619
|
+
result += applyWidth(spec, numStr(gVal));
|
|
22620
|
+
} else {
|
|
22621
|
+
const precMatch = spec.match(/\.(\d+)/);
|
|
22622
|
+
const gPrec = precMatch ? parseInt(precMatch[1]) : 6;
|
|
22623
|
+
let gStr;
|
|
22624
|
+
if (gVal === 0) {
|
|
22625
|
+
gStr = "0";
|
|
22626
|
+
} else {
|
|
22627
|
+
const exp = Math.floor(Math.log10(Math.abs(gVal)));
|
|
22628
|
+
if (exp < -4 || exp >= gPrec) {
|
|
22629
|
+
gStr = gVal.toExponential(gPrec - 1);
|
|
22630
|
+
const ePos = gStr.indexOf("e");
|
|
22631
|
+
let mantissa = gStr.slice(0, ePos);
|
|
22632
|
+
let expPart = gStr.slice(ePos);
|
|
22633
|
+
if (mantissa.includes(".")) {
|
|
22634
|
+
mantissa = mantissa.replace(/\.?0+$/, "");
|
|
22635
|
+
}
|
|
22636
|
+
expPart = expPart.replace(/e([+-])(\d)$/, "e$10$2");
|
|
22637
|
+
gStr = mantissa + expPart;
|
|
22638
|
+
} else {
|
|
22639
|
+
gStr = gVal.toPrecision(gPrec);
|
|
22640
|
+
if (gStr.includes(".")) {
|
|
22641
|
+
gStr = gStr.replace(/\.?0+$/, "");
|
|
22642
|
+
}
|
|
22643
|
+
if (gStr.includes("e")) {
|
|
22644
|
+
gStr = String(parseFloat(gStr));
|
|
22645
|
+
}
|
|
22646
|
+
}
|
|
22647
|
+
}
|
|
22648
|
+
if (ch === "G") gStr = gStr.toUpperCase();
|
|
22649
|
+
result += applyWidth(spec, gStr);
|
|
22650
|
+
}
|
|
22651
|
+
} else if (ch === "s") {
|
|
22652
|
+
const sVal = toString(flatArgs[argIdx++]);
|
|
22653
|
+
const sFlags = spec.slice(1);
|
|
22654
|
+
const sLeftAlign = sFlags.includes("-");
|
|
22655
|
+
const sWidthMatch = spec.match(/^%[^0-9]*(\d+)/);
|
|
22656
|
+
const sWidth = sWidthMatch ? parseInt(sWidthMatch[1]) : 0;
|
|
22657
|
+
if (sWidth > sVal.length) {
|
|
22658
|
+
const sPad = " ".repeat(sWidth - sVal.length);
|
|
22659
|
+
result += sLeftAlign ? sVal + sPad : sPad + sVal;
|
|
22660
|
+
} else {
|
|
22661
|
+
result += sVal;
|
|
22662
|
+
}
|
|
22663
|
+
} else if (ch === "c") {
|
|
22664
|
+
result += String.fromCharCode(
|
|
22665
|
+
Math.round(toNumber(flatArgs[argIdx++]))
|
|
22666
|
+
);
|
|
22667
|
+
} else {
|
|
22668
|
+
result += spec + ch;
|
|
22669
|
+
argIdx++;
|
|
22670
|
+
}
|
|
22671
|
+
}
|
|
22672
|
+
} else if (fmt[i] === "\\" && i + 1 < fmt.length) {
|
|
22673
|
+
i++;
|
|
22674
|
+
switch (fmt[i]) {
|
|
22675
|
+
case "n":
|
|
22676
|
+
result += "\n";
|
|
22677
|
+
break;
|
|
22678
|
+
case "t":
|
|
22679
|
+
result += " ";
|
|
22680
|
+
break;
|
|
22681
|
+
case "\\":
|
|
22682
|
+
result += "\\";
|
|
22683
|
+
break;
|
|
22684
|
+
default:
|
|
22685
|
+
result += "\\" + fmt[i];
|
|
22686
|
+
}
|
|
22687
|
+
i++;
|
|
22688
|
+
} else {
|
|
22689
|
+
result += fmt[i];
|
|
22690
|
+
i++;
|
|
22691
|
+
}
|
|
22692
|
+
}
|
|
22693
|
+
if (argIdx === startArgIdx) break;
|
|
22694
|
+
} while (argIdx < flatArgs.length);
|
|
22695
|
+
return result;
|
|
22696
|
+
}
|
|
22697
|
+
|
|
22289
22698
|
// src/numbl-core/helpers/arithmetic.ts
|
|
22290
22699
|
function toComplex(v) {
|
|
22291
22700
|
if (isRuntimeComplexNumber(v)) return { re: v.re, im: v.im };
|
|
@@ -22461,6 +22870,18 @@ function tryNativeElemwiseReal(at, bt, opCode) {
|
|
|
22461
22870
|
);
|
|
22462
22871
|
return RTV.tensorRaw(result, at.shape);
|
|
22463
22872
|
}
|
|
22873
|
+
function tryNativeElemwiseScalar(scalar, tensor, opCode, scalarOnLeft) {
|
|
22874
|
+
if (tensor.imag) return null;
|
|
22875
|
+
const bridge = getLapackBridge();
|
|
22876
|
+
if (!bridge?.elemwiseScalar) return null;
|
|
22877
|
+
const result = bridge.elemwiseScalar(
|
|
22878
|
+
scalar,
|
|
22879
|
+
tensor.data,
|
|
22880
|
+
opCode,
|
|
22881
|
+
scalarOnLeft
|
|
22882
|
+
);
|
|
22883
|
+
return RTV.tensorRaw(result, tensor.shape);
|
|
22884
|
+
}
|
|
22464
22885
|
function tensorElemwiseComplex(at, bt, opCode, jsOp) {
|
|
22465
22886
|
const bridge = getLapackBridge();
|
|
22466
22887
|
if (bridge?.elemwiseComplex) {
|
|
@@ -22501,7 +22922,26 @@ function tensorElemwiseComplex(at, bt, opCode, jsOp) {
|
|
|
22501
22922
|
const isReal = resultIm.every((x) => x === 0);
|
|
22502
22923
|
return RTV.tensor(resultRe, at.shape, isReal ? void 0 : resultIm);
|
|
22503
22924
|
}
|
|
22925
|
+
function coerceToConcatString(v) {
|
|
22926
|
+
if (isRuntimeString(v)) return v;
|
|
22927
|
+
if (isRuntimeChar(v)) return v.value;
|
|
22928
|
+
if (isRuntimeLogical(v)) return v ? "true" : "false";
|
|
22929
|
+
if (isRuntimeNumber(v)) return num2strScalar(v);
|
|
22930
|
+
if (isRuntimeTensor(v) && v.data.length === 1 && !v.imag) {
|
|
22931
|
+
const x = v.data[0];
|
|
22932
|
+
if (v._isLogical === true) return x ? "true" : "false";
|
|
22933
|
+
return num2strScalar(x);
|
|
22934
|
+
}
|
|
22935
|
+
return null;
|
|
22936
|
+
}
|
|
22504
22937
|
function mAdd(a, b) {
|
|
22938
|
+
if (isRuntimeString(a) || isRuntimeString(b)) {
|
|
22939
|
+
const aStr = coerceToConcatString(a);
|
|
22940
|
+
const bStr = coerceToConcatString(b);
|
|
22941
|
+
if (aStr !== null && bStr !== null) {
|
|
22942
|
+
return RTV.string(aStr + bStr);
|
|
22943
|
+
}
|
|
22944
|
+
}
|
|
22505
22945
|
const m = matchSameShapeTensors(a, b);
|
|
22506
22946
|
if (m) {
|
|
22507
22947
|
const [at, bt] = m;
|
|
@@ -22531,6 +22971,13 @@ function mAdd(a, b) {
|
|
|
22531
22971
|
im: aIm + bIm
|
|
22532
22972
|
}));
|
|
22533
22973
|
}
|
|
22974
|
+
if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
|
|
22975
|
+
const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_ADD, true);
|
|
22976
|
+
if (nr) return nr;
|
|
22977
|
+
} else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
|
|
22978
|
+
const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_ADD, false);
|
|
22979
|
+
if (nr) return nr;
|
|
22980
|
+
}
|
|
22534
22981
|
return binaryOp(a, b, (x, y) => x + y);
|
|
22535
22982
|
}
|
|
22536
22983
|
function mSub(a, b) {
|
|
@@ -22563,6 +23010,13 @@ function mSub(a, b) {
|
|
|
22563
23010
|
im: aIm - bIm
|
|
22564
23011
|
}));
|
|
22565
23012
|
}
|
|
23013
|
+
if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
|
|
23014
|
+
const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_SUB, true);
|
|
23015
|
+
if (nr) return nr;
|
|
23016
|
+
} else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
|
|
23017
|
+
const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_SUB, false);
|
|
23018
|
+
if (nr) return nr;
|
|
23019
|
+
}
|
|
22566
23020
|
return binaryOp(a, b, (x, y) => x - y);
|
|
22567
23021
|
}
|
|
22568
23022
|
function mMul(a, b) {
|
|
@@ -22579,6 +23033,13 @@ function mMul(a, b) {
|
|
|
22579
23033
|
im: aRe * bIm + aIm * bRe
|
|
22580
23034
|
}));
|
|
22581
23035
|
}
|
|
23036
|
+
if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
|
|
23037
|
+
const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_MUL, true);
|
|
23038
|
+
if (nr) return nr;
|
|
23039
|
+
} else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
|
|
23040
|
+
const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_MUL, false);
|
|
23041
|
+
if (nr) return nr;
|
|
23042
|
+
}
|
|
22582
23043
|
return binaryOp(a, b, (x, y) => x * y);
|
|
22583
23044
|
}
|
|
22584
23045
|
function mElemMul(a, b) {
|
|
@@ -22611,6 +23072,13 @@ function mElemMul(a, b) {
|
|
|
22611
23072
|
im: aRe * bIm + aIm * bRe
|
|
22612
23073
|
}));
|
|
22613
23074
|
}
|
|
23075
|
+
if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
|
|
23076
|
+
const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_MUL, true);
|
|
23077
|
+
if (nr) return nr;
|
|
23078
|
+
} else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
|
|
23079
|
+
const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_MUL, false);
|
|
23080
|
+
if (nr) return nr;
|
|
23081
|
+
}
|
|
22614
23082
|
return binaryOp(a, b, (x, y) => x * y);
|
|
22615
23083
|
}
|
|
22616
23084
|
function mDiv(a, b) {
|
|
@@ -22649,6 +23117,13 @@ function mElemDiv(a, b) {
|
|
|
22649
23117
|
if (isComplexOrMixed(a, b)) {
|
|
22650
23118
|
return complexBinaryOp(a, b, complexDivide);
|
|
22651
23119
|
}
|
|
23120
|
+
if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
|
|
23121
|
+
const nr = tryNativeElemwiseScalar(a, b, ELEMWISE_DIV, true);
|
|
23122
|
+
if (nr) return nr;
|
|
23123
|
+
} else if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
|
|
23124
|
+
const nr = tryNativeElemwiseScalar(b, a, ELEMWISE_DIV, false);
|
|
23125
|
+
if (nr) return nr;
|
|
23126
|
+
}
|
|
22652
23127
|
return binaryOp(a, b, (x, y) => x / y);
|
|
22653
23128
|
}
|
|
22654
23129
|
function mLeftDiv(a, b) {
|
|
@@ -23618,7 +24093,7 @@ var token_config_default = {
|
|
|
23618
24093
|
stripUnderscores: true,
|
|
23619
24094
|
integerToken: "Integer",
|
|
23620
24095
|
floatToken: "Float",
|
|
23621
|
-
exponentChars: ["e", "E"],
|
|
24096
|
+
exponentChars: ["e", "E", "d", "D"],
|
|
23622
24097
|
decimalPoint: ".",
|
|
23623
24098
|
dotOperatorPrefixes: ["*", "/", "\\", "^"]
|
|
23624
24099
|
},
|
|
@@ -23923,6 +24398,9 @@ function tokenizeDetailed(input) {
|
|
|
23923
24398
|
if (numCfg.stripUnderscores) {
|
|
23924
24399
|
lexeme = lexeme.replace(/_/g, "");
|
|
23925
24400
|
}
|
|
24401
|
+
if (isFloat) {
|
|
24402
|
+
lexeme = lexeme.replace(/[dD]/g, "e");
|
|
24403
|
+
}
|
|
23926
24404
|
const tok = isFloat ? Token[numCfg.floatToken] : Token[numCfg.integerToken];
|
|
23927
24405
|
lineStart = false;
|
|
23928
24406
|
out.push({ token: tok, lexeme, start, end: pos });
|
|
@@ -26914,6 +27392,29 @@ function methodDispatch(rt, name, nargout, args) {
|
|
|
26914
27392
|
}
|
|
26915
27393
|
return fieldVal;
|
|
26916
27394
|
}
|
|
27395
|
+
{
|
|
27396
|
+
const accessorKey = `${firstRV.className}.get.${name}`;
|
|
27397
|
+
if (!rt.activeAccessors.has(accessorKey)) {
|
|
27398
|
+
const getter = rt.cachedResolveClassMethod(
|
|
27399
|
+
firstRV.className,
|
|
27400
|
+
`get.${name}`
|
|
27401
|
+
);
|
|
27402
|
+
if (getter) {
|
|
27403
|
+
rt.activeAccessors.add(accessorKey);
|
|
27404
|
+
let gotVal;
|
|
27405
|
+
try {
|
|
27406
|
+
gotVal = getter(1, first);
|
|
27407
|
+
} finally {
|
|
27408
|
+
rt.activeAccessors.delete(accessorKey);
|
|
27409
|
+
}
|
|
27410
|
+
const remaining = args.slice(1);
|
|
27411
|
+
if (remaining.length > 0) {
|
|
27412
|
+
return rt.index(gotVal, remaining, nargout);
|
|
27413
|
+
}
|
|
27414
|
+
return gotVal;
|
|
27415
|
+
}
|
|
27416
|
+
}
|
|
27417
|
+
}
|
|
26917
27418
|
try {
|
|
26918
27419
|
return callClassMethod(rt, firstRV.className, name, nargout, args);
|
|
26919
27420
|
} catch (e) {
|
|
@@ -27868,6 +28369,7 @@ function index(rt, base, indices, nargout = 1, skipSubsref = false) {
|
|
|
27868
28369
|
const im2 = t.imag[i];
|
|
27869
28370
|
return im2 === 0 ? t.data[i] : RTV.complex(t.data[i], im2);
|
|
27870
28371
|
}
|
|
28372
|
+
if (t._isLogical === true) return t.data[i] !== 0;
|
|
27871
28373
|
return t.data[i];
|
|
27872
28374
|
}
|
|
27873
28375
|
} else if (nIdx === 2) {
|
|
@@ -27876,7 +28378,14 @@ function index(rt, base, indices, nargout = 1, skipSubsref = false) {
|
|
|
27876
28378
|
if (typeof ri === "number" && typeof ci === "number") {
|
|
27877
28379
|
const s = t.shape;
|
|
27878
28380
|
const rows = s.length === 0 ? 1 : s.length === 1 ? 1 : s[0];
|
|
27879
|
-
|
|
28381
|
+
let cols;
|
|
28382
|
+
if (s.length === 0) cols = 1;
|
|
28383
|
+
else if (s.length === 1) cols = s[0];
|
|
28384
|
+
else if (s.length === 2) cols = s[1];
|
|
28385
|
+
else {
|
|
28386
|
+
cols = 1;
|
|
28387
|
+
for (let k = 1; k < s.length; k++) cols *= s[k];
|
|
28388
|
+
}
|
|
27880
28389
|
const r = Math.round(ri) - 1;
|
|
27881
28390
|
const c = Math.round(ci) - 1;
|
|
27882
28391
|
if (r < 0 || r >= rows || c < 0 || c >= cols)
|
|
@@ -27886,6 +28395,7 @@ function index(rt, base, indices, nargout = 1, skipSubsref = false) {
|
|
|
27886
28395
|
const im2 = t.imag[lin];
|
|
27887
28396
|
return im2 === 0 ? t.data[lin] : RTV.complex(t.data[lin], im2);
|
|
27888
28397
|
}
|
|
28398
|
+
if (t._isLogical === true) return t.data[lin] !== 0;
|
|
27889
28399
|
return t.data[lin];
|
|
27890
28400
|
}
|
|
27891
28401
|
} else if (nIdx >= 3) {
|
|
@@ -28276,14 +28786,20 @@ function multiOutputCellAssign(base, indices, results) {
|
|
|
28276
28786
|
if (base === void 0 || base === null) base = RTV.cell([], [0, 0]);
|
|
28277
28787
|
let mv = ensureRuntimeValue(base);
|
|
28278
28788
|
if (!isRuntimeCell(mv)) mv = RTV.cell([], [0, 0]);
|
|
28279
|
-
const idxMv = ensureRuntimeValue(indices);
|
|
28280
28789
|
let idxArray;
|
|
28281
|
-
if (
|
|
28282
|
-
|
|
28283
|
-
|
|
28284
|
-
|
|
28790
|
+
if (indices === COLON_SENTINEL) {
|
|
28791
|
+
const n = mv.data.length;
|
|
28792
|
+
idxArray = [];
|
|
28793
|
+
for (let i = 1; i <= n; i++) idxArray.push(i);
|
|
28285
28794
|
} else {
|
|
28286
|
-
|
|
28795
|
+
const idxMv = ensureRuntimeValue(indices);
|
|
28796
|
+
if (isRuntimeTensor(idxMv)) {
|
|
28797
|
+
idxArray = Array.from(idxMv.data);
|
|
28798
|
+
} else if (isRuntimeNumber(idxMv)) {
|
|
28799
|
+
idxArray = [idxMv];
|
|
28800
|
+
} else {
|
|
28801
|
+
idxArray = [1];
|
|
28802
|
+
}
|
|
28287
28803
|
}
|
|
28288
28804
|
for (let i = 0; i < idxArray.length && i < results.length; i++) {
|
|
28289
28805
|
const idx = idxArray[i];
|
|
@@ -28294,225 +28810,6 @@ function multiOutputCellAssign(base, indices, results) {
|
|
|
28294
28810
|
return mv;
|
|
28295
28811
|
}
|
|
28296
28812
|
|
|
28297
|
-
// src/numbl-core/helpers/string.ts
|
|
28298
|
-
function numStr(n) {
|
|
28299
|
-
if (n === Infinity) return "Inf";
|
|
28300
|
-
if (n === -Infinity) return "-Inf";
|
|
28301
|
-
if (isNaN(n)) return "NaN";
|
|
28302
|
-
if (n === 0) return "0";
|
|
28303
|
-
const prec = 5;
|
|
28304
|
-
const exp = Math.floor(Math.log10(Math.abs(n)));
|
|
28305
|
-
let s;
|
|
28306
|
-
if (exp < -4 || exp >= prec) {
|
|
28307
|
-
s = n.toExponential(prec - 1);
|
|
28308
|
-
const ePos = s.indexOf("e");
|
|
28309
|
-
let mantissa = s.slice(0, ePos);
|
|
28310
|
-
const expPart0 = s.slice(ePos);
|
|
28311
|
-
if (mantissa.includes(".")) mantissa = mantissa.replace(/\.?0+$/, "");
|
|
28312
|
-
const expPart = expPart0.replace(/([eE][+-])(\d)$/, "$10$2");
|
|
28313
|
-
s = mantissa + expPart;
|
|
28314
|
-
} else {
|
|
28315
|
-
if (Number.isInteger(n)) return String(n);
|
|
28316
|
-
s = n.toPrecision(prec);
|
|
28317
|
-
if (s.includes(".")) s = s.replace(/\.?0+$/, "");
|
|
28318
|
-
}
|
|
28319
|
-
return s;
|
|
28320
|
-
}
|
|
28321
|
-
function applyWidth(spec, str) {
|
|
28322
|
-
const m = spec.match(/^%([-+ #]*)0?(\d+)?/);
|
|
28323
|
-
if (!m) return str;
|
|
28324
|
-
const explicitFlags = m[1] || "";
|
|
28325
|
-
const leftAlign = explicitFlags.includes("-");
|
|
28326
|
-
const afterPercent = spec.slice(1);
|
|
28327
|
-
const flagAndWidth = afterPercent.match(/^([-+ #]*)(0?)(\d+)?/);
|
|
28328
|
-
const zeroFlag = flagAndWidth ? flagAndWidth[2] === "0" : false;
|
|
28329
|
-
const width = flagAndWidth && flagAndWidth[3] ? parseInt(flagAndWidth[3]) : 0;
|
|
28330
|
-
if (width <= str.length) return str;
|
|
28331
|
-
const zeroPad = !leftAlign && zeroFlag;
|
|
28332
|
-
const padLen = width - str.length;
|
|
28333
|
-
if (leftAlign) return str + " ".repeat(padLen);
|
|
28334
|
-
if (zeroPad) {
|
|
28335
|
-
if (str[0] === "-" || str[0] === "+") {
|
|
28336
|
-
return str[0] + "0".repeat(padLen) + str.slice(1);
|
|
28337
|
-
}
|
|
28338
|
-
return "0".repeat(padLen) + str;
|
|
28339
|
-
}
|
|
28340
|
-
return " ".repeat(padLen) + str;
|
|
28341
|
-
}
|
|
28342
|
-
function sprintfFormat(fmt, args) {
|
|
28343
|
-
const flatArgs = [];
|
|
28344
|
-
for (const arg of args) {
|
|
28345
|
-
if (isRuntimeTensor(arg)) {
|
|
28346
|
-
for (let k = 0; k < arg.data.length; k++) {
|
|
28347
|
-
flatArgs.push(arg.data[k]);
|
|
28348
|
-
}
|
|
28349
|
-
} else {
|
|
28350
|
-
flatArgs.push(arg);
|
|
28351
|
-
}
|
|
28352
|
-
}
|
|
28353
|
-
let result = "";
|
|
28354
|
-
let argIdx = 0;
|
|
28355
|
-
do {
|
|
28356
|
-
const startArgIdx = argIdx;
|
|
28357
|
-
let outOfArgs = false;
|
|
28358
|
-
let i = 0;
|
|
28359
|
-
while (i < fmt.length && !outOfArgs) {
|
|
28360
|
-
if (fmt[i] === "%" && i + 1 < fmt.length) {
|
|
28361
|
-
i++;
|
|
28362
|
-
let spec = "%";
|
|
28363
|
-
while (i < fmt.length && !"dfigeEsoxXuc%".includes(fmt[i])) {
|
|
28364
|
-
spec += fmt[i];
|
|
28365
|
-
i++;
|
|
28366
|
-
}
|
|
28367
|
-
if (i < fmt.length) {
|
|
28368
|
-
const ch = fmt[i];
|
|
28369
|
-
i++;
|
|
28370
|
-
if (ch === "%") {
|
|
28371
|
-
result += "%";
|
|
28372
|
-
} else if (argIdx >= flatArgs.length) {
|
|
28373
|
-
outOfArgs = true;
|
|
28374
|
-
} else if (ch === "d" || ch === "i" || ch === "u") {
|
|
28375
|
-
const raw = toNumber(flatArgs[argIdx++]);
|
|
28376
|
-
const isInt = Number.isInteger(raw);
|
|
28377
|
-
const canPrintAsInt = ch === "u" ? isInt && raw >= 0 : isInt;
|
|
28378
|
-
if (!canPrintAsInt) {
|
|
28379
|
-
let eStr = raw.toExponential(6);
|
|
28380
|
-
eStr = eStr.replace(/e([+-])(\d)$/, "e$10$2");
|
|
28381
|
-
result += applyWidth(spec, eStr);
|
|
28382
|
-
} else {
|
|
28383
|
-
const n = raw;
|
|
28384
|
-
const flags = spec.slice(1);
|
|
28385
|
-
const hasPlus = flags.includes("+");
|
|
28386
|
-
const leftAlign = flags.includes("-");
|
|
28387
|
-
const widthMatch = spec.match(/^%[^0-9]*(\d+)/);
|
|
28388
|
-
const width = widthMatch ? parseInt(widthMatch[1]) : 0;
|
|
28389
|
-
const zeroPad = !leftAlign && /^[-+ ]*0/.test(spec.slice(1));
|
|
28390
|
-
const s = String(Math.abs(n));
|
|
28391
|
-
const sign = n < 0 ? "-" : hasPlus ? "+" : "";
|
|
28392
|
-
if (width > 0) {
|
|
28393
|
-
const padChar = zeroPad ? "0" : " ";
|
|
28394
|
-
const padLen = Math.max(0, width - sign.length - s.length);
|
|
28395
|
-
const pad = padChar.repeat(padLen);
|
|
28396
|
-
result += leftAlign ? sign + s + " ".repeat(padLen) : zeroPad ? sign + pad + s : pad + sign + s;
|
|
28397
|
-
} else {
|
|
28398
|
-
result += sign + s;
|
|
28399
|
-
}
|
|
28400
|
-
}
|
|
28401
|
-
} else if (ch === "f") {
|
|
28402
|
-
const n = toNumber(flatArgs[argIdx++]);
|
|
28403
|
-
if (!isFinite(n) || isNaN(n)) {
|
|
28404
|
-
result += applyWidth(spec, numStr(n));
|
|
28405
|
-
} else {
|
|
28406
|
-
const fFlags = spec.slice(1);
|
|
28407
|
-
const fHasPlus = fFlags.includes("+");
|
|
28408
|
-
const precMatch = spec.match(/\.(\d+)/);
|
|
28409
|
-
const prec = precMatch ? parseInt(precMatch[1]) : 6;
|
|
28410
|
-
const formatted = n.toFixed(prec);
|
|
28411
|
-
const fSign = n < 0 ? "" : fHasPlus ? "+" : "";
|
|
28412
|
-
result += applyWidth(spec, fSign + formatted);
|
|
28413
|
-
}
|
|
28414
|
-
} else if (ch === "e" || ch === "E") {
|
|
28415
|
-
const n = toNumber(flatArgs[argIdx++]);
|
|
28416
|
-
if (!isFinite(n) || isNaN(n)) {
|
|
28417
|
-
result += applyWidth(spec, numStr(n));
|
|
28418
|
-
} else {
|
|
28419
|
-
const precMatch = spec.match(/\.(\d+)/);
|
|
28420
|
-
const prec = precMatch ? parseInt(precMatch[1]) : 6;
|
|
28421
|
-
let eStr = n.toExponential(prec);
|
|
28422
|
-
eStr = eStr.replace(/e([+-])(\d)$/, "e$10$2");
|
|
28423
|
-
if (ch === "E") eStr = eStr.toUpperCase();
|
|
28424
|
-
result += applyWidth(spec, eStr);
|
|
28425
|
-
}
|
|
28426
|
-
} else if (ch === "x" || ch === "X") {
|
|
28427
|
-
const n = Math.round(toNumber(flatArgs[argIdx++]));
|
|
28428
|
-
let s = Math.abs(n).toString(16);
|
|
28429
|
-
if (ch === "X") s = s.toUpperCase();
|
|
28430
|
-
result += applyWidth(spec, s);
|
|
28431
|
-
} else if (ch === "o") {
|
|
28432
|
-
const n = Math.round(toNumber(flatArgs[argIdx++]));
|
|
28433
|
-
result += applyWidth(spec, Math.abs(n).toString(8));
|
|
28434
|
-
} else if (ch === "g" || ch === "G") {
|
|
28435
|
-
const gVal = toNumber(flatArgs[argIdx++]);
|
|
28436
|
-
if (!isFinite(gVal) || isNaN(gVal)) {
|
|
28437
|
-
result += applyWidth(spec, numStr(gVal));
|
|
28438
|
-
} else {
|
|
28439
|
-
const precMatch = spec.match(/\.(\d+)/);
|
|
28440
|
-
const gPrec = precMatch ? parseInt(precMatch[1]) : 6;
|
|
28441
|
-
let gStr;
|
|
28442
|
-
if (gVal === 0) {
|
|
28443
|
-
gStr = "0";
|
|
28444
|
-
} else {
|
|
28445
|
-
const exp = Math.floor(Math.log10(Math.abs(gVal)));
|
|
28446
|
-
if (exp < -4 || exp >= gPrec) {
|
|
28447
|
-
gStr = gVal.toExponential(gPrec - 1);
|
|
28448
|
-
const ePos = gStr.indexOf("e");
|
|
28449
|
-
let mantissa = gStr.slice(0, ePos);
|
|
28450
|
-
let expPart = gStr.slice(ePos);
|
|
28451
|
-
if (mantissa.includes(".")) {
|
|
28452
|
-
mantissa = mantissa.replace(/\.?0+$/, "");
|
|
28453
|
-
}
|
|
28454
|
-
expPart = expPart.replace(/e([+-])(\d)$/, "e$10$2");
|
|
28455
|
-
gStr = mantissa + expPart;
|
|
28456
|
-
} else {
|
|
28457
|
-
gStr = gVal.toPrecision(gPrec);
|
|
28458
|
-
if (gStr.includes(".")) {
|
|
28459
|
-
gStr = gStr.replace(/\.?0+$/, "");
|
|
28460
|
-
}
|
|
28461
|
-
if (gStr.includes("e")) {
|
|
28462
|
-
gStr = String(parseFloat(gStr));
|
|
28463
|
-
}
|
|
28464
|
-
}
|
|
28465
|
-
}
|
|
28466
|
-
if (ch === "G") gStr = gStr.toUpperCase();
|
|
28467
|
-
result += applyWidth(spec, gStr);
|
|
28468
|
-
}
|
|
28469
|
-
} else if (ch === "s") {
|
|
28470
|
-
const sVal = toString(flatArgs[argIdx++]);
|
|
28471
|
-
const sFlags = spec.slice(1);
|
|
28472
|
-
const sLeftAlign = sFlags.includes("-");
|
|
28473
|
-
const sWidthMatch = spec.match(/^%[^0-9]*(\d+)/);
|
|
28474
|
-
const sWidth = sWidthMatch ? parseInt(sWidthMatch[1]) : 0;
|
|
28475
|
-
if (sWidth > sVal.length) {
|
|
28476
|
-
const sPad = " ".repeat(sWidth - sVal.length);
|
|
28477
|
-
result += sLeftAlign ? sVal + sPad : sPad + sVal;
|
|
28478
|
-
} else {
|
|
28479
|
-
result += sVal;
|
|
28480
|
-
}
|
|
28481
|
-
} else if (ch === "c") {
|
|
28482
|
-
result += String.fromCharCode(
|
|
28483
|
-
Math.round(toNumber(flatArgs[argIdx++]))
|
|
28484
|
-
);
|
|
28485
|
-
} else {
|
|
28486
|
-
result += spec + ch;
|
|
28487
|
-
argIdx++;
|
|
28488
|
-
}
|
|
28489
|
-
}
|
|
28490
|
-
} else if (fmt[i] === "\\" && i + 1 < fmt.length) {
|
|
28491
|
-
i++;
|
|
28492
|
-
switch (fmt[i]) {
|
|
28493
|
-
case "n":
|
|
28494
|
-
result += "\n";
|
|
28495
|
-
break;
|
|
28496
|
-
case "t":
|
|
28497
|
-
result += " ";
|
|
28498
|
-
break;
|
|
28499
|
-
case "\\":
|
|
28500
|
-
result += "\\";
|
|
28501
|
-
break;
|
|
28502
|
-
default:
|
|
28503
|
-
result += "\\" + fmt[i];
|
|
28504
|
-
}
|
|
28505
|
-
i++;
|
|
28506
|
-
} else {
|
|
28507
|
-
result += fmt[i];
|
|
28508
|
-
i++;
|
|
28509
|
-
}
|
|
28510
|
-
}
|
|
28511
|
-
if (argIdx === startArgIdx) break;
|
|
28512
|
-
} while (argIdx < flatArgs.length);
|
|
28513
|
-
return result;
|
|
28514
|
-
}
|
|
28515
|
-
|
|
28516
28813
|
// src/numbl-core/interpreter/builtins/misc.ts
|
|
28517
28814
|
registerIBuiltin({
|
|
28518
28815
|
name: "substruct",
|
|
@@ -28565,6 +28862,44 @@ registerIBuiltin({
|
|
|
28565
28862
|
}
|
|
28566
28863
|
})
|
|
28567
28864
|
});
|
|
28865
|
+
var WEBOPTIONS_DEFAULTS = {
|
|
28866
|
+
CharacterEncoding: RTV.char("auto"),
|
|
28867
|
+
UserAgent: RTV.char("numbl"),
|
|
28868
|
+
Timeout: 5,
|
|
28869
|
+
Username: RTV.char(""),
|
|
28870
|
+
Password: RTV.char(""),
|
|
28871
|
+
KeyName: RTV.char(""),
|
|
28872
|
+
KeyValue: RTV.char(""),
|
|
28873
|
+
ContentType: RTV.char("auto"),
|
|
28874
|
+
MediaType: RTV.char("auto"),
|
|
28875
|
+
RequestMethod: RTV.char("auto"),
|
|
28876
|
+
ArrayFormat: RTV.char("csv"),
|
|
28877
|
+
CertificateFilename: RTV.char("default")
|
|
28878
|
+
};
|
|
28879
|
+
registerIBuiltin({
|
|
28880
|
+
name: "weboptions",
|
|
28881
|
+
resolve: () => ({
|
|
28882
|
+
outputTypes: [{ kind: "struct" }],
|
|
28883
|
+
apply: (args) => {
|
|
28884
|
+
const fields = /* @__PURE__ */ new Map();
|
|
28885
|
+
for (const [k, v] of Object.entries(WEBOPTIONS_DEFAULTS)) {
|
|
28886
|
+
fields.set(k, v);
|
|
28887
|
+
}
|
|
28888
|
+
if (args.length % 2 !== 0)
|
|
28889
|
+
throw new RuntimeError("weboptions: expected name-value pairs");
|
|
28890
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
28891
|
+
const key = args[i];
|
|
28892
|
+
if (!isRuntimeChar(key) && !isRuntimeString(key))
|
|
28893
|
+
throw new RuntimeError("weboptions: option name must be a string");
|
|
28894
|
+
const name = isRuntimeChar(key) ? key.value : key;
|
|
28895
|
+
if (!(name in WEBOPTIONS_DEFAULTS))
|
|
28896
|
+
throw new RuntimeError(`weboptions: unknown option '${name}'`);
|
|
28897
|
+
fields.set(name, args[i + 1]);
|
|
28898
|
+
}
|
|
28899
|
+
return RTV.struct(Object.fromEntries(fields));
|
|
28900
|
+
}
|
|
28901
|
+
})
|
|
28902
|
+
});
|
|
28568
28903
|
registerIBuiltin({
|
|
28569
28904
|
name: "odeget",
|
|
28570
28905
|
resolve: () => ({
|
|
@@ -28674,7 +29009,7 @@ for (const name of ["clear", "clc", "clf"]) {
|
|
|
28674
29009
|
name,
|
|
28675
29010
|
resolve: () => ({
|
|
28676
29011
|
outputTypes: [],
|
|
28677
|
-
apply: () => 0
|
|
29012
|
+
apply: () => void 0
|
|
28678
29013
|
})
|
|
28679
29014
|
});
|
|
28680
29015
|
}
|
|
@@ -28808,7 +29143,7 @@ registerIBuiltin({
|
|
|
28808
29143
|
name: "set",
|
|
28809
29144
|
resolve: () => ({
|
|
28810
29145
|
outputTypes: [],
|
|
28811
|
-
apply: () => 0
|
|
29146
|
+
apply: () => void 0
|
|
28812
29147
|
})
|
|
28813
29148
|
});
|
|
28814
29149
|
for (const name of [
|
|
@@ -28830,7 +29165,7 @@ for (const name of [
|
|
|
28830
29165
|
name,
|
|
28831
29166
|
resolve: () => ({
|
|
28832
29167
|
outputTypes: [],
|
|
28833
|
-
apply: () => 0
|
|
29168
|
+
apply: () => void 0
|
|
28834
29169
|
})
|
|
28835
29170
|
});
|
|
28836
29171
|
}
|
|
@@ -29119,6 +29454,148 @@ registerIBuiltin({
|
|
|
29119
29454
|
}
|
|
29120
29455
|
});
|
|
29121
29456
|
|
|
29457
|
+
// src/numbl-core/interpreter/builtins/time-system.ts
|
|
29458
|
+
var ticTime = 0;
|
|
29459
|
+
function getTicTime() {
|
|
29460
|
+
return ticTime;
|
|
29461
|
+
}
|
|
29462
|
+
defineBuiltin({
|
|
29463
|
+
name: "tic",
|
|
29464
|
+
cases: [
|
|
29465
|
+
{
|
|
29466
|
+
match: (argTypes) => argTypes.length === 0 ? [{ kind: "number" }] : null,
|
|
29467
|
+
apply: () => {
|
|
29468
|
+
ticTime = performance.now();
|
|
29469
|
+
return RTV.num(ticTime / 1e3);
|
|
29470
|
+
}
|
|
29471
|
+
}
|
|
29472
|
+
]
|
|
29473
|
+
});
|
|
29474
|
+
defineBuiltin({
|
|
29475
|
+
name: "clock",
|
|
29476
|
+
cases: [
|
|
29477
|
+
{
|
|
29478
|
+
match: (argTypes) => argTypes.length === 0 ? [{ kind: "tensor", isComplex: false, shape: [1, 6] }] : null,
|
|
29479
|
+
apply: () => {
|
|
29480
|
+
const now = /* @__PURE__ */ new Date();
|
|
29481
|
+
return RTV.tensor(
|
|
29482
|
+
new FloatXArray([
|
|
29483
|
+
now.getFullYear(),
|
|
29484
|
+
now.getMonth() + 1,
|
|
29485
|
+
now.getDate(),
|
|
29486
|
+
now.getHours(),
|
|
29487
|
+
now.getMinutes(),
|
|
29488
|
+
now.getSeconds() + now.getMilliseconds() / 1e3
|
|
29489
|
+
]),
|
|
29490
|
+
[1, 6]
|
|
29491
|
+
);
|
|
29492
|
+
}
|
|
29493
|
+
}
|
|
29494
|
+
]
|
|
29495
|
+
});
|
|
29496
|
+
defineBuiltin({
|
|
29497
|
+
name: "etime",
|
|
29498
|
+
cases: [
|
|
29499
|
+
{
|
|
29500
|
+
match: (argTypes) => argTypes.length === 2 ? [{ kind: "number" }] : null,
|
|
29501
|
+
apply: (args) => {
|
|
29502
|
+
const t1 = args[0];
|
|
29503
|
+
const t0 = args[1];
|
|
29504
|
+
if (!isRuntimeTensor(t1) || !isRuntimeTensor(t0))
|
|
29505
|
+
throw new RuntimeError("etime: arguments must be clock vectors");
|
|
29506
|
+
const toMs = (t) => {
|
|
29507
|
+
const d = new Date(
|
|
29508
|
+
t.data[0],
|
|
29509
|
+
t.data[1] - 1,
|
|
29510
|
+
t.data[2],
|
|
29511
|
+
t.data[3],
|
|
29512
|
+
t.data[4],
|
|
29513
|
+
Math.floor(t.data[5]),
|
|
29514
|
+
t.data[5] % 1 * 1e3
|
|
29515
|
+
);
|
|
29516
|
+
return d.getTime();
|
|
29517
|
+
};
|
|
29518
|
+
return RTV.num((toMs(t1) - toMs(t0)) / 1e3);
|
|
29519
|
+
}
|
|
29520
|
+
}
|
|
29521
|
+
]
|
|
29522
|
+
});
|
|
29523
|
+
defineBuiltin({
|
|
29524
|
+
name: "version",
|
|
29525
|
+
cases: [
|
|
29526
|
+
{
|
|
29527
|
+
match: (argTypes) => argTypes.length === 0 ? [{ kind: "char" }] : null,
|
|
29528
|
+
apply: () => RTV.char("9.14.0")
|
|
29529
|
+
}
|
|
29530
|
+
]
|
|
29531
|
+
});
|
|
29532
|
+
function getComputerStrings() {
|
|
29533
|
+
if (typeof process === "undefined") {
|
|
29534
|
+
return { str: "BROWSER", arch: "browser" };
|
|
29535
|
+
}
|
|
29536
|
+
const platform = process.platform;
|
|
29537
|
+
const cpuArch = process.arch;
|
|
29538
|
+
if (platform === "win32") return { str: "PCWIN64", arch: "win64" };
|
|
29539
|
+
if (platform === "darwin") {
|
|
29540
|
+
if (cpuArch === "arm64") return { str: "MACA64", arch: "maca64" };
|
|
29541
|
+
return { str: "MACI64", arch: "maci64" };
|
|
29542
|
+
}
|
|
29543
|
+
return { str: "GLNXA64", arch: "glnxa64" };
|
|
29544
|
+
}
|
|
29545
|
+
registerIBuiltin({
|
|
29546
|
+
name: "computer",
|
|
29547
|
+
resolve: () => ({
|
|
29548
|
+
outputTypes: [{ kind: "unknown" }],
|
|
29549
|
+
apply: (args, nargout) => {
|
|
29550
|
+
const info = getComputerStrings();
|
|
29551
|
+
if (args.length >= 1 && isRuntimeChar(args[0])) {
|
|
29552
|
+
const arg = toString(args[0]);
|
|
29553
|
+
if (arg === "arch") return RTV.char(info.arch);
|
|
29554
|
+
throw new RuntimeError(`computer: unknown argument '${arg}'`);
|
|
29555
|
+
}
|
|
29556
|
+
const maxsize = 2 ** 48 - 1;
|
|
29557
|
+
const endian = RTV.char("L");
|
|
29558
|
+
if (nargout <= 1) return RTV.char(info.str);
|
|
29559
|
+
if (nargout === 2) return [RTV.char(info.str), RTV.num(maxsize)];
|
|
29560
|
+
return [RTV.char(info.str), RTV.num(maxsize), endian];
|
|
29561
|
+
}
|
|
29562
|
+
})
|
|
29563
|
+
});
|
|
29564
|
+
function getMexExt() {
|
|
29565
|
+
if (typeof process === "undefined") return "";
|
|
29566
|
+
const platform = process.platform;
|
|
29567
|
+
const cpuArch = process.arch;
|
|
29568
|
+
if (platform === "win32") return "mexw64";
|
|
29569
|
+
if (platform === "darwin")
|
|
29570
|
+
return cpuArch === "arm64" ? "mexmaca64" : "mexmaci64";
|
|
29571
|
+
return "mexa64";
|
|
29572
|
+
}
|
|
29573
|
+
defineBuiltin({
|
|
29574
|
+
name: "mexext",
|
|
29575
|
+
cases: [
|
|
29576
|
+
{
|
|
29577
|
+
match: (argTypes) => argTypes.length === 0 ? [{ kind: "char" }] : null,
|
|
29578
|
+
apply: () => RTV.char(getMexExt())
|
|
29579
|
+
}
|
|
29580
|
+
]
|
|
29581
|
+
});
|
|
29582
|
+
var _platform = typeof process !== "undefined" ? process.platform : "linux";
|
|
29583
|
+
for (const [name, val] of [
|
|
29584
|
+
["ismac", _platform === "darwin"],
|
|
29585
|
+
["ispc", _platform === "win32"],
|
|
29586
|
+
["isunix", _platform !== "win32"]
|
|
29587
|
+
]) {
|
|
29588
|
+
defineBuiltin({
|
|
29589
|
+
name,
|
|
29590
|
+
cases: [
|
|
29591
|
+
{
|
|
29592
|
+
match: (argTypes) => argTypes.length === 0 ? [{ kind: "boolean" }] : null,
|
|
29593
|
+
apply: () => RTV.logical(val)
|
|
29594
|
+
}
|
|
29595
|
+
]
|
|
29596
|
+
});
|
|
29597
|
+
}
|
|
29598
|
+
|
|
29122
29599
|
// src/numbl-core/runtime/plotUtils.ts
|
|
29123
29600
|
var COLOR_SHORT = {
|
|
29124
29601
|
r: [1, 0, 0],
|
|
@@ -31351,6 +31828,114 @@ function bisectEvent(eventIdx, step, events) {
|
|
|
31351
31828
|
return [tOld + xFinal * h, denseOutputEval(yOld, Q, h, xFinal)];
|
|
31352
31829
|
}
|
|
31353
31830
|
|
|
31831
|
+
// src/numbl-core/helpers/quadgk.ts
|
|
31832
|
+
var XK = [
|
|
31833
|
+
-0.9914553711208126,
|
|
31834
|
+
-0.9491079123427585,
|
|
31835
|
+
-0.8648644233597691,
|
|
31836
|
+
-0.7415311855993945,
|
|
31837
|
+
-0.586087235467691,
|
|
31838
|
+
-0.4058451513773972,
|
|
31839
|
+
-0.2077849550078985,
|
|
31840
|
+
0,
|
|
31841
|
+
0.2077849550078985,
|
|
31842
|
+
0.4058451513773972,
|
|
31843
|
+
0.586087235467691,
|
|
31844
|
+
0.7415311855993945,
|
|
31845
|
+
0.8648644233597691,
|
|
31846
|
+
0.9491079123427585,
|
|
31847
|
+
0.9914553711208126
|
|
31848
|
+
];
|
|
31849
|
+
var WK = [
|
|
31850
|
+
0.0229353220105292,
|
|
31851
|
+
0.0630920926299786,
|
|
31852
|
+
0.1047900103222502,
|
|
31853
|
+
0.1406532597155259,
|
|
31854
|
+
0.1690047266392679,
|
|
31855
|
+
0.1903505780647854,
|
|
31856
|
+
0.2044329400752989,
|
|
31857
|
+
0.2094821410847278,
|
|
31858
|
+
0.2044329400752989,
|
|
31859
|
+
0.1903505780647854,
|
|
31860
|
+
0.1690047266392679,
|
|
31861
|
+
0.1406532597155259,
|
|
31862
|
+
0.1047900103222502,
|
|
31863
|
+
0.0630920926299786,
|
|
31864
|
+
0.0229353220105292
|
|
31865
|
+
];
|
|
31866
|
+
var WG = [
|
|
31867
|
+
0.1294849661688697,
|
|
31868
|
+
0.2797053914892767,
|
|
31869
|
+
0.3818300505051189,
|
|
31870
|
+
0.4179591836734694,
|
|
31871
|
+
0.3818300505051189,
|
|
31872
|
+
0.2797053914892767,
|
|
31873
|
+
0.1294849661688697
|
|
31874
|
+
];
|
|
31875
|
+
function kronrodNodes(lo, hi) {
|
|
31876
|
+
const m = (lo + hi) / 2;
|
|
31877
|
+
const h = (hi - lo) / 2;
|
|
31878
|
+
const out = new Array(15);
|
|
31879
|
+
for (let i = 0; i < 15; i++) out[i] = m + h * XK[i];
|
|
31880
|
+
return out;
|
|
31881
|
+
}
|
|
31882
|
+
function segmentEstimate(lo, hi, fv) {
|
|
31883
|
+
const h = (hi - lo) / 2;
|
|
31884
|
+
let K = 0;
|
|
31885
|
+
let G = 0;
|
|
31886
|
+
for (let i = 0; i < 15; i++) K += WK[i] * fv[i];
|
|
31887
|
+
for (let i = 0; i < 7; i++) G += WG[i] * fv[2 * i + 1];
|
|
31888
|
+
K *= h;
|
|
31889
|
+
G *= h;
|
|
31890
|
+
return { K, err: Math.abs(K - G) };
|
|
31891
|
+
}
|
|
31892
|
+
function quadgkAdaptive(integrand, a, b, opts = {}) {
|
|
31893
|
+
const relTol = opts.relTol ?? 1e-6;
|
|
31894
|
+
const absTol = opts.absTol ?? 1e-10;
|
|
31895
|
+
const maxIntervals = opts.maxIntervalCount ?? 650;
|
|
31896
|
+
if (a === b) return { value: 0, errbnd: 0, intervalsUsed: 0 };
|
|
31897
|
+
const sign = a < b ? 1 : -1;
|
|
31898
|
+
const lo0 = Math.min(a, b);
|
|
31899
|
+
const hi0 = Math.max(a, b);
|
|
31900
|
+
const segmentOn = (lo, hi) => {
|
|
31901
|
+
const pts = kronrodNodes(lo, hi);
|
|
31902
|
+
const fv = integrand(pts);
|
|
31903
|
+
if (fv.length !== 15) {
|
|
31904
|
+
throw new Error(
|
|
31905
|
+
`quadgk: integrand must return 15 values for 15 nodes, got ${fv.length}`
|
|
31906
|
+
);
|
|
31907
|
+
}
|
|
31908
|
+
return segmentEstimate(lo, hi, fv);
|
|
31909
|
+
};
|
|
31910
|
+
const initial = segmentOn(lo0, hi0);
|
|
31911
|
+
let totalK = initial.K;
|
|
31912
|
+
let totalErr = initial.err;
|
|
31913
|
+
const worklist = [{ lo: lo0, hi: hi0, ...initial }];
|
|
31914
|
+
const converged = () => totalErr <= Math.max(absTol, relTol * Math.abs(totalK));
|
|
31915
|
+
let iters = 0;
|
|
31916
|
+
while (!converged() && worklist.length < maxIntervals && iters < 1e4) {
|
|
31917
|
+
iters++;
|
|
31918
|
+
let worstIdx = 0;
|
|
31919
|
+
for (let i = 1; i < worklist.length; i++) {
|
|
31920
|
+
if (worklist[i].err > worklist[worstIdx].err) worstIdx = i;
|
|
31921
|
+
}
|
|
31922
|
+
const worst = worklist[worstIdx];
|
|
31923
|
+
if (worst.hi - worst.lo <= 1e-15 * (hi0 - lo0)) break;
|
|
31924
|
+
const mid = (worst.lo + worst.hi) / 2;
|
|
31925
|
+
const s1 = segmentOn(worst.lo, mid);
|
|
31926
|
+
const s2 = segmentOn(mid, worst.hi);
|
|
31927
|
+
totalK += s1.K + s2.K - worst.K;
|
|
31928
|
+
totalErr += s1.err + s2.err - worst.err;
|
|
31929
|
+
worklist[worstIdx] = { lo: worst.lo, hi: mid, ...s1 };
|
|
31930
|
+
worklist.push({ lo: mid, hi: worst.hi, ...s2 });
|
|
31931
|
+
}
|
|
31932
|
+
return {
|
|
31933
|
+
value: sign * totalK,
|
|
31934
|
+
errbnd: totalErr,
|
|
31935
|
+
intervalsUsed: worklist.length
|
|
31936
|
+
};
|
|
31937
|
+
}
|
|
31938
|
+
|
|
31354
31939
|
// src/numbl-core/runtime/specialBuiltinNames.ts
|
|
31355
31940
|
var SPECIAL_BUILTIN_NAMES = [
|
|
31356
31941
|
"help",
|
|
@@ -31439,6 +32024,7 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
31439
32024
|
"webread",
|
|
31440
32025
|
"delete",
|
|
31441
32026
|
"rmdir",
|
|
32027
|
+
"movefile",
|
|
31442
32028
|
"unzip",
|
|
31443
32029
|
"dir",
|
|
31444
32030
|
"warning",
|
|
@@ -31451,7 +32037,9 @@ var SPECIAL_BUILTIN_NAMES = [
|
|
|
31451
32037
|
"cd",
|
|
31452
32038
|
"ode45",
|
|
31453
32039
|
"ode23",
|
|
31454
|
-
"deval"
|
|
32040
|
+
"deval",
|
|
32041
|
+
"toc",
|
|
32042
|
+
"quadgk"
|
|
31455
32043
|
];
|
|
31456
32044
|
|
|
31457
32045
|
// src/numbl-core/runtime/specialBuiltins.ts
|
|
@@ -31465,49 +32053,74 @@ function registerSpecial(name, fn) {
|
|
|
31465
32053
|
})
|
|
31466
32054
|
});
|
|
31467
32055
|
}
|
|
32056
|
+
function registerSpecialVoid(name, fn) {
|
|
32057
|
+
registerDynamicIBuiltin({
|
|
32058
|
+
name,
|
|
32059
|
+
resolve: () => ({
|
|
32060
|
+
outputTypes: [],
|
|
32061
|
+
apply: (args) => {
|
|
32062
|
+
fn(args);
|
|
32063
|
+
return void 0;
|
|
32064
|
+
}
|
|
32065
|
+
})
|
|
32066
|
+
});
|
|
32067
|
+
}
|
|
31468
32068
|
function registerSpecialBuiltins(rt) {
|
|
31469
|
-
registerSpecial("help", (
|
|
32069
|
+
registerSpecial("help", (nargout, args) => {
|
|
32070
|
+
let text = "";
|
|
32071
|
+
const emit = (s) => {
|
|
32072
|
+
text += s;
|
|
32073
|
+
if (nargout === 0) rt.output(s);
|
|
32074
|
+
};
|
|
31470
32075
|
if (args.length === 0) {
|
|
31471
32076
|
const names = getAllBuiltinNames().sort();
|
|
31472
|
-
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
|
|
31482
|
-
rt.output(`No help available for '${name}'.
|
|
32077
|
+
emit("Available builtins:\n");
|
|
32078
|
+
emit(" " + names.join(", ") + "\n");
|
|
32079
|
+
emit("\nType 'help <name>' for help on a specific builtin.\n");
|
|
32080
|
+
} else {
|
|
32081
|
+
const name = toString(args[0]);
|
|
32082
|
+
const h = getIBuiltinHelp(name);
|
|
32083
|
+
if (!h) {
|
|
32084
|
+
const allNames = getAllBuiltinNames();
|
|
32085
|
+
if (allNames.includes(name)) {
|
|
32086
|
+
emit(`No help available for '${name}'.
|
|
31483
32087
|
`);
|
|
31484
|
-
|
|
31485
|
-
|
|
32088
|
+
} else {
|
|
32089
|
+
emit(`Unknown function '${name}'.
|
|
31486
32090
|
`);
|
|
31487
|
-
|
|
31488
|
-
|
|
31489
|
-
|
|
31490
|
-
rt.output(` ${h.signatures.join("\n ")}
|
|
32091
|
+
}
|
|
32092
|
+
} else {
|
|
32093
|
+
emit(` ${h.signatures.join("\n ")}
|
|
31491
32094
|
|
|
31492
32095
|
`);
|
|
31493
|
-
|
|
32096
|
+
emit(`${h.description}
|
|
31494
32097
|
`);
|
|
31495
|
-
|
|
32098
|
+
}
|
|
32099
|
+
}
|
|
32100
|
+
return nargout >= 1 ? RTV.char(text) : void 0;
|
|
31496
32101
|
});
|
|
31497
|
-
|
|
32102
|
+
registerSpecialVoid("disp", (args) => {
|
|
31498
32103
|
if (args.length >= 1) {
|
|
31499
32104
|
const mv = ensureRuntimeValue(args[0]);
|
|
31500
|
-
if (isRuntimeTensor(mv) && mv.data.length === 0) return
|
|
32105
|
+
if (isRuntimeTensor(mv) && mv.data.length === 0) return;
|
|
31501
32106
|
rt.output(displayValue(mv) + "\n");
|
|
31502
32107
|
}
|
|
31503
|
-
return 0;
|
|
31504
32108
|
});
|
|
31505
|
-
registerSpecial("
|
|
31506
|
-
|
|
32109
|
+
registerSpecial("toc", (nargout) => {
|
|
32110
|
+
const elapsed = (performance.now() - getTicTime()) / 1e3;
|
|
32111
|
+
if (nargout === 0) {
|
|
32112
|
+
rt.output(`Elapsed time is ${elapsed.toFixed(6)} seconds.
|
|
32113
|
+
`);
|
|
32114
|
+
}
|
|
32115
|
+
return RTV.num(elapsed);
|
|
32116
|
+
});
|
|
32117
|
+
registerSpecial("warning", (nargout, args) => {
|
|
32118
|
+
if (args.length === 0) return nargout >= 1 ? RTV.num(0) : void 0;
|
|
31507
32119
|
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
31508
32120
|
if (margs.length === 2 && isRuntimeChar(margs[0]) && isRuntimeChar(margs[1])) {
|
|
31509
32121
|
const state = toString(margs[0]);
|
|
31510
32122
|
if (state === "on" || state === "off") {
|
|
32123
|
+
if (nargout === 0) return void 0;
|
|
31511
32124
|
return RTV.struct(
|
|
31512
32125
|
/* @__PURE__ */ new Map([
|
|
31513
32126
|
["state", RTV.char("on")],
|
|
@@ -31536,9 +32149,9 @@ function registerSpecialBuiltins(rt) {
|
|
|
31536
32149
|
} else {
|
|
31537
32150
|
rt.output("Warning: " + sprintfFormat(fmt, fmtArgs) + "\n");
|
|
31538
32151
|
}
|
|
31539
|
-
return RTV.num(0);
|
|
32152
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
31540
32153
|
});
|
|
31541
|
-
registerSpecial("fprintf", (
|
|
32154
|
+
registerSpecial("fprintf", (nargout, args) => {
|
|
31542
32155
|
let output = "";
|
|
31543
32156
|
if (args.length >= 1) {
|
|
31544
32157
|
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
@@ -31549,27 +32162,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
31549
32162
|
fmtIdx = 1;
|
|
31550
32163
|
}
|
|
31551
32164
|
const fmt = toString(margs[fmtIdx]);
|
|
31552
|
-
|
|
31553
|
-
for (let i = fmtIdx + 1; i < margs.length; i++) {
|
|
31554
|
-
const a = margs[i];
|
|
31555
|
-
if (isRuntimeTensor(a)) {
|
|
31556
|
-
for (let j = 0; j < a.data.length; j++)
|
|
31557
|
-
scalarArgs.push(RTV.num(a.data[j]));
|
|
31558
|
-
} else {
|
|
31559
|
-
scalarArgs.push(a);
|
|
31560
|
-
}
|
|
31561
|
-
}
|
|
31562
|
-
const specCount = (fmt.match(/%[^%]/g) || []).length;
|
|
31563
|
-
if (specCount === 0 || scalarArgs.length === 0) {
|
|
31564
|
-
output = sprintfFormat(fmt, scalarArgs);
|
|
31565
|
-
} else {
|
|
31566
|
-
let idx = 0;
|
|
31567
|
-
while (idx < scalarArgs.length) {
|
|
31568
|
-
const batch = scalarArgs.slice(idx, idx + specCount);
|
|
31569
|
-
output += sprintfFormat(fmt, batch);
|
|
31570
|
-
idx += specCount;
|
|
31571
|
-
}
|
|
31572
|
-
}
|
|
32165
|
+
output = sprintfFormat(fmt, margs.slice(fmtIdx + 1));
|
|
31573
32166
|
if (fid === 1 || fid === 2) {
|
|
31574
32167
|
rt.output(output);
|
|
31575
32168
|
} else {
|
|
@@ -31580,7 +32173,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
31580
32173
|
rt.fileIO.fwrite(fid, output);
|
|
31581
32174
|
}
|
|
31582
32175
|
}
|
|
31583
|
-
return output.length;
|
|
32176
|
+
return nargout >= 1 ? output.length : void 0;
|
|
31584
32177
|
});
|
|
31585
32178
|
registerSpecial("arrayfun", (nargout, args) => {
|
|
31586
32179
|
return arrayfunImpl(rt, nargout, args);
|
|
@@ -31612,6 +32205,55 @@ function registerSpecialBuiltins(rt) {
|
|
|
31612
32205
|
registerSpecial("bsxfun", (nargout, args) => {
|
|
31613
32206
|
return bsxfunImpl(rt, nargout, args);
|
|
31614
32207
|
});
|
|
32208
|
+
registerSpecial("quadgk", (nargout, args) => {
|
|
32209
|
+
if (args.length < 3)
|
|
32210
|
+
throw new RuntimeError(
|
|
32211
|
+
"quadgk: requires at least 3 arguments (fun, a, b)"
|
|
32212
|
+
);
|
|
32213
|
+
const fnArg = ensureRuntimeValue(args[0]);
|
|
32214
|
+
if (!isRuntimeFunction(fnArg))
|
|
32215
|
+
throw new RuntimeError("quadgk: first argument must be a function");
|
|
32216
|
+
const a = toNumber(ensureRuntimeValue(args[1]));
|
|
32217
|
+
const b = toNumber(ensureRuntimeValue(args[2]));
|
|
32218
|
+
let relTol;
|
|
32219
|
+
let absTol;
|
|
32220
|
+
let maxIntervalCount;
|
|
32221
|
+
for (let i = 3; i + 1 < args.length; i += 2) {
|
|
32222
|
+
const keyRv = ensureRuntimeValue(args[i]);
|
|
32223
|
+
const key = isRuntimeChar(keyRv) ? keyRv.value : isRuntimeString(keyRv) ? keyRv : "";
|
|
32224
|
+
const lowerKey = key.toLowerCase();
|
|
32225
|
+
const valRv = ensureRuntimeValue(args[i + 1]);
|
|
32226
|
+
if (lowerKey === "reltol") relTol = toNumber(valRv);
|
|
32227
|
+
else if (lowerKey === "abstol") absTol = toNumber(valRv);
|
|
32228
|
+
else if (lowerKey === "maxintervalcount")
|
|
32229
|
+
maxIntervalCount = toNumber(valRv);
|
|
32230
|
+
}
|
|
32231
|
+
const integrand = (pts) => {
|
|
32232
|
+
const vecData = new FloatXArray(pts);
|
|
32233
|
+
const vec = RTV.tensor(vecData, [1, pts.length]);
|
|
32234
|
+
const resultRaw = rt.index(fnArg, [vec], 1);
|
|
32235
|
+
const rv = ensureRuntimeValue(resultRaw);
|
|
32236
|
+
if (isRuntimeNumber(rv)) {
|
|
32237
|
+
return new Array(pts.length).fill(rv);
|
|
32238
|
+
}
|
|
32239
|
+
if (isRuntimeTensor(rv)) {
|
|
32240
|
+
if (rv.data.length !== pts.length) {
|
|
32241
|
+
throw new RuntimeError(
|
|
32242
|
+
`quadgk: integrand returned ${rv.data.length} values for ${pts.length} nodes`
|
|
32243
|
+
);
|
|
32244
|
+
}
|
|
32245
|
+
return Array.from(rv.data);
|
|
32246
|
+
}
|
|
32247
|
+
throw new RuntimeError("quadgk: integrand must return a numeric vector");
|
|
32248
|
+
};
|
|
32249
|
+
const result = quadgkAdaptive(integrand, a, b, {
|
|
32250
|
+
relTol,
|
|
32251
|
+
absTol,
|
|
32252
|
+
maxIntervalCount
|
|
32253
|
+
});
|
|
32254
|
+
if (nargout >= 2) return [result.value, result.errbnd];
|
|
32255
|
+
return result.value;
|
|
32256
|
+
});
|
|
31615
32257
|
registerSpecial("subsref", (nargout, args) => {
|
|
31616
32258
|
return subsrefBuiltin(rt, nargout, args);
|
|
31617
32259
|
});
|
|
@@ -32140,6 +32782,40 @@ function registerSpecialBuiltins(rt) {
|
|
|
32140
32782
|
RTV.char("")
|
|
32141
32783
|
];
|
|
32142
32784
|
});
|
|
32785
|
+
function extractWebOptions(arg) {
|
|
32786
|
+
if (!isRuntimeStruct(arg)) return void 0;
|
|
32787
|
+
const s = arg;
|
|
32788
|
+
if (!s.fields.has("Timeout")) return void 0;
|
|
32789
|
+
const opts = {};
|
|
32790
|
+
const t = s.fields.get("Timeout");
|
|
32791
|
+
if (t !== void 0) opts.timeout = toNumber(t);
|
|
32792
|
+
const rm = s.fields.get("RequestMethod");
|
|
32793
|
+
if (rm !== void 0) {
|
|
32794
|
+
const v = toString(rm);
|
|
32795
|
+
if (v !== "auto") opts.requestMethod = v;
|
|
32796
|
+
}
|
|
32797
|
+
const un = s.fields.get("Username");
|
|
32798
|
+
if (un !== void 0) {
|
|
32799
|
+
const v = toString(un);
|
|
32800
|
+
if (v) opts.username = v;
|
|
32801
|
+
}
|
|
32802
|
+
const pw = s.fields.get("Password");
|
|
32803
|
+
if (pw !== void 0) {
|
|
32804
|
+
const v = toString(pw);
|
|
32805
|
+
if (v) opts.password = v;
|
|
32806
|
+
}
|
|
32807
|
+
const kn = s.fields.get("KeyName");
|
|
32808
|
+
if (kn !== void 0) {
|
|
32809
|
+
const v = toString(kn);
|
|
32810
|
+
if (v) opts.keyName = v;
|
|
32811
|
+
}
|
|
32812
|
+
const kv = s.fields.get("KeyValue");
|
|
32813
|
+
if (kv !== void 0) {
|
|
32814
|
+
const v = toString(kv);
|
|
32815
|
+
if (v) opts.keyValue = v;
|
|
32816
|
+
}
|
|
32817
|
+
return opts;
|
|
32818
|
+
}
|
|
32143
32819
|
registerSpecial("websave", (_nargout, args) => {
|
|
32144
32820
|
const io = requireFileIO();
|
|
32145
32821
|
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
@@ -32149,8 +32825,14 @@ function registerSpecialBuiltins(rt) {
|
|
|
32149
32825
|
throw new RuntimeError("websave is not available in this environment");
|
|
32150
32826
|
const filename = toString(margs[0]);
|
|
32151
32827
|
let url = toString(margs[1]);
|
|
32828
|
+
let webOpts;
|
|
32829
|
+
let queryEnd = margs.length;
|
|
32830
|
+
if (margs.length > 2) {
|
|
32831
|
+
webOpts = extractWebOptions(margs[margs.length - 1]);
|
|
32832
|
+
if (webOpts) queryEnd = margs.length - 1;
|
|
32833
|
+
}
|
|
32152
32834
|
const queryParts = [];
|
|
32153
|
-
for (let i = 2; i + 1 <
|
|
32835
|
+
for (let i = 2; i + 1 < queryEnd; i += 2) {
|
|
32154
32836
|
const name = encodeURIComponent(toString(margs[i]));
|
|
32155
32837
|
const value = encodeURIComponent(toString(margs[i + 1]));
|
|
32156
32838
|
queryParts.push(`${name}=${value}`);
|
|
@@ -32159,7 +32841,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
32159
32841
|
const sep = url.includes("?") ? "&" : "?";
|
|
32160
32842
|
url += sep + queryParts.join("&");
|
|
32161
32843
|
}
|
|
32162
|
-
io.websave(url, filename);
|
|
32844
|
+
io.websave(url, filename, webOpts);
|
|
32163
32845
|
return RTV.char(filename);
|
|
32164
32846
|
});
|
|
32165
32847
|
registerSpecial("webread", (_nargout, args) => {
|
|
@@ -32170,8 +32852,14 @@ function registerSpecialBuiltins(rt) {
|
|
|
32170
32852
|
if (!io.webread)
|
|
32171
32853
|
throw new RuntimeError("webread is not available in this environment");
|
|
32172
32854
|
let url = toString(margs[0]);
|
|
32855
|
+
let webOpts;
|
|
32856
|
+
let queryEnd = margs.length;
|
|
32857
|
+
if (margs.length > 1) {
|
|
32858
|
+
webOpts = extractWebOptions(margs[margs.length - 1]);
|
|
32859
|
+
if (webOpts) queryEnd = margs.length - 1;
|
|
32860
|
+
}
|
|
32173
32861
|
const queryParts = [];
|
|
32174
|
-
for (let i = 1; i + 1 <
|
|
32862
|
+
for (let i = 1; i + 1 < queryEnd; i += 2) {
|
|
32175
32863
|
const name = encodeURIComponent(toString(margs[i]));
|
|
32176
32864
|
const value = encodeURIComponent(toString(margs[i + 1]));
|
|
32177
32865
|
queryParts.push(`${name}=${value}`);
|
|
@@ -32180,7 +32868,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
32180
32868
|
const sep = url.includes("?") ? "&" : "?";
|
|
32181
32869
|
url += sep + queryParts.join("&");
|
|
32182
32870
|
}
|
|
32183
|
-
const text = io.webread(url);
|
|
32871
|
+
const text = io.webread(url, webOpts);
|
|
32184
32872
|
try {
|
|
32185
32873
|
const parsed = JSON.parse(text);
|
|
32186
32874
|
return convertJsonValue(parsed);
|
|
@@ -32188,7 +32876,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
32188
32876
|
return RTV.char(text);
|
|
32189
32877
|
}
|
|
32190
32878
|
});
|
|
32191
|
-
|
|
32879
|
+
registerSpecialVoid("delete", (args) => {
|
|
32192
32880
|
const io = requireFileIO();
|
|
32193
32881
|
if (!io.deleteFile)
|
|
32194
32882
|
throw new RuntimeError("delete is not available in this environment");
|
|
@@ -32198,7 +32886,6 @@ function registerSpecialBuiltins(rt) {
|
|
|
32198
32886
|
for (const arg of margs) {
|
|
32199
32887
|
io.deleteFile(toString(arg));
|
|
32200
32888
|
}
|
|
32201
|
-
return 0;
|
|
32202
32889
|
});
|
|
32203
32890
|
registerSpecial("rmdir", (nargout, args) => {
|
|
32204
32891
|
const io = requireFileIO();
|
|
@@ -32221,6 +32908,34 @@ function registerSpecialBuiltins(rt) {
|
|
|
32221
32908
|
RTV.char("")
|
|
32222
32909
|
];
|
|
32223
32910
|
});
|
|
32911
|
+
registerSpecial("movefile", (nargout, args) => {
|
|
32912
|
+
const io = requireFileIO();
|
|
32913
|
+
if (!io.movefile)
|
|
32914
|
+
throw new RuntimeError("movefile is not available in this environment");
|
|
32915
|
+
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
32916
|
+
if (margs.length < 1)
|
|
32917
|
+
throw new RuntimeError("movefile requires at least 1 argument");
|
|
32918
|
+
const source = toString(margs[0]);
|
|
32919
|
+
const destination = margs.length >= 2 ? toString(margs[1]) : rt.system?.cwd() ?? ".";
|
|
32920
|
+
let force = false;
|
|
32921
|
+
if (margs.length >= 3) {
|
|
32922
|
+
const third = toString(margs[2]);
|
|
32923
|
+
if (third.toLowerCase() === "f") force = true;
|
|
32924
|
+
}
|
|
32925
|
+
const ok = io.movefile(source, destination, force);
|
|
32926
|
+
if (nargout === 0) {
|
|
32927
|
+
if (!ok)
|
|
32928
|
+
throw new RuntimeError(
|
|
32929
|
+
`movefile: cannot move '${source}' to '${destination}'`
|
|
32930
|
+
);
|
|
32931
|
+
return void 0;
|
|
32932
|
+
}
|
|
32933
|
+
return nargout <= 1 ? RTV.num(ok ? 1 : 0) : [
|
|
32934
|
+
RTV.num(ok ? 1 : 0),
|
|
32935
|
+
RTV.char(ok ? "" : `Cannot move '${source}' to '${destination}'`),
|
|
32936
|
+
RTV.char("")
|
|
32937
|
+
];
|
|
32938
|
+
});
|
|
32224
32939
|
registerSpecial("unzip", (nargout, args) => {
|
|
32225
32940
|
const io = requireFileIO();
|
|
32226
32941
|
if (!io.unzip)
|
|
@@ -32272,7 +32987,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
32272
32987
|
const cellData = extracted.map((f) => RTV.char(f));
|
|
32273
32988
|
return RTV.cell(cellData, [1, cellData.length]);
|
|
32274
32989
|
}
|
|
32275
|
-
return 0;
|
|
32990
|
+
return void 0;
|
|
32276
32991
|
});
|
|
32277
32992
|
registerSpecial("dir", (nargout, args) => {
|
|
32278
32993
|
const io = requireFileIO();
|
|
@@ -32369,7 +33084,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
32369
33084
|
const parts = margs.map((a) => toString(a));
|
|
32370
33085
|
return RTV.char(parts.join("/"));
|
|
32371
33086
|
});
|
|
32372
|
-
|
|
33087
|
+
registerSpecialVoid("assignin", (args) => {
|
|
32373
33088
|
if (args.length < 3)
|
|
32374
33089
|
throw new RuntimeError("assignin requires 3 arguments");
|
|
32375
33090
|
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
@@ -32384,7 +33099,6 @@ function registerSpecialBuiltins(rt) {
|
|
|
32384
33099
|
} else {
|
|
32385
33100
|
rt.setWorkspaceVariable(varName, args[2]);
|
|
32386
33101
|
}
|
|
32387
|
-
return 0;
|
|
32388
33102
|
});
|
|
32389
33103
|
registerSpecial("evalin", (_nargout, args) => {
|
|
32390
33104
|
if (args.length < 2)
|
|
@@ -32405,13 +33119,12 @@ function registerSpecialBuiltins(rt) {
|
|
|
32405
33119
|
}
|
|
32406
33120
|
return val;
|
|
32407
33121
|
});
|
|
32408
|
-
|
|
33122
|
+
registerSpecialVoid("drawnow", () => {
|
|
32409
33123
|
rt.drawnow();
|
|
32410
|
-
return 0;
|
|
32411
33124
|
});
|
|
32412
|
-
registerSpecial("pause", (
|
|
33125
|
+
registerSpecial("pause", (nargout, args) => {
|
|
32413
33126
|
rt.pause(args[0] ?? 0);
|
|
32414
|
-
return 0;
|
|
33127
|
+
return nargout >= 1 ? RTV.char("on") : void 0;
|
|
32415
33128
|
});
|
|
32416
33129
|
registerSpecial("mfilename", (_nargout, args) => {
|
|
32417
33130
|
const file = rt.$file ?? "";
|
|
@@ -32455,7 +33168,7 @@ function registerSpecialBuiltins(rt) {
|
|
|
32455
33168
|
}
|
|
32456
33169
|
}
|
|
32457
33170
|
if (nargout >= 1) return RTV.char(rt.searchPaths.join(";"));
|
|
32458
|
-
return 0;
|
|
33171
|
+
return void 0;
|
|
32459
33172
|
});
|
|
32460
33173
|
registerSpecial("rmpath", (nargout, args) => {
|
|
32461
33174
|
if (!rt.onPathChange) {
|
|
@@ -32475,11 +33188,11 @@ function registerSpecialBuiltins(rt) {
|
|
|
32475
33188
|
}
|
|
32476
33189
|
}
|
|
32477
33190
|
if (nargout >= 1) return RTV.char(rt.searchPaths.join(";"));
|
|
32478
|
-
return 0;
|
|
33191
|
+
return void 0;
|
|
32479
33192
|
});
|
|
32480
|
-
registerSpecial("savepath", () => {
|
|
33193
|
+
registerSpecial("savepath", (nargout) => {
|
|
32481
33194
|
rt.output("Warning: savepath is a no-op in numbl\n");
|
|
32482
|
-
return 0;
|
|
33195
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32483
33196
|
});
|
|
32484
33197
|
registerSpecial("input", (_nargout, args) => {
|
|
32485
33198
|
const margs = args.map((a) => ensureRuntimeValue(a));
|
|
@@ -32542,11 +33255,11 @@ function registerSpecialBuiltins(rt) {
|
|
|
32542
33255
|
}
|
|
32543
33256
|
return RTV.char(sys?.getEnv(toString(args[0])) ?? "");
|
|
32544
33257
|
});
|
|
32545
|
-
|
|
33258
|
+
registerSpecialVoid("setenv", (args) => {
|
|
32546
33259
|
const sys = rt.system;
|
|
32547
33260
|
if (args.length === 2) {
|
|
32548
33261
|
sys?.setEnv(toString(args[0]), toString(args[1]));
|
|
32549
|
-
return
|
|
33262
|
+
return;
|
|
32550
33263
|
}
|
|
32551
33264
|
if (args.length === 1) {
|
|
32552
33265
|
const d = args[0];
|
|
@@ -32554,20 +33267,26 @@ function registerSpecialBuiltins(rt) {
|
|
|
32554
33267
|
for (const { key, value } of d.entries.values()) {
|
|
32555
33268
|
sys?.setEnv(toString(key), toString(value));
|
|
32556
33269
|
}
|
|
32557
|
-
return
|
|
33270
|
+
return;
|
|
32558
33271
|
}
|
|
32559
33272
|
sys?.setEnv(toString(d), "");
|
|
32560
|
-
return
|
|
33273
|
+
return;
|
|
32561
33274
|
}
|
|
32562
33275
|
throw new RuntimeError("setenv: invalid arguments");
|
|
32563
33276
|
});
|
|
32564
33277
|
registerSpecial("pwd", () => {
|
|
32565
33278
|
return RTV.char(rt.system?.cwd() ?? "/");
|
|
32566
33279
|
});
|
|
32567
|
-
registerSpecial("cd", (
|
|
33280
|
+
registerSpecial("cd", (nargout, args) => {
|
|
32568
33281
|
const sys = rt.system;
|
|
32569
33282
|
const curDir = sys?.cwd() ?? "/";
|
|
32570
|
-
if (args.length === 0)
|
|
33283
|
+
if (args.length === 0) {
|
|
33284
|
+
if (nargout === 0) {
|
|
33285
|
+
rt.output(curDir + "\n");
|
|
33286
|
+
return void 0;
|
|
33287
|
+
}
|
|
33288
|
+
return RTV.char(curDir);
|
|
33289
|
+
}
|
|
32571
33290
|
const target = toString(args[0]);
|
|
32572
33291
|
if (sys) {
|
|
32573
33292
|
try {
|
|
@@ -32575,15 +33294,18 @@ function registerSpecialBuiltins(rt) {
|
|
|
32575
33294
|
} catch {
|
|
32576
33295
|
throw new RuntimeError(`Cannot change directory to '${target}'`);
|
|
32577
33296
|
}
|
|
33297
|
+
if (rt.onCwdChange) {
|
|
33298
|
+
rt.onCwdChange(sys.cwd());
|
|
33299
|
+
}
|
|
32578
33300
|
}
|
|
32579
|
-
return RTV.char(curDir);
|
|
33301
|
+
return nargout >= 1 ? RTV.char(curDir) : void 0;
|
|
32580
33302
|
});
|
|
32581
|
-
registerSpecial("figure", (
|
|
33303
|
+
registerSpecial("figure", (nargout, args) => {
|
|
32582
33304
|
const handle = args.length > 0 ? args[0] : 1;
|
|
32583
33305
|
plotInstr(rt.plotInstructions, { type: "set_figure_handle", handle });
|
|
32584
|
-
return 0;
|
|
33306
|
+
return nargout >= 1 ? RTV.num(toNumber(ensureRuntimeValue(handle))) : void 0;
|
|
32585
33307
|
});
|
|
32586
|
-
registerSpecial("subplot", (
|
|
33308
|
+
registerSpecial("subplot", (nargout, args) => {
|
|
32587
33309
|
if (args.length >= 3) {
|
|
32588
33310
|
plotInstr(rt.plotInstructions, {
|
|
32589
33311
|
type: "set_subplot",
|
|
@@ -32592,43 +33314,41 @@ function registerSpecialBuiltins(rt) {
|
|
|
32592
33314
|
index: args[2]
|
|
32593
33315
|
});
|
|
32594
33316
|
}
|
|
32595
|
-
return 0;
|
|
33317
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32596
33318
|
});
|
|
32597
|
-
registerSpecial("title", (
|
|
33319
|
+
registerSpecial("title", (nargout, args) => {
|
|
32598
33320
|
if (args.length > 0) {
|
|
32599
33321
|
plotInstr(rt.plotInstructions, { type: "set_title", text: args[0] });
|
|
32600
33322
|
}
|
|
32601
|
-
return 0;
|
|
33323
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32602
33324
|
});
|
|
32603
|
-
registerSpecial("xlabel", (
|
|
33325
|
+
registerSpecial("xlabel", (nargout, args) => {
|
|
32604
33326
|
if (args.length > 0) {
|
|
32605
33327
|
plotInstr(rt.plotInstructions, { type: "set_xlabel", text: args[0] });
|
|
32606
33328
|
}
|
|
32607
|
-
return 0;
|
|
33329
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32608
33330
|
});
|
|
32609
|
-
registerSpecial("ylabel", (
|
|
33331
|
+
registerSpecial("ylabel", (nargout, args) => {
|
|
32610
33332
|
if (args.length > 0) {
|
|
32611
33333
|
plotInstr(rt.plotInstructions, { type: "set_ylabel", text: args[0] });
|
|
32612
33334
|
}
|
|
32613
|
-
return 0;
|
|
33335
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32614
33336
|
});
|
|
32615
|
-
|
|
33337
|
+
registerSpecialVoid("hold", (args) => {
|
|
32616
33338
|
if (args.length > 0) {
|
|
32617
33339
|
plotInstr(rt.plotInstructions, { type: "set_hold", value: args[0] });
|
|
32618
33340
|
}
|
|
32619
|
-
return 0;
|
|
32620
33341
|
});
|
|
32621
|
-
|
|
33342
|
+
registerSpecialVoid("grid", (args) => {
|
|
32622
33343
|
if (args.length > 0) {
|
|
32623
33344
|
plotInstr(rt.plotInstructions, { type: "set_grid", value: args[0] });
|
|
32624
33345
|
}
|
|
32625
|
-
return 0;
|
|
32626
33346
|
});
|
|
32627
|
-
registerSpecial("legend", (
|
|
33347
|
+
registerSpecial("legend", (nargout, args) => {
|
|
32628
33348
|
legendCall(rt.plotInstructions, args);
|
|
32629
|
-
return 0;
|
|
33349
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32630
33350
|
});
|
|
32631
|
-
registerSpecial("close", (
|
|
33351
|
+
registerSpecial("close", (nargout, args) => {
|
|
32632
33352
|
if (args.length > 0) {
|
|
32633
33353
|
const val = toString(args[0]);
|
|
32634
33354
|
if (val === "all") {
|
|
@@ -32639,26 +33359,25 @@ function registerSpecialBuiltins(rt) {
|
|
|
32639
33359
|
} else {
|
|
32640
33360
|
plotInstr(rt.plotInstructions, { type: "close" });
|
|
32641
33361
|
}
|
|
32642
|
-
return 0;
|
|
33362
|
+
return nargout >= 1 ? RTV.num(1) : void 0;
|
|
32643
33363
|
});
|
|
32644
|
-
registerSpecial("sgtitle", (
|
|
33364
|
+
registerSpecial("sgtitle", (nargout, args) => {
|
|
32645
33365
|
if (args.length > 0) {
|
|
32646
33366
|
plotInstr(rt.plotInstructions, { type: "set_sgtitle", text: args[0] });
|
|
32647
33367
|
}
|
|
32648
|
-
return 0;
|
|
33368
|
+
return nargout >= 1 ? RTV.num(0) : void 0;
|
|
32649
33369
|
});
|
|
32650
|
-
|
|
33370
|
+
registerSpecialVoid("shading", (args) => {
|
|
32651
33371
|
if (args.length > 0) {
|
|
32652
33372
|
plotInstr(rt.plotInstructions, {
|
|
32653
33373
|
type: "set_shading",
|
|
32654
33374
|
shading: args[0]
|
|
32655
33375
|
});
|
|
32656
33376
|
}
|
|
32657
|
-
return 0;
|
|
32658
33377
|
});
|
|
32659
|
-
registerSpecial("clf", () => {
|
|
33378
|
+
registerSpecial("clf", (nargout) => {
|
|
32660
33379
|
plotInstr(rt.plotInstructions, { type: "clf" });
|
|
32661
|
-
return 0;
|
|
33380
|
+
return nargout >= 1 ? RTV.num(1) : void 0;
|
|
32662
33381
|
});
|
|
32663
33382
|
registerSpecial("ode45", (nargout, args) => {
|
|
32664
33383
|
return _ode45Impl(rt, nargout, args, dormandPrince45);
|
|
@@ -33114,6 +33833,8 @@ var Runtime = class _Runtime {
|
|
|
33114
33833
|
classMethodCache = /* @__PURE__ */ new Map();
|
|
33115
33834
|
/** Callback for addpath/rmpath — mutates search paths and rebuilds function index. */
|
|
33116
33835
|
onPathChange = null;
|
|
33836
|
+
/** Callback invoked after cd() to update the implicit cwd search path. */
|
|
33837
|
+
onCwdChange = null;
|
|
33117
33838
|
/** Reference to the active search paths (set by executeCode). */
|
|
33118
33839
|
searchPaths = [];
|
|
33119
33840
|
// Workspace accessors: varName → { get, set } closures over script-level vars
|
|
@@ -33393,23 +34114,26 @@ var Runtime = class _Runtime {
|
|
|
33393
34114
|
if (e instanceof RuntimeError) {
|
|
33394
34115
|
return RTV.struct(
|
|
33395
34116
|
/* @__PURE__ */ new Map([
|
|
33396
|
-
["message", RTV.
|
|
33397
|
-
["identifier", RTV.
|
|
34117
|
+
["message", RTV.char(e.message)],
|
|
34118
|
+
["identifier", RTV.char(e.identifier)],
|
|
34119
|
+
["stack", buildStackField(e)]
|
|
33398
34120
|
])
|
|
33399
34121
|
);
|
|
33400
34122
|
}
|
|
33401
34123
|
if (e instanceof Error) {
|
|
33402
34124
|
return RTV.struct(
|
|
33403
34125
|
/* @__PURE__ */ new Map([
|
|
33404
|
-
["message", RTV.
|
|
33405
|
-
["identifier", RTV.
|
|
34126
|
+
["message", RTV.char(e.message)],
|
|
34127
|
+
["identifier", RTV.char("")],
|
|
34128
|
+
["stack", emptyStackField()]
|
|
33406
34129
|
])
|
|
33407
34130
|
);
|
|
33408
34131
|
}
|
|
33409
34132
|
return RTV.struct(
|
|
33410
34133
|
/* @__PURE__ */ new Map([
|
|
33411
|
-
["message", RTV.
|
|
33412
|
-
["identifier", RTV.
|
|
34134
|
+
["message", RTV.char(String(e))],
|
|
34135
|
+
["identifier", RTV.char("")],
|
|
34136
|
+
["stack", emptyStackField()]
|
|
33413
34137
|
])
|
|
33414
34138
|
);
|
|
33415
34139
|
}
|
|
@@ -34241,6 +34965,63 @@ var rstr = (s) => {
|
|
|
34241
34965
|
if (isRuntimeChar(s)) return s.value;
|
|
34242
34966
|
throw new RuntimeError(`Expected string or char, got ${kstr(s)}`);
|
|
34243
34967
|
};
|
|
34968
|
+
function emptyStackField() {
|
|
34969
|
+
return RTV.structArray(["file", "name", "line"], []);
|
|
34970
|
+
}
|
|
34971
|
+
function buildStackField(e) {
|
|
34972
|
+
const fieldNames = ["file", "name", "line"];
|
|
34973
|
+
const frames = e.callStack;
|
|
34974
|
+
if (!frames || frames.length === 0) {
|
|
34975
|
+
if (e.file || e.line !== null) {
|
|
34976
|
+
return RTV.structArray(fieldNames, [
|
|
34977
|
+
RTV.struct(
|
|
34978
|
+
/* @__PURE__ */ new Map([
|
|
34979
|
+
["file", RTV.char(e.file ?? "")],
|
|
34980
|
+
["name", RTV.char("")],
|
|
34981
|
+
["line", e.line ?? 0]
|
|
34982
|
+
])
|
|
34983
|
+
)
|
|
34984
|
+
]);
|
|
34985
|
+
}
|
|
34986
|
+
return emptyStackField();
|
|
34987
|
+
}
|
|
34988
|
+
const elements = [];
|
|
34989
|
+
const N = frames.length;
|
|
34990
|
+
for (let i = N - 1; i >= 0; i--) {
|
|
34991
|
+
let frameFile;
|
|
34992
|
+
let frameLine;
|
|
34993
|
+
if (i === N - 1) {
|
|
34994
|
+
frameFile = e.file;
|
|
34995
|
+
frameLine = e.line ?? 0;
|
|
34996
|
+
} else {
|
|
34997
|
+
const callerFrame = frames[i + 1];
|
|
34998
|
+
frameFile = callerFrame.callerFile;
|
|
34999
|
+
frameLine = callerFrame.callerLine;
|
|
35000
|
+
}
|
|
35001
|
+
elements.push(
|
|
35002
|
+
RTV.struct(
|
|
35003
|
+
/* @__PURE__ */ new Map([
|
|
35004
|
+
["file", RTV.char(frameFile ?? "")],
|
|
35005
|
+
["name", RTV.char(frames[i].name)],
|
|
35006
|
+
["line", frameLine]
|
|
35007
|
+
])
|
|
35008
|
+
)
|
|
35009
|
+
);
|
|
35010
|
+
}
|
|
35011
|
+
const outermost = frames[0];
|
|
35012
|
+
if (outermost.callerFile && outermost.callerLine > 0) {
|
|
35013
|
+
elements.push(
|
|
35014
|
+
RTV.struct(
|
|
35015
|
+
/* @__PURE__ */ new Map([
|
|
35016
|
+
["file", RTV.char(outermost.callerFile)],
|
|
35017
|
+
["name", RTV.char("")],
|
|
35018
|
+
["line", outermost.callerLine]
|
|
35019
|
+
])
|
|
35020
|
+
)
|
|
35021
|
+
);
|
|
35022
|
+
}
|
|
35023
|
+
return RTV.structArray(fieldNames, elements);
|
|
35024
|
+
}
|
|
34244
35025
|
|
|
34245
35026
|
// src/numbl-core/helpers/reduction-helpers.ts
|
|
34246
35027
|
function squeezeTrailing(shape) {
|
|
@@ -35248,6 +36029,89 @@ defineBuiltin({
|
|
|
35248
36029
|
}
|
|
35249
36030
|
});
|
|
35250
36031
|
|
|
36032
|
+
// src/numbl-core/interpreter/builtins/logical.ts
|
|
36033
|
+
var LOGICAL_KINDS = /* @__PURE__ */ new Set([
|
|
36034
|
+
"number",
|
|
36035
|
+
"boolean",
|
|
36036
|
+
"tensor",
|
|
36037
|
+
"sparse_matrix"
|
|
36038
|
+
]);
|
|
36039
|
+
function binaryLogicalMatch(argTypes) {
|
|
36040
|
+
if (argTypes.length !== 2) return null;
|
|
36041
|
+
if (!LOGICAL_KINDS.has(argTypes[0].kind)) return null;
|
|
36042
|
+
if (!LOGICAL_KINDS.has(argTypes[1].kind)) return null;
|
|
36043
|
+
if (argTypes[0].kind === "tensor" || argTypes[1].kind === "tensor") {
|
|
36044
|
+
return [{ kind: "tensor", isComplex: false, isLogical: true }];
|
|
36045
|
+
}
|
|
36046
|
+
if (argTypes[0].kind === "sparse_matrix" || argTypes[1].kind === "sparse_matrix") {
|
|
36047
|
+
return [{ kind: "tensor", isComplex: false, isLogical: true }];
|
|
36048
|
+
}
|
|
36049
|
+
return [{ kind: "boolean" }];
|
|
36050
|
+
}
|
|
36051
|
+
function isTensorLike(v) {
|
|
36052
|
+
return isRuntimeTensor(v) || isRuntimeSparseMatrix(v);
|
|
36053
|
+
}
|
|
36054
|
+
function applyBinaryLogical(args, op, scalarFn) {
|
|
36055
|
+
const a = args[0];
|
|
36056
|
+
const b = args[1];
|
|
36057
|
+
if (isTensorLike(a) || isTensorLike(b)) {
|
|
36058
|
+
return elementWiseLogicalOp(a, b, op);
|
|
36059
|
+
}
|
|
36060
|
+
return RTV.logical(scalarFn(toBool(a), toBool(b)));
|
|
36061
|
+
}
|
|
36062
|
+
var orCase = {
|
|
36063
|
+
match: binaryLogicalMatch,
|
|
36064
|
+
apply: (args) => applyBinaryLogical(
|
|
36065
|
+
args,
|
|
36066
|
+
(x, y) => x !== 0 || y !== 0 ? 1 : 0,
|
|
36067
|
+
(a, b) => a || b
|
|
36068
|
+
)
|
|
36069
|
+
};
|
|
36070
|
+
defineBuiltin({
|
|
36071
|
+
name: "or",
|
|
36072
|
+
help: {
|
|
36073
|
+
signatures: ["TF = or(A, B)"],
|
|
36074
|
+
description: "Logical OR. Functional form of A | B; returns a logical scalar or tensor."
|
|
36075
|
+
},
|
|
36076
|
+
cases: [orCase]
|
|
36077
|
+
});
|
|
36078
|
+
var andCase = {
|
|
36079
|
+
match: binaryLogicalMatch,
|
|
36080
|
+
apply: (args) => applyBinaryLogical(
|
|
36081
|
+
args,
|
|
36082
|
+
(x, y) => x !== 0 && y !== 0 ? 1 : 0,
|
|
36083
|
+
(a, b) => a && b
|
|
36084
|
+
)
|
|
36085
|
+
};
|
|
36086
|
+
defineBuiltin({
|
|
36087
|
+
name: "and",
|
|
36088
|
+
help: {
|
|
36089
|
+
signatures: ["TF = and(A, B)"],
|
|
36090
|
+
description: "Logical AND. Functional form of A & B; returns a logical scalar or tensor."
|
|
36091
|
+
},
|
|
36092
|
+
cases: [andCase]
|
|
36093
|
+
});
|
|
36094
|
+
defineBuiltin({
|
|
36095
|
+
name: "not",
|
|
36096
|
+
help: {
|
|
36097
|
+
signatures: ["TF = not(A)"],
|
|
36098
|
+
description: "Logical negation. Functional form of ~A; returns a logical scalar or tensor."
|
|
36099
|
+
},
|
|
36100
|
+
cases: [
|
|
36101
|
+
{
|
|
36102
|
+
match: (argTypes) => {
|
|
36103
|
+
if (argTypes.length !== 1) return null;
|
|
36104
|
+
if (!LOGICAL_KINDS.has(argTypes[0].kind)) return null;
|
|
36105
|
+
if (argTypes[0].kind === "tensor" || argTypes[0].kind === "sparse_matrix") {
|
|
36106
|
+
return [{ kind: "tensor", isComplex: false, isLogical: true }];
|
|
36107
|
+
}
|
|
36108
|
+
return [{ kind: "boolean" }];
|
|
36109
|
+
},
|
|
36110
|
+
apply: (args) => not(args[0])
|
|
36111
|
+
}
|
|
36112
|
+
]
|
|
36113
|
+
});
|
|
36114
|
+
|
|
35251
36115
|
// src/numbl-core/interpreter/builtins/utility.ts
|
|
35252
36116
|
function sparseToDense2(S) {
|
|
35253
36117
|
const data = new FloatXArray(S.m * S.n);
|
|
@@ -35356,7 +36220,7 @@ defineBuiltin({
|
|
|
35356
36220
|
{
|
|
35357
36221
|
match: (argTypes) => {
|
|
35358
36222
|
if (argTypes.length < 1) return null;
|
|
35359
|
-
return [
|
|
36223
|
+
return [];
|
|
35360
36224
|
},
|
|
35361
36225
|
apply: (args) => {
|
|
35362
36226
|
const v = args[0];
|
|
@@ -35377,7 +36241,7 @@ defineBuiltin({
|
|
|
35377
36241
|
const msg = args.length > 1 ? textValue(args[1]) ?? String(args[1]) : "Assertion failed";
|
|
35378
36242
|
throw new Error(msg);
|
|
35379
36243
|
}
|
|
35380
|
-
return 0;
|
|
36244
|
+
return void 0;
|
|
35381
36245
|
}
|
|
35382
36246
|
}
|
|
35383
36247
|
]
|
|
@@ -35388,7 +36252,7 @@ defineBuiltin({
|
|
|
35388
36252
|
{
|
|
35389
36253
|
match: (argTypes) => {
|
|
35390
36254
|
if (argTypes.length === 0) return null;
|
|
35391
|
-
return [
|
|
36255
|
+
return [];
|
|
35392
36256
|
},
|
|
35393
36257
|
apply: (args) => {
|
|
35394
36258
|
const first = textValue(args[0]) ?? String(args[0]);
|
|
@@ -36060,6 +36924,19 @@ defineBuiltin({
|
|
|
36060
36924
|
name: "NaN",
|
|
36061
36925
|
cases: arrayConstructorCases(nanFill, NaN)
|
|
36062
36926
|
});
|
|
36927
|
+
function infFill(shape) {
|
|
36928
|
+
const data = new FloatXArray(numel(shape));
|
|
36929
|
+
data.fill(Infinity);
|
|
36930
|
+
return makeTensor(data, void 0, shape);
|
|
36931
|
+
}
|
|
36932
|
+
defineBuiltin({
|
|
36933
|
+
name: "inf",
|
|
36934
|
+
cases: arrayConstructorCases(infFill, Infinity)
|
|
36935
|
+
});
|
|
36936
|
+
defineBuiltin({
|
|
36937
|
+
name: "Inf",
|
|
36938
|
+
cases: arrayConstructorCases(infFill, Infinity)
|
|
36939
|
+
});
|
|
36063
36940
|
defineBuiltin({
|
|
36064
36941
|
name: "eye",
|
|
36065
36942
|
cases: arrayConstructorCases(
|
|
@@ -36897,19 +37774,33 @@ function preserveTextType(t) {
|
|
|
36897
37774
|
if (t.kind === "string") return { kind: "string" };
|
|
36898
37775
|
return null;
|
|
36899
37776
|
}
|
|
37777
|
+
function applyTextFn(v, fn) {
|
|
37778
|
+
if (isRuntimeCell(v)) {
|
|
37779
|
+
const out = new Array(v.data.length);
|
|
37780
|
+
for (let i = 0; i < v.data.length; i++) {
|
|
37781
|
+
out[i] = applyTextFn(v.data[i], fn);
|
|
37782
|
+
}
|
|
37783
|
+
return RTV.cell(out, [...v.shape]);
|
|
37784
|
+
}
|
|
37785
|
+
if (isRuntimeChar(v)) return RTV.char(fn(v.value));
|
|
37786
|
+
if (isRuntimeString(v)) return RTV.string(fn(toString(v)));
|
|
37787
|
+
return v;
|
|
37788
|
+
}
|
|
36900
37789
|
function textPreserveResolve(fn) {
|
|
36901
37790
|
return (argTypes) => {
|
|
36902
37791
|
if (argTypes.length !== 1) return null;
|
|
36903
|
-
const
|
|
37792
|
+
const t = argTypes[0];
|
|
37793
|
+
if (t.kind === "cell") {
|
|
37794
|
+
return {
|
|
37795
|
+
outputTypes: [{ kind: "cell" }],
|
|
37796
|
+
apply: (args) => applyTextFn(args[0], fn)
|
|
37797
|
+
};
|
|
37798
|
+
}
|
|
37799
|
+
const out = preserveTextType(t);
|
|
36904
37800
|
if (!out) return null;
|
|
36905
37801
|
return {
|
|
36906
37802
|
outputTypes: [out],
|
|
36907
|
-
apply: (args) =>
|
|
36908
|
-
const v = args[0];
|
|
36909
|
-
const s = toString(v);
|
|
36910
|
-
const result = fn(s);
|
|
36911
|
-
return isRuntimeChar(v) ? RTV.char(result) : RTV.string(result);
|
|
36912
|
-
}
|
|
37803
|
+
apply: (args) => applyTextFn(args[0], fn)
|
|
36913
37804
|
};
|
|
36914
37805
|
};
|
|
36915
37806
|
}
|
|
@@ -38960,7 +39851,7 @@ defineBuiltin({
|
|
|
38960
39851
|
cases: [
|
|
38961
39852
|
{
|
|
38962
39853
|
match: (argTypes, nargout) => {
|
|
38963
|
-
if (nargout
|
|
39854
|
+
if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
|
|
38964
39855
|
return null;
|
|
38965
39856
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
38966
39857
|
return [NUM];
|
|
@@ -39077,7 +39968,7 @@ defineBuiltin({
|
|
|
39077
39968
|
cases: [
|
|
39078
39969
|
{
|
|
39079
39970
|
match: (argTypes, nargout) => {
|
|
39080
|
-
if (nargout
|
|
39971
|
+
if (nargout > 1 || argTypes.length < 1 || argTypes.length > 3)
|
|
39081
39972
|
return null;
|
|
39082
39973
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
39083
39974
|
const a = argTypes[0];
|
|
@@ -39156,7 +40047,7 @@ defineBuiltin({
|
|
|
39156
40047
|
cases: [
|
|
39157
40048
|
{
|
|
39158
40049
|
match: (argTypes, nargout) => {
|
|
39159
|
-
if (nargout
|
|
40050
|
+
if (nargout > 1 || argTypes.length !== 2) return null;
|
|
39160
40051
|
if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
|
|
39161
40052
|
return null;
|
|
39162
40053
|
const hasTensor = argTypes.some((t) => t.kind === "tensor");
|
|
@@ -39240,7 +40131,7 @@ defineBuiltin({
|
|
|
39240
40131
|
cases: [
|
|
39241
40132
|
{
|
|
39242
40133
|
match: (argTypes, nargout) => {
|
|
39243
|
-
if (argTypes.length !== 1 || nargout
|
|
40134
|
+
if (argTypes.length !== 1 || nargout > 1) return null;
|
|
39244
40135
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
39245
40136
|
const hasComplex = argTypes[0].kind === "complex_or_number" || argTypes[0].kind === "tensor" && argTypes[0].isComplex;
|
|
39246
40137
|
return [hasComplex ? COMPLEX_OR_NUM : NUM];
|
|
@@ -39352,7 +40243,7 @@ defineBuiltin({
|
|
|
39352
40243
|
cases: [
|
|
39353
40244
|
{
|
|
39354
40245
|
match: (argTypes, nargout) => {
|
|
39355
|
-
if (argTypes.length !== 1 || nargout
|
|
40246
|
+
if (argTypes.length !== 1 || nargout > 1) return null;
|
|
39356
40247
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
39357
40248
|
return [NUM];
|
|
39358
40249
|
},
|
|
@@ -39377,7 +40268,7 @@ defineBuiltin({
|
|
|
39377
40268
|
cases: [
|
|
39378
40269
|
{
|
|
39379
40270
|
match: (argTypes, nargout) => {
|
|
39380
|
-
if (nargout
|
|
40271
|
+
if (nargout > 1) return null;
|
|
39381
40272
|
if (argTypes.length !== 2 && argTypes.length !== 3) return null;
|
|
39382
40273
|
if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
|
|
39383
40274
|
return null;
|
|
@@ -39443,7 +40334,7 @@ defineBuiltin({
|
|
|
39443
40334
|
cases: [
|
|
39444
40335
|
{
|
|
39445
40336
|
match: (argTypes, nargout) => {
|
|
39446
|
-
if (argTypes.length !== 1 || nargout
|
|
40337
|
+
if (argTypes.length !== 1 || nargout > 1) return null;
|
|
39447
40338
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
39448
40339
|
const a = argTypes[0];
|
|
39449
40340
|
if (a.kind === "number" || a.kind === "boolean") return [NUM];
|
|
@@ -39556,11 +40447,11 @@ function invComplexJS(dataRe, dataIm, n) {
|
|
|
39556
40447
|
registerIBuiltin({
|
|
39557
40448
|
name: "svd",
|
|
39558
40449
|
resolve: (argTypes, nargout) => {
|
|
39559
|
-
if (nargout <
|
|
40450
|
+
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 2)
|
|
39560
40451
|
return null;
|
|
39561
40452
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
39562
40453
|
const c = tensorType();
|
|
39563
|
-
if (nargout
|
|
40454
|
+
if (nargout <= 1)
|
|
39564
40455
|
return { outputTypes: [c], apply: (args, n) => svdApply(args, n) };
|
|
39565
40456
|
return { outputTypes: [c, c, c], apply: (args, n) => svdApply(args, n) };
|
|
39566
40457
|
}
|
|
@@ -39571,7 +40462,7 @@ function svdApply(args, nargout) {
|
|
|
39571
40462
|
const A = args[0];
|
|
39572
40463
|
if (isRuntimeNumber(A)) {
|
|
39573
40464
|
const val = Math.abs(A);
|
|
39574
|
-
if (nargout
|
|
40465
|
+
if (nargout <= 1) return RTV.tensor(new FloatXArray([val]), [1, 1]);
|
|
39575
40466
|
return [
|
|
39576
40467
|
RTV.tensor(new FloatXArray([A >= 0 ? 1 : -1]), [1, 1]),
|
|
39577
40468
|
RTV.tensor(new FloatXArray([val]), [1, 1]),
|
|
@@ -39598,7 +40489,7 @@ function svdApply(args, nargout) {
|
|
|
39598
40489
|
nargout === 3
|
|
39599
40490
|
);
|
|
39600
40491
|
if (!result) throw new RuntimeError("svd: complex SVD failed");
|
|
39601
|
-
if (nargout
|
|
40492
|
+
if (nargout <= 1) return RTV.tensor(new FloatXArray(result.S), [k, 1]);
|
|
39602
40493
|
const uCols = econ ? k : m;
|
|
39603
40494
|
const vCols = econ ? k : n;
|
|
39604
40495
|
return [
|
|
@@ -39619,7 +40510,7 @@ function svdApply(args, nargout) {
|
|
|
39619
40510
|
if (bridge?.svd) {
|
|
39620
40511
|
const result = bridge.svd(toF64(A.data), m, n, econ, nargout === 3);
|
|
39621
40512
|
if (result) {
|
|
39622
|
-
if (nargout
|
|
40513
|
+
if (nargout <= 1) return RTV.tensor(new FloatXArray(result.S), [k, 1]);
|
|
39623
40514
|
const uCols = econ ? k : m;
|
|
39624
40515
|
const vCols = econ ? k : n;
|
|
39625
40516
|
return [
|
|
@@ -39689,12 +40580,12 @@ function powerIterationEigenvalues(A_data, n, numEigenvalues) {
|
|
|
39689
40580
|
registerIBuiltin({
|
|
39690
40581
|
name: "qr",
|
|
39691
40582
|
resolve: (argTypes, nargout) => {
|
|
39692
|
-
if (nargout <
|
|
40583
|
+
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 2)
|
|
39693
40584
|
return null;
|
|
39694
40585
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
39695
40586
|
const isComplex2 = argTypes[0].kind === "tensor" && argTypes[0].isComplex;
|
|
39696
40587
|
const t = tensorType(isComplex2 || void 0);
|
|
39697
|
-
if (nargout
|
|
40588
|
+
if (nargout <= 1)
|
|
39698
40589
|
return { outputTypes: [t], apply: (args, n) => qrApply(args, n) };
|
|
39699
40590
|
if (nargout === 3)
|
|
39700
40591
|
return {
|
|
@@ -39711,7 +40602,7 @@ function qrApply(args, nargout) {
|
|
|
39711
40602
|
if (isRuntimeNumber(A)) {
|
|
39712
40603
|
const val = A;
|
|
39713
40604
|
const s = val >= 0 ? 1 : -1;
|
|
39714
|
-
if (nargout
|
|
40605
|
+
if (nargout <= 1) return RTV.tensor(new FloatXArray([s * val]), [1, 1]);
|
|
39715
40606
|
if (nargout === 3)
|
|
39716
40607
|
return [
|
|
39717
40608
|
RTV.tensor(new FloatXArray([s]), [1, 1]),
|
|
@@ -39744,7 +40635,7 @@ function qrApply(args, nargout) {
|
|
|
39744
40635
|
nargout === 2
|
|
39745
40636
|
);
|
|
39746
40637
|
if (!result) throw new RuntimeError("qr: complex QR failed");
|
|
39747
|
-
if (nargout
|
|
40638
|
+
if (nargout <= 1) {
|
|
39748
40639
|
const rRows = econ ? k : m;
|
|
39749
40640
|
return RTV.tensor(
|
|
39750
40641
|
new FloatXArray(result.RRe),
|
|
@@ -39770,7 +40661,7 @@ function qrApply(args, nargout) {
|
|
|
39770
40661
|
if (bridge?.qr) {
|
|
39771
40662
|
const result = bridge.qr(toF64(A.data), m, n, econ, nargout === 2);
|
|
39772
40663
|
if (result) {
|
|
39773
|
-
if (nargout
|
|
40664
|
+
if (nargout <= 1)
|
|
39774
40665
|
return RTV.tensor(new FloatXArray(result.R), [econ ? k : m, n]);
|
|
39775
40666
|
const qCols = econ ? k : m;
|
|
39776
40667
|
return [
|
|
@@ -39813,7 +40704,7 @@ function qrApply(args, nargout) {
|
|
|
39813
40704
|
R_data[colMajorIndex(j + i, c, m)] -= scale * v[i];
|
|
39814
40705
|
}
|
|
39815
40706
|
}
|
|
39816
|
-
if (nargout
|
|
40707
|
+
if (nargout <= 1) {
|
|
39817
40708
|
if (econ) {
|
|
39818
40709
|
const R_econ = new FloatXArray(k * n);
|
|
39819
40710
|
for (let r = 0; r < k; r++)
|
|
@@ -40029,11 +40920,11 @@ function qrPivotApply(A, m, n, k, econ) {
|
|
|
40029
40920
|
registerIBuiltin({
|
|
40030
40921
|
name: "lu",
|
|
40031
40922
|
resolve: (argTypes, nargout) => {
|
|
40032
|
-
if (nargout <
|
|
40923
|
+
if (nargout < 0 || nargout > 3) return null;
|
|
40033
40924
|
if (argTypes.length < 1 || argTypes.length > 2) return null;
|
|
40034
40925
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
40035
40926
|
const t = tensorType();
|
|
40036
|
-
if (nargout
|
|
40927
|
+
if (nargout <= 1)
|
|
40037
40928
|
return { outputTypes: [t], apply: (args, n) => luApply(args, n) };
|
|
40038
40929
|
if (nargout === 2)
|
|
40039
40930
|
return { outputTypes: [t, t], apply: (args, n) => luApply(args, n) };
|
|
@@ -40052,7 +40943,7 @@ function luApply(args, nargout) {
|
|
|
40052
40943
|
if (nargout <= 2) {
|
|
40053
40944
|
const L2 = RTV.tensor(new FloatXArray([1]), [1, 1]);
|
|
40054
40945
|
const U2 = RTV.tensor(new FloatXArray([val]), [1, 1]);
|
|
40055
|
-
if (nargout
|
|
40946
|
+
if (nargout <= 1) return L2;
|
|
40056
40947
|
return [L2, U2];
|
|
40057
40948
|
}
|
|
40058
40949
|
const L = RTV.tensor(new FloatXArray([1]), [1, 1]);
|
|
@@ -40090,7 +40981,7 @@ function luApply(args, nargout) {
|
|
|
40090
40981
|
if (U_im && LU_im) U_im[i + j * k] = LU_im[i + j * m];
|
|
40091
40982
|
}
|
|
40092
40983
|
}
|
|
40093
|
-
if (nargout
|
|
40984
|
+
if (nargout <= 1)
|
|
40094
40985
|
return RTV.tensor(
|
|
40095
40986
|
new FloatXArray(LU_re),
|
|
40096
40987
|
[m, n],
|
|
@@ -40166,11 +41057,11 @@ function ipivToPermVector(ipiv, m) {
|
|
|
40166
41057
|
registerIBuiltin({
|
|
40167
41058
|
name: "eig",
|
|
40168
41059
|
resolve: (argTypes, nargout) => {
|
|
40169
|
-
if (nargout <
|
|
41060
|
+
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
|
|
40170
41061
|
return null;
|
|
40171
41062
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
40172
41063
|
const c = tensorType(true);
|
|
40173
|
-
if (nargout
|
|
41064
|
+
if (nargout <= 1)
|
|
40174
41065
|
return { outputTypes: [c], apply: (args, n) => eigApply(args, n) };
|
|
40175
41066
|
if (nargout === 2)
|
|
40176
41067
|
return { outputTypes: [c, c], apply: (args, n) => eigApply(args, n) };
|
|
@@ -40184,7 +41075,7 @@ function eigApply(args, nargout) {
|
|
|
40184
41075
|
const { balance, outputForm } = parseEigOptionsRuntime(args);
|
|
40185
41076
|
if (isRuntimeNumber(A)) {
|
|
40186
41077
|
const val = A;
|
|
40187
|
-
if (nargout
|
|
41078
|
+
if (nargout <= 1) return RTV.num(val);
|
|
40188
41079
|
const V = RTV.tensor(new FloatXArray([1]), [1, 1]);
|
|
40189
41080
|
if (nargout === 2) {
|
|
40190
41081
|
if (outputForm === "vector") return [V, RTV.num(val)];
|
|
@@ -40213,7 +41104,7 @@ function eigApply(args, nargout) {
|
|
|
40213
41104
|
);
|
|
40214
41105
|
if (!result2) throw new RuntimeError("eig: complex eig failed");
|
|
40215
41106
|
const { wRe, wIm, VLRe, VLIm, VRRe, VRIm } = result2;
|
|
40216
|
-
if (nargout
|
|
41107
|
+
if (nargout <= 1) return maybeComplexTensor(wRe, [n, 1], wIm);
|
|
40217
41108
|
const Vout2 = computeVR && VRRe && VRIm ? maybeComplexTensor(VRRe, [n, n], VRIm) : RTV.tensor(new FloatXArray(n * n), [n, n]);
|
|
40218
41109
|
const Dout2 = outputForm === "vector" ? maybeComplexTensor(wRe, [n, 1], wIm) : buildDiagMatrix(wRe, wIm, n);
|
|
40219
41110
|
if (nargout === 2) return [Vout2, Dout2];
|
|
@@ -40226,7 +41117,7 @@ function eigApply(args, nargout) {
|
|
|
40226
41117
|
if (!result) throw new RuntimeError("eig: LAPACK eig failed");
|
|
40227
41118
|
const { wr, wi, VL, VR } = result;
|
|
40228
41119
|
const hasComplex = wi.some((v) => v !== 0);
|
|
40229
|
-
if (nargout
|
|
41120
|
+
if (nargout <= 1) return maybeComplexTensor(wr, [n, 1], wi);
|
|
40230
41121
|
const Vout = computeVR && VR ? buildEigenvectorMatrix(VR, wi, n, hasComplex) : RTV.tensor(new FloatXArray(n * n), [n, n]);
|
|
40231
41122
|
const Dout = outputForm === "vector" ? maybeComplexTensor(wr, [n, 1], wi) : buildDiagMatrix(wr, wi, n);
|
|
40232
41123
|
if (nargout === 2) return [Vout, Dout];
|
|
@@ -40250,11 +41141,11 @@ function parseEigOptionsRuntime(args) {
|
|
|
40250
41141
|
registerIBuiltin({
|
|
40251
41142
|
name: "chol",
|
|
40252
41143
|
resolve: (argTypes, nargout) => {
|
|
40253
|
-
if (nargout <
|
|
41144
|
+
if (nargout < 0 || nargout > 3 || argTypes.length < 1 || argTypes.length > 3)
|
|
40254
41145
|
return null;
|
|
40255
41146
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
40256
41147
|
const t = tensorType();
|
|
40257
|
-
if (nargout
|
|
41148
|
+
if (nargout <= 1)
|
|
40258
41149
|
return { outputTypes: [t], apply: (args, n) => cholApply(args, n) };
|
|
40259
41150
|
if (nargout === 2)
|
|
40260
41151
|
return { outputTypes: [t, NUM], apply: (args, n) => cholApply(args, n) };
|
|
@@ -40415,7 +41306,7 @@ defineBuiltin({
|
|
|
40415
41306
|
cases: [
|
|
40416
41307
|
{
|
|
40417
41308
|
match: (argTypes, nargout) => {
|
|
40418
|
-
if (argTypes.length !== 2 || nargout
|
|
41309
|
+
if (argTypes.length !== 2 || nargout > 1) return null;
|
|
40419
41310
|
if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
|
|
40420
41311
|
return null;
|
|
40421
41312
|
return [tensorType()];
|
|
@@ -40458,7 +41349,7 @@ defineBuiltin({
|
|
|
40458
41349
|
cases: [
|
|
40459
41350
|
{
|
|
40460
41351
|
match: (argTypes, nargout) => {
|
|
40461
|
-
if (nargout
|
|
41352
|
+
if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
|
|
40462
41353
|
return null;
|
|
40463
41354
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
40464
41355
|
return [NUM];
|
|
@@ -40519,7 +41410,7 @@ defineBuiltin({
|
|
|
40519
41410
|
cases: [
|
|
40520
41411
|
{
|
|
40521
41412
|
match: (argTypes, nargout) => {
|
|
40522
|
-
if (nargout
|
|
41413
|
+
if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
|
|
40523
41414
|
return null;
|
|
40524
41415
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
40525
41416
|
return [NUM];
|
|
@@ -40567,7 +41458,7 @@ defineBuiltin({
|
|
|
40567
41458
|
cases: [
|
|
40568
41459
|
{
|
|
40569
41460
|
match: (argTypes, nargout) => {
|
|
40570
|
-
if (nargout
|
|
41461
|
+
if (nargout > 1 || argTypes.length < 1 || argTypes.length > 2)
|
|
40571
41462
|
return null;
|
|
40572
41463
|
if (!isNumericJitType(argTypes[0])) return null;
|
|
40573
41464
|
const a = argTypes[0];
|
|
@@ -40664,7 +41555,7 @@ defineBuiltin({
|
|
|
40664
41555
|
cases: [
|
|
40665
41556
|
{
|
|
40666
41557
|
match: (argTypes, nargout) => {
|
|
40667
|
-
if (nargout
|
|
41558
|
+
if (nargout > 1 || argTypes.length !== 2) return null;
|
|
40668
41559
|
if (!isNumericJitType(argTypes[0]) || !isNumericJitType(argTypes[1]))
|
|
40669
41560
|
return null;
|
|
40670
41561
|
return [tensorType()];
|
|
@@ -40672,11 +41563,15 @@ defineBuiltin({
|
|
|
40672
41563
|
apply: (args) => {
|
|
40673
41564
|
if (args.length !== 2)
|
|
40674
41565
|
throw new RuntimeError("kron requires 2 arguments");
|
|
40675
|
-
const
|
|
40676
|
-
|
|
40677
|
-
|
|
40678
|
-
|
|
41566
|
+
const coerce = (v) => {
|
|
41567
|
+
if (isRuntimeNumber(v))
|
|
41568
|
+
return RTV.tensor(new FloatXArray([v]), [1, 1]);
|
|
41569
|
+
if (isRuntimeSparseMatrix(v)) return sparseToDense(v);
|
|
41570
|
+
if (isRuntimeTensor(v)) return v;
|
|
40679
41571
|
throw new RuntimeError("kron: arguments must be numeric");
|
|
41572
|
+
};
|
|
41573
|
+
const A = coerce(args[0]);
|
|
41574
|
+
const B = coerce(args[1]);
|
|
40680
41575
|
const [m, n] = tensorSize2D(A);
|
|
40681
41576
|
const [p2, q] = tensorSize2D(B);
|
|
40682
41577
|
const rows = m * p2, cols = n * q;
|
|
@@ -40700,7 +41595,7 @@ defineBuiltin({
|
|
|
40700
41595
|
cases: [
|
|
40701
41596
|
{
|
|
40702
41597
|
match: (argTypes, nargout) => {
|
|
40703
|
-
if (nargout
|
|
41598
|
+
if (nargout > 1 || argTypes.length === 0) return null;
|
|
40704
41599
|
if (!argTypes.every(isNumericJitType)) return null;
|
|
40705
41600
|
return [tensorType()];
|
|
40706
41601
|
},
|
|
@@ -40743,7 +41638,7 @@ defineBuiltin({
|
|
|
40743
41638
|
cases: [
|
|
40744
41639
|
{
|
|
40745
41640
|
match: (argTypes, nargout) => {
|
|
40746
|
-
if (nargout
|
|
41641
|
+
if (nargout > 1) return null;
|
|
40747
41642
|
if (argTypes.length !== 2 && argTypes.length !== 4) return null;
|
|
40748
41643
|
const xIdx = 0, yIdx = argTypes.length === 4 ? 2 : 1;
|
|
40749
41644
|
if (!isNumericJitType(argTypes[xIdx]) || !isNumericJitType(argTypes[yIdx]))
|
|
@@ -40872,7 +41767,7 @@ defineBuiltin({
|
|
|
40872
41767
|
cases: [
|
|
40873
41768
|
{
|
|
40874
41769
|
match: (argTypes, nargout) => {
|
|
40875
|
-
if (nargout
|
|
41770
|
+
if (nargout > 1 || argTypes.length !== 1) return null;
|
|
40876
41771
|
if (argTypes[0].kind !== "tensor") return null;
|
|
40877
41772
|
return [tensorType(argTypes[0].isComplex)];
|
|
40878
41773
|
},
|
|
@@ -42994,6 +43889,65 @@ defineBuiltin({
|
|
|
42994
43889
|
}
|
|
42995
43890
|
]
|
|
42996
43891
|
});
|
|
43892
|
+
defineBuiltin({
|
|
43893
|
+
name: "bitget",
|
|
43894
|
+
cases: [
|
|
43895
|
+
{
|
|
43896
|
+
match: (argTypes) => {
|
|
43897
|
+
if (argTypes.length !== 2) return null;
|
|
43898
|
+
return [{ kind: "unknown" }];
|
|
43899
|
+
},
|
|
43900
|
+
// bitget(A, bit) returns bit number `bit` (1-based, 1 = LSB) of each
|
|
43901
|
+
// element of A. MATLAB supports vector `bit` with broadcasting; we
|
|
43902
|
+
// match the scalar-or-same-shape rules used by the other bitwise ops.
|
|
43903
|
+
apply: (args) => bitwiseOp(
|
|
43904
|
+
args[0],
|
|
43905
|
+
args[1],
|
|
43906
|
+
(a, bit) => {
|
|
43907
|
+
const b = Math.round(bit);
|
|
43908
|
+
if (b < 1) return 0;
|
|
43909
|
+
if (b <= 31) return a >>> b - 1 & 1;
|
|
43910
|
+
const bi = BigInt(a);
|
|
43911
|
+
return Number(bi >> BigInt(b - 1) & 1n);
|
|
43912
|
+
},
|
|
43913
|
+
"bitget"
|
|
43914
|
+
)
|
|
43915
|
+
}
|
|
43916
|
+
]
|
|
43917
|
+
});
|
|
43918
|
+
defineBuiltin({
|
|
43919
|
+
name: "bitset",
|
|
43920
|
+
cases: [
|
|
43921
|
+
{
|
|
43922
|
+
match: (argTypes) => {
|
|
43923
|
+
if (argTypes.length < 2 || argTypes.length > 3) return null;
|
|
43924
|
+
return [{ kind: "unknown" }];
|
|
43925
|
+
},
|
|
43926
|
+
// bitset(A, bit) → set bit to 1
|
|
43927
|
+
// bitset(A, bit, v) → set bit to v (0 or 1)
|
|
43928
|
+
apply: (args) => {
|
|
43929
|
+
const v = args.length >= 3 ? Math.round(toNumber(args[2])) : 1;
|
|
43930
|
+
return bitwiseOp(
|
|
43931
|
+
args[0],
|
|
43932
|
+
args[1],
|
|
43933
|
+
(a, bit) => {
|
|
43934
|
+
const b = Math.round(bit);
|
|
43935
|
+
if (b < 1) return a;
|
|
43936
|
+
if (b <= 31) {
|
|
43937
|
+
const mask2 = 1 << b - 1;
|
|
43938
|
+
return v ? a | mask2 : a & ~mask2;
|
|
43939
|
+
}
|
|
43940
|
+
const bi = BigInt(a);
|
|
43941
|
+
const mask = 1n << BigInt(b - 1);
|
|
43942
|
+
const out = v ? bi | mask : bi & ~mask;
|
|
43943
|
+
return Number(out);
|
|
43944
|
+
},
|
|
43945
|
+
"bitset"
|
|
43946
|
+
);
|
|
43947
|
+
}
|
|
43948
|
+
}
|
|
43949
|
+
]
|
|
43950
|
+
});
|
|
42997
43951
|
function coordTransform(name, nArgs, nOut, fn) {
|
|
42998
43952
|
defineBuiltin({
|
|
42999
43953
|
name,
|
|
@@ -44123,6 +45077,131 @@ defineBuiltin({
|
|
|
44123
45077
|
}
|
|
44124
45078
|
]
|
|
44125
45079
|
});
|
|
45080
|
+
var INT_RANGES = [
|
|
45081
|
+
{ name: "int8", min: -128, max: 127 },
|
|
45082
|
+
{ name: "int16", min: -32768, max: 32767 },
|
|
45083
|
+
{ name: "int32", min: -2147483648, max: 2147483647 },
|
|
45084
|
+
// int64/uint64 can't represent their full native range as doubles;
|
|
45085
|
+
// clamp at Number.MAX_SAFE_INTEGER to avoid silent precision loss.
|
|
45086
|
+
{
|
|
45087
|
+
name: "int64",
|
|
45088
|
+
min: -Number.MAX_SAFE_INTEGER,
|
|
45089
|
+
max: Number.MAX_SAFE_INTEGER
|
|
45090
|
+
},
|
|
45091
|
+
{ name: "uint8", min: 0, max: 255 },
|
|
45092
|
+
{ name: "uint16", min: 0, max: 65535 },
|
|
45093
|
+
{ name: "uint32", min: 0, max: 4294967295 },
|
|
45094
|
+
{ name: "uint64", min: 0, max: Number.MAX_SAFE_INTEGER }
|
|
45095
|
+
];
|
|
45096
|
+
function saturateRoundToward(x, min, max) {
|
|
45097
|
+
if (isNaN(x)) return 0;
|
|
45098
|
+
const r = x >= 0 ? Math.floor(x + 0.5) : -Math.floor(-x + 0.5);
|
|
45099
|
+
if (r < min) return min;
|
|
45100
|
+
if (r > max) return max;
|
|
45101
|
+
return r;
|
|
45102
|
+
}
|
|
45103
|
+
for (const { name, min, max } of INT_RANGES) {
|
|
45104
|
+
defineBuiltin({
|
|
45105
|
+
name,
|
|
45106
|
+
cases: [
|
|
45107
|
+
{
|
|
45108
|
+
match: (argTypes) => {
|
|
45109
|
+
if (argTypes.length !== 1) return null;
|
|
45110
|
+
const a = argTypes[0];
|
|
45111
|
+
if (a.kind === "number" || a.kind === "boolean" || a.kind === "char" || a.kind === "complex_or_number")
|
|
45112
|
+
return [{ kind: "number" }];
|
|
45113
|
+
if (a.kind === "tensor")
|
|
45114
|
+
return [
|
|
45115
|
+
{
|
|
45116
|
+
kind: "tensor",
|
|
45117
|
+
isComplex: false,
|
|
45118
|
+
shape: a.shape,
|
|
45119
|
+
ndim: a.ndim
|
|
45120
|
+
}
|
|
45121
|
+
];
|
|
45122
|
+
return null;
|
|
45123
|
+
},
|
|
45124
|
+
apply: (args) => {
|
|
45125
|
+
const v = args[0];
|
|
45126
|
+
if (isRuntimeNumber(v))
|
|
45127
|
+
return RTV.num(saturateRoundToward(v, min, max));
|
|
45128
|
+
if (isRuntimeLogical(v)) return RTV.num(v ? 1 : 0);
|
|
45129
|
+
if (isRuntimeComplexNumber(v))
|
|
45130
|
+
return RTV.num(saturateRoundToward(v.re, min, max));
|
|
45131
|
+
if (isRuntimeChar(v)) {
|
|
45132
|
+
if (v.value.length === 0)
|
|
45133
|
+
return RTV.tensor(new FloatXArray(0), [0, 0]);
|
|
45134
|
+
if (v.value.length === 1)
|
|
45135
|
+
return RTV.num(
|
|
45136
|
+
saturateRoundToward(v.value.charCodeAt(0), min, max)
|
|
45137
|
+
);
|
|
45138
|
+
const out = new FloatXArray(v.value.length);
|
|
45139
|
+
for (let i = 0; i < v.value.length; i++) {
|
|
45140
|
+
out[i] = saturateRoundToward(v.value.charCodeAt(i), min, max);
|
|
45141
|
+
}
|
|
45142
|
+
return RTV.row(Array.from(out));
|
|
45143
|
+
}
|
|
45144
|
+
if (isRuntimeTensor(v)) {
|
|
45145
|
+
const data = new FloatXArray(v.data.length);
|
|
45146
|
+
for (let i = 0; i < v.data.length; i++) {
|
|
45147
|
+
data[i] = saturateRoundToward(v.data[i], min, max);
|
|
45148
|
+
}
|
|
45149
|
+
return RTV.tensor(data, [...v.shape]);
|
|
45150
|
+
}
|
|
45151
|
+
return RTV.num(saturateRoundToward(toNumber(v), min, max));
|
|
45152
|
+
}
|
|
45153
|
+
}
|
|
45154
|
+
]
|
|
45155
|
+
});
|
|
45156
|
+
}
|
|
45157
|
+
defineBuiltin({
|
|
45158
|
+
name: "idivide",
|
|
45159
|
+
cases: [
|
|
45160
|
+
{
|
|
45161
|
+
match: (argTypes) => {
|
|
45162
|
+
if (argTypes.length < 2 || argTypes.length > 3) return null;
|
|
45163
|
+
return [{ kind: "unknown" }];
|
|
45164
|
+
},
|
|
45165
|
+
apply: (args) => {
|
|
45166
|
+
const divFix = (a2, b2) => {
|
|
45167
|
+
if (b2 === 0) {
|
|
45168
|
+
return 0;
|
|
45169
|
+
}
|
|
45170
|
+
const q = a2 / b2;
|
|
45171
|
+
return q >= 0 ? Math.floor(q) : -Math.floor(-q);
|
|
45172
|
+
};
|
|
45173
|
+
const a = args[0];
|
|
45174
|
+
const b = args[1];
|
|
45175
|
+
if (isRuntimeNumber(a) && isRuntimeNumber(b)) {
|
|
45176
|
+
return RTV.num(divFix(a, b));
|
|
45177
|
+
}
|
|
45178
|
+
if (isRuntimeTensor(a) && isRuntimeNumber(b)) {
|
|
45179
|
+
const bv = b;
|
|
45180
|
+
const data = new FloatXArray(a.data.length);
|
|
45181
|
+
for (let i = 0; i < a.data.length; i++)
|
|
45182
|
+
data[i] = divFix(a.data[i], bv);
|
|
45183
|
+
return RTV.tensor(data, [...a.shape]);
|
|
45184
|
+
}
|
|
45185
|
+
if (isRuntimeNumber(a) && isRuntimeTensor(b)) {
|
|
45186
|
+
const av = a;
|
|
45187
|
+
const data = new FloatXArray(b.data.length);
|
|
45188
|
+
for (let i = 0; i < b.data.length; i++)
|
|
45189
|
+
data[i] = divFix(av, b.data[i]);
|
|
45190
|
+
return RTV.tensor(data, [...b.shape]);
|
|
45191
|
+
}
|
|
45192
|
+
if (isRuntimeTensor(a) && isRuntimeTensor(b)) {
|
|
45193
|
+
if (a.data.length !== b.data.length)
|
|
45194
|
+
throw new RuntimeError("idivide: arrays must be the same size");
|
|
45195
|
+
const data = new FloatXArray(a.data.length);
|
|
45196
|
+
for (let i = 0; i < a.data.length; i++)
|
|
45197
|
+
data[i] = divFix(a.data[i], b.data[i]);
|
|
45198
|
+
return RTV.tensor(data, [...a.shape]);
|
|
45199
|
+
}
|
|
45200
|
+
throw new RuntimeError("idivide: arguments must be numeric");
|
|
45201
|
+
}
|
|
45202
|
+
}
|
|
45203
|
+
]
|
|
45204
|
+
});
|
|
44126
45205
|
defineBuiltin({
|
|
44127
45206
|
name: "logical",
|
|
44128
45207
|
cases: [
|
|
@@ -44734,9 +45813,11 @@ registerIBuiltin({
|
|
|
44734
45813
|
// src/numbl-core/helpers/prng.ts
|
|
44735
45814
|
var _rngState = null;
|
|
44736
45815
|
var _rngSeed = 0;
|
|
45816
|
+
var _bmSpare = null;
|
|
44737
45817
|
function setRngShuffle() {
|
|
44738
45818
|
_rngState = null;
|
|
44739
45819
|
_rngSeed = 0;
|
|
45820
|
+
_bmSpare = null;
|
|
44740
45821
|
}
|
|
44741
45822
|
function setRngSeed(seed) {
|
|
44742
45823
|
_rngSeed = seed;
|
|
@@ -44752,6 +45833,7 @@ function splitmix32(seed) {
|
|
|
44752
45833
|
};
|
|
44753
45834
|
}
|
|
44754
45835
|
function seedRng(seed) {
|
|
45836
|
+
_bmSpare = null;
|
|
44755
45837
|
const sm = splitmix32(seed);
|
|
44756
45838
|
_rngState = new Uint32Array([sm(), sm(), sm(), sm()]);
|
|
44757
45839
|
if (_rngState[0] === 0 && _rngState[1] === 0 && _rngState[2] === 0 && _rngState[3] === 0) {
|
|
@@ -44778,10 +45860,60 @@ function rngRandom() {
|
|
|
44778
45860
|
return (xoshiro128ss() >>> 0) / 4294967296;
|
|
44779
45861
|
}
|
|
44780
45862
|
function boxMullerRandom() {
|
|
44781
|
-
|
|
44782
|
-
|
|
44783
|
-
|
|
44784
|
-
|
|
45863
|
+
if (_bmSpare !== null) {
|
|
45864
|
+
const s2 = _bmSpare;
|
|
45865
|
+
_bmSpare = null;
|
|
45866
|
+
return s2;
|
|
45867
|
+
}
|
|
45868
|
+
let u, v, s;
|
|
45869
|
+
do {
|
|
45870
|
+
u = 2 * rngRandom() - 1;
|
|
45871
|
+
v = 2 * rngRandom() - 1;
|
|
45872
|
+
s = u * u + v * v;
|
|
45873
|
+
} while (s >= 1 || s === 0);
|
|
45874
|
+
const mul = Math.sqrt(-2 * Math.log(s) / s);
|
|
45875
|
+
_bmSpare = v * mul;
|
|
45876
|
+
return u * mul;
|
|
45877
|
+
}
|
|
45878
|
+
function fillRandn(data) {
|
|
45879
|
+
if (_rngState !== null) {
|
|
45880
|
+
const bridge = getLapackBridge();
|
|
45881
|
+
if (bridge?.fillRandn) {
|
|
45882
|
+
const r = bridge.fillRandn(
|
|
45883
|
+
_rngState,
|
|
45884
|
+
data.length,
|
|
45885
|
+
_bmSpare ?? 0,
|
|
45886
|
+
_bmSpare !== null
|
|
45887
|
+
);
|
|
45888
|
+
_bmSpare = r.hasSpare ? r.spare : null;
|
|
45889
|
+
if (data instanceof Float64Array) {
|
|
45890
|
+
data.set(r.data);
|
|
45891
|
+
} else {
|
|
45892
|
+
for (let i2 = 0; i2 < data.length; i2++) data[i2] = r.data[i2];
|
|
45893
|
+
}
|
|
45894
|
+
return;
|
|
45895
|
+
}
|
|
45896
|
+
}
|
|
45897
|
+
const n = data.length;
|
|
45898
|
+
let i = 0;
|
|
45899
|
+
if (_bmSpare !== null && i < n) {
|
|
45900
|
+
data[i++] = _bmSpare;
|
|
45901
|
+
_bmSpare = null;
|
|
45902
|
+
}
|
|
45903
|
+
for (; i + 1 < n; i += 2) {
|
|
45904
|
+
let u, v, s;
|
|
45905
|
+
do {
|
|
45906
|
+
u = 2 * rngRandom() - 1;
|
|
45907
|
+
v = 2 * rngRandom() - 1;
|
|
45908
|
+
s = u * u + v * v;
|
|
45909
|
+
} while (s >= 1 || s === 0);
|
|
45910
|
+
const mul = Math.sqrt(-2 * Math.log(s) / s);
|
|
45911
|
+
data[i] = u * mul;
|
|
45912
|
+
data[i + 1] = v * mul;
|
|
45913
|
+
}
|
|
45914
|
+
if (i < n) {
|
|
45915
|
+
data[i] = boxMullerRandom();
|
|
45916
|
+
}
|
|
44785
45917
|
}
|
|
44786
45918
|
function getRngStateStruct() {
|
|
44787
45919
|
const stateArray = _rngState ? RTV.tensor(new FloatXArray(Array.from(_rngState).map((v) => v)), [4, 1]) : RTV.tensor(new FloatXArray(0), [0, 1]);
|
|
@@ -44849,7 +45981,7 @@ registerIBuiltin({
|
|
|
44849
45981
|
};
|
|
44850
45982
|
}
|
|
44851
45983
|
});
|
|
44852
|
-
function registerRandBuiltin(name, gen) {
|
|
45984
|
+
function registerRandBuiltin(name, gen, bulkFill) {
|
|
44853
45985
|
defineBuiltin({
|
|
44854
45986
|
name,
|
|
44855
45987
|
cases: [
|
|
@@ -44888,7 +46020,11 @@ function registerRandBuiltin(name, gen) {
|
|
|
44888
46020
|
if (shape.length === 1) shape.push(shape[0]);
|
|
44889
46021
|
const n = numel(shape);
|
|
44890
46022
|
const data = new FloatXArray(n);
|
|
44891
|
-
|
|
46023
|
+
if (bulkFill) {
|
|
46024
|
+
bulkFill(data);
|
|
46025
|
+
} else {
|
|
46026
|
+
for (let i = 0; i < n; i++) data[i] = gen();
|
|
46027
|
+
}
|
|
44892
46028
|
return RTV.tensor(data, shape);
|
|
44893
46029
|
}
|
|
44894
46030
|
}
|
|
@@ -44896,7 +46032,7 @@ function registerRandBuiltin(name, gen) {
|
|
|
44896
46032
|
});
|
|
44897
46033
|
}
|
|
44898
46034
|
registerRandBuiltin("rand", rngRandom);
|
|
44899
|
-
registerRandBuiltin("randn", boxMullerRandom);
|
|
46035
|
+
registerRandBuiltin("randn", boxMullerRandom, fillRandn);
|
|
44900
46036
|
defineBuiltin({
|
|
44901
46037
|
name: "randi",
|
|
44902
46038
|
cases: [
|
|
@@ -45341,136 +46477,6 @@ registerIBuiltin({
|
|
|
45341
46477
|
}
|
|
45342
46478
|
});
|
|
45343
46479
|
|
|
45344
|
-
// src/numbl-core/interpreter/builtins/time-system.ts
|
|
45345
|
-
var ticTime = 0;
|
|
45346
|
-
defineBuiltin({
|
|
45347
|
-
name: "tic",
|
|
45348
|
-
cases: [
|
|
45349
|
-
{
|
|
45350
|
-
match: (argTypes) => argTypes.length === 0 ? [{ kind: "number" }] : null,
|
|
45351
|
-
apply: () => {
|
|
45352
|
-
ticTime = performance.now();
|
|
45353
|
-
return RTV.num(ticTime / 1e3);
|
|
45354
|
-
}
|
|
45355
|
-
}
|
|
45356
|
-
]
|
|
45357
|
-
});
|
|
45358
|
-
defineBuiltin({
|
|
45359
|
-
name: "toc",
|
|
45360
|
-
cases: [
|
|
45361
|
-
{
|
|
45362
|
-
match: (argTypes) => argTypes.length === 0 ? [{ kind: "number" }] : null,
|
|
45363
|
-
apply: () => RTV.num((performance.now() - ticTime) / 1e3)
|
|
45364
|
-
}
|
|
45365
|
-
]
|
|
45366
|
-
});
|
|
45367
|
-
defineBuiltin({
|
|
45368
|
-
name: "clock",
|
|
45369
|
-
cases: [
|
|
45370
|
-
{
|
|
45371
|
-
match: (argTypes) => argTypes.length === 0 ? [{ kind: "tensor", isComplex: false, shape: [1, 6] }] : null,
|
|
45372
|
-
apply: () => {
|
|
45373
|
-
const now = /* @__PURE__ */ new Date();
|
|
45374
|
-
return RTV.tensor(
|
|
45375
|
-
new FloatXArray([
|
|
45376
|
-
now.getFullYear(),
|
|
45377
|
-
now.getMonth() + 1,
|
|
45378
|
-
now.getDate(),
|
|
45379
|
-
now.getHours(),
|
|
45380
|
-
now.getMinutes(),
|
|
45381
|
-
now.getSeconds() + now.getMilliseconds() / 1e3
|
|
45382
|
-
]),
|
|
45383
|
-
[1, 6]
|
|
45384
|
-
);
|
|
45385
|
-
}
|
|
45386
|
-
}
|
|
45387
|
-
]
|
|
45388
|
-
});
|
|
45389
|
-
defineBuiltin({
|
|
45390
|
-
name: "etime",
|
|
45391
|
-
cases: [
|
|
45392
|
-
{
|
|
45393
|
-
match: (argTypes) => argTypes.length === 2 ? [{ kind: "number" }] : null,
|
|
45394
|
-
apply: (args) => {
|
|
45395
|
-
const t1 = args[0];
|
|
45396
|
-
const t0 = args[1];
|
|
45397
|
-
if (!isRuntimeTensor(t1) || !isRuntimeTensor(t0))
|
|
45398
|
-
throw new RuntimeError("etime: arguments must be clock vectors");
|
|
45399
|
-
const toMs = (t) => {
|
|
45400
|
-
const d = new Date(
|
|
45401
|
-
t.data[0],
|
|
45402
|
-
t.data[1] - 1,
|
|
45403
|
-
t.data[2],
|
|
45404
|
-
t.data[3],
|
|
45405
|
-
t.data[4],
|
|
45406
|
-
Math.floor(t.data[5]),
|
|
45407
|
-
t.data[5] % 1 * 1e3
|
|
45408
|
-
);
|
|
45409
|
-
return d.getTime();
|
|
45410
|
-
};
|
|
45411
|
-
return RTV.num((toMs(t1) - toMs(t0)) / 1e3);
|
|
45412
|
-
}
|
|
45413
|
-
}
|
|
45414
|
-
]
|
|
45415
|
-
});
|
|
45416
|
-
defineBuiltin({
|
|
45417
|
-
name: "version",
|
|
45418
|
-
cases: [
|
|
45419
|
-
{
|
|
45420
|
-
match: (argTypes) => argTypes.length === 0 ? [{ kind: "char" }] : null,
|
|
45421
|
-
apply: () => RTV.char("9.14.0")
|
|
45422
|
-
}
|
|
45423
|
-
]
|
|
45424
|
-
});
|
|
45425
|
-
function getComputerStrings() {
|
|
45426
|
-
if (typeof process === "undefined") {
|
|
45427
|
-
return { str: "BROWSER", arch: "browser" };
|
|
45428
|
-
}
|
|
45429
|
-
const platform = process.platform;
|
|
45430
|
-
const cpuArch = process.arch;
|
|
45431
|
-
if (platform === "win32") return { str: "PCWIN64", arch: "win64" };
|
|
45432
|
-
if (platform === "darwin") {
|
|
45433
|
-
if (cpuArch === "arm64") return { str: "MACA64", arch: "maca64" };
|
|
45434
|
-
return { str: "MACI64", arch: "maci64" };
|
|
45435
|
-
}
|
|
45436
|
-
return { str: "GLNXA64", arch: "glnxa64" };
|
|
45437
|
-
}
|
|
45438
|
-
registerIBuiltin({
|
|
45439
|
-
name: "computer",
|
|
45440
|
-
resolve: () => ({
|
|
45441
|
-
outputTypes: [{ kind: "unknown" }],
|
|
45442
|
-
apply: (args, nargout) => {
|
|
45443
|
-
const info = getComputerStrings();
|
|
45444
|
-
if (args.length >= 1 && isRuntimeChar(args[0])) {
|
|
45445
|
-
const arg = toString(args[0]);
|
|
45446
|
-
if (arg === "arch") return RTV.char(info.arch);
|
|
45447
|
-
throw new RuntimeError(`computer: unknown argument '${arg}'`);
|
|
45448
|
-
}
|
|
45449
|
-
const maxsize = 2 ** 48 - 1;
|
|
45450
|
-
const endian = RTV.char("L");
|
|
45451
|
-
if (nargout <= 1) return RTV.char(info.str);
|
|
45452
|
-
if (nargout === 2) return [RTV.char(info.str), RTV.num(maxsize)];
|
|
45453
|
-
return [RTV.char(info.str), RTV.num(maxsize), endian];
|
|
45454
|
-
}
|
|
45455
|
-
})
|
|
45456
|
-
});
|
|
45457
|
-
var _platform = typeof process !== "undefined" ? process.platform : "linux";
|
|
45458
|
-
for (const [name, val] of [
|
|
45459
|
-
["ismac", _platform === "darwin"],
|
|
45460
|
-
["ispc", _platform === "win32"],
|
|
45461
|
-
["isunix", _platform !== "win32"]
|
|
45462
|
-
]) {
|
|
45463
|
-
defineBuiltin({
|
|
45464
|
-
name,
|
|
45465
|
-
cases: [
|
|
45466
|
-
{
|
|
45467
|
-
match: (argTypes) => argTypes.length === 0 ? [{ kind: "boolean" }] : null,
|
|
45468
|
-
apply: () => RTV.logical(val)
|
|
45469
|
-
}
|
|
45470
|
-
]
|
|
45471
|
-
});
|
|
45472
|
-
}
|
|
45473
|
-
|
|
45474
46480
|
// src/numbl-core/interpreter/builtins/sparse.ts
|
|
45475
46481
|
function toNumericArray(v, name) {
|
|
45476
46482
|
if (isRuntimeNumber(v)) return [v];
|
|
@@ -48330,7 +49336,7 @@ function getSourceLine(getSource, file, line) {
|
|
|
48330
49336
|
}
|
|
48331
49337
|
|
|
48332
49338
|
// src/numbl-core/version.ts
|
|
48333
|
-
var NUMBL_VERSION = "0.1.
|
|
49339
|
+
var NUMBL_VERSION = "0.1.4";
|
|
48334
49340
|
|
|
48335
49341
|
// src/cli-repl.ts
|
|
48336
49342
|
import { createInterface } from "readline";
|
|
@@ -49592,9 +50598,7 @@ function lowerStmt(ctx, stmt) {
|
|
|
49592
50598
|
result = lowerAssign(ctx, stmt);
|
|
49593
50599
|
break;
|
|
49594
50600
|
case "ExprStmt":
|
|
49595
|
-
|
|
49596
|
-
result = lowerExprStmt(ctx, stmt);
|
|
49597
|
-
break;
|
|
50601
|
+
return null;
|
|
49598
50602
|
case "If":
|
|
49599
50603
|
result = lowerIf(ctx, stmt);
|
|
49600
50604
|
break;
|
|
@@ -49669,11 +50673,6 @@ function lowerMultiAssign(ctx, stmt) {
|
|
|
49669
50673
|
}
|
|
49670
50674
|
];
|
|
49671
50675
|
}
|
|
49672
|
-
function lowerExprStmt(ctx, stmt) {
|
|
49673
|
-
const expr = lowerExpr(ctx, stmt.expr);
|
|
49674
|
-
if (!expr) return null;
|
|
49675
|
-
return [{ tag: "ExprStmt", expr }];
|
|
49676
|
-
}
|
|
49677
50676
|
function lowerIf(ctx, stmt) {
|
|
49678
50677
|
const cond = lowerExpr(ctx, stmt.cond);
|
|
49679
50678
|
if (!cond) return null;
|
|
@@ -50742,10 +51741,14 @@ function execStmt(stmt) {
|
|
|
50742
51741
|
}
|
|
50743
51742
|
switch (stmt.type) {
|
|
50744
51743
|
case "ExprStmt": {
|
|
50745
|
-
const val = this.
|
|
51744
|
+
const val = this.evalExprNargout(stmt.expr, 0);
|
|
50746
51745
|
const singleVal = Array.isArray(val) ? val[0] : val;
|
|
51746
|
+
if (singleVal === void 0) {
|
|
51747
|
+
return null;
|
|
51748
|
+
}
|
|
50747
51749
|
const rv = ensureRuntimeValue(singleVal);
|
|
50748
51750
|
this.ans = rv;
|
|
51751
|
+
this.env.set("ans", rv);
|
|
50749
51752
|
if (!stmt.suppressed && !this.isOutputExpr(stmt.expr)) {
|
|
50750
51753
|
this.rt.displayResult(rv);
|
|
50751
51754
|
}
|
|
@@ -50766,19 +51769,25 @@ function execStmt(stmt) {
|
|
|
50766
51769
|
if (stmt.lvalues.length === 1 && stmt.lvalues[0].type === "IndexCell") {
|
|
50767
51770
|
const lv = stmt.lvalues[0];
|
|
50768
51771
|
const cellBase = lv.base.type === "Ident" ? this.env.get(lv.base.name) ?? RTV.cell([], [0, 0]) : this.evalExpr(lv.base);
|
|
50769
|
-
const indices =
|
|
50770
|
-
const idxVal = ensureRuntimeValue(indices[0]);
|
|
51772
|
+
const indices = this.evalIndicesWithEnd(cellBase, lv.indices);
|
|
50771
51773
|
let expandedCount = 1;
|
|
50772
|
-
|
|
50773
|
-
|
|
50774
|
-
|
|
50775
|
-
expandedCount =
|
|
51774
|
+
const idx0 = indices[0];
|
|
51775
|
+
if (idx0 === COLON_SENTINEL) {
|
|
51776
|
+
const baseRv = ensureRuntimeValue(cellBase);
|
|
51777
|
+
expandedCount = isRuntimeCell(baseRv) ? baseRv.data.length : 0;
|
|
51778
|
+
} else {
|
|
51779
|
+
const idxVal = ensureRuntimeValue(idx0);
|
|
51780
|
+
if (isRuntimeTensor(idxVal)) {
|
|
51781
|
+
expandedCount = idxVal.data.length;
|
|
51782
|
+
} else if (typeof idxVal === "number") {
|
|
51783
|
+
expandedCount = 1;
|
|
51784
|
+
}
|
|
50776
51785
|
}
|
|
50777
51786
|
const val2 = this.evalExprNargout(stmt.expr, expandedCount);
|
|
50778
51787
|
const values2 = Array.isArray(val2) ? val2 : [val2];
|
|
50779
51788
|
const result = this.rt.multiOutputCellAssign(
|
|
50780
51789
|
cellBase,
|
|
50781
|
-
|
|
51790
|
+
idx0,
|
|
50782
51791
|
values2.map((v) => ensureRuntimeValue(v))
|
|
50783
51792
|
);
|
|
50784
51793
|
if (lv.base.type === "Ident") {
|
|
@@ -50795,10 +51804,12 @@ function execStmt(stmt) {
|
|
|
50795
51804
|
const rv = this.rt.share(i < values.length ? values[i] : void 0);
|
|
50796
51805
|
this.assignLValue(lv, rv);
|
|
50797
51806
|
}
|
|
50798
|
-
if (!stmt.suppressed
|
|
50799
|
-
|
|
50800
|
-
|
|
50801
|
-
|
|
51807
|
+
if (!stmt.suppressed) {
|
|
51808
|
+
for (let i = 0; i < stmt.lvalues.length; i++) {
|
|
51809
|
+
const lv = stmt.lvalues[i];
|
|
51810
|
+
if (lv.type === "Var" && i < values.length) {
|
|
51811
|
+
this.rt.displayAssign(lv.name, ensureRuntimeValue(values[i]));
|
|
51812
|
+
}
|
|
50802
51813
|
}
|
|
50803
51814
|
}
|
|
50804
51815
|
return null;
|
|
@@ -51155,6 +52166,18 @@ function evalArgs(argExprs) {
|
|
|
51155
52166
|
}
|
|
51156
52167
|
return args;
|
|
51157
52168
|
}
|
|
52169
|
+
var binopProfileName = {
|
|
52170
|
+
["Add" /* Add */]: "plus",
|
|
52171
|
+
["Sub" /* Sub */]: "minus",
|
|
52172
|
+
["Mul" /* Mul */]: "mtimes",
|
|
52173
|
+
["ElemMul" /* ElemMul */]: "times",
|
|
52174
|
+
["Div" /* Div */]: "mrdivide",
|
|
52175
|
+
["ElemDiv" /* ElemDiv */]: "rdivide",
|
|
52176
|
+
["LeftDiv" /* LeftDiv */]: "mldivide",
|
|
52177
|
+
["ElemLeftDiv" /* ElemLeftDiv */]: "ldivide",
|
|
52178
|
+
["Pow" /* Pow */]: "mpower",
|
|
52179
|
+
["ElemPow" /* ElemPow */]: "power"
|
|
52180
|
+
};
|
|
51158
52181
|
function evalBinary(expr) {
|
|
51159
52182
|
if (expr.op === "AndAnd" /* AndAnd */) {
|
|
51160
52183
|
const left2 = this.evalExpr(expr.left);
|
|
@@ -51180,6 +52203,13 @@ function evalBinary(expr) {
|
|
|
51180
52203
|
if (!isNaN(r)) return r;
|
|
51181
52204
|
return mPow(ensureRuntimeValue(left), ensureRuntimeValue(right));
|
|
51182
52205
|
}
|
|
52206
|
+
if (this.rt.profilingEnabled && (typeof left !== "number" || typeof right !== "number")) {
|
|
52207
|
+
const opName = binopProfileName[expr.op] ?? expr.op;
|
|
52208
|
+
this.rt.profileEnter("builtin:interp:" + opName);
|
|
52209
|
+
const result = binop(expr.op, left, right);
|
|
52210
|
+
this.rt.profileLeave();
|
|
52211
|
+
return result;
|
|
52212
|
+
}
|
|
51183
52213
|
return binop(expr.op, left, right);
|
|
51184
52214
|
}
|
|
51185
52215
|
function evalUnary(expr) {
|
|
@@ -51319,7 +52349,11 @@ function evalAnonFunc(expr) {
|
|
|
51319
52349
|
capturedMethodName,
|
|
51320
52350
|
() => {
|
|
51321
52351
|
try {
|
|
51322
|
-
|
|
52352
|
+
const result = this.evalExprNargout(bodyExpr, narg);
|
|
52353
|
+
if (narg > 1 && !(Array.isArray(result) && result.length >= narg)) {
|
|
52354
|
+
throw new RuntimeError("Too many output arguments.");
|
|
52355
|
+
}
|
|
52356
|
+
return result;
|
|
51323
52357
|
} finally {
|
|
51324
52358
|
this.env = savedEnv;
|
|
51325
52359
|
}
|
|
@@ -51578,7 +52612,6 @@ function switchMatch2(switchVal, caseVal) {
|
|
|
51578
52612
|
return switchMatch(switchVal, caseVal);
|
|
51579
52613
|
}
|
|
51580
52614
|
function isOutputExpr(expr) {
|
|
51581
|
-
if (expr.type !== "FuncCall") return false;
|
|
51582
52615
|
const outputFunctions = [
|
|
51583
52616
|
"disp",
|
|
51584
52617
|
"display",
|
|
@@ -51586,9 +52619,12 @@ function isOutputExpr(expr) {
|
|
|
51586
52619
|
"warning",
|
|
51587
52620
|
"assert",
|
|
51588
52621
|
"tic",
|
|
52622
|
+
"toc",
|
|
51589
52623
|
"help"
|
|
51590
52624
|
];
|
|
51591
|
-
return outputFunctions.includes(expr.name);
|
|
52625
|
+
if (expr.type === "FuncCall") return outputFunctions.includes(expr.name);
|
|
52626
|
+
if (expr.type === "Ident") return outputFunctions.includes(expr.name);
|
|
52627
|
+
return false;
|
|
51592
52628
|
}
|
|
51593
52629
|
|
|
51594
52630
|
// src/numbl-core/interpreter/interpreterFunctions.ts
|
|
@@ -51797,6 +52833,17 @@ register("exist", (ctx, args) => {
|
|
|
51797
52833
|
}
|
|
51798
52834
|
return FALL_THROUGH;
|
|
51799
52835
|
});
|
|
52836
|
+
register("which", (ctx, args) => {
|
|
52837
|
+
if (args.length < 1) return FALL_THROUGH;
|
|
52838
|
+
const nameArg = toString(ensureRuntimeValue(args[0]));
|
|
52839
|
+
if (ctx.env.has(nameArg)) return RTV.char("variable");
|
|
52840
|
+
const filePath = ctx.lookupWorkspaceFile(nameArg);
|
|
52841
|
+
if (filePath) return RTV.char(filePath);
|
|
52842
|
+
if (ctx.rt.builtins[nameArg] || getIBuiltin(nameArg)) {
|
|
52843
|
+
return RTV.char("built-in");
|
|
52844
|
+
}
|
|
52845
|
+
return RTV.char("");
|
|
52846
|
+
});
|
|
51800
52847
|
register("isfolder", (ctx, args) => {
|
|
51801
52848
|
if (args.length < 1) return FALL_THROUGH;
|
|
51802
52849
|
const fio = ctx.rt.fileIO;
|
|
@@ -51899,6 +52946,9 @@ register("run", (ctx, args) => {
|
|
|
51899
52946
|
} catch {
|
|
51900
52947
|
throw new RuntimeError(`Cannot change directory to '${scriptDir}'`);
|
|
51901
52948
|
}
|
|
52949
|
+
if (ctx.rt.onCwdChange) {
|
|
52950
|
+
ctx.rt.onCwdChange(sys.cwd());
|
|
52951
|
+
}
|
|
51902
52952
|
}
|
|
51903
52953
|
const cwdAfterCd = sys?.cwd() ?? "/";
|
|
51904
52954
|
try {
|
|
@@ -51910,6 +52960,9 @@ register("run", (ctx, args) => {
|
|
|
51910
52960
|
sys.chdir(oldCwd);
|
|
51911
52961
|
} catch {
|
|
51912
52962
|
}
|
|
52963
|
+
if (ctx.rt.onCwdChange) {
|
|
52964
|
+
ctx.rt.onCwdChange(sys.cwd());
|
|
52965
|
+
}
|
|
51913
52966
|
}
|
|
51914
52967
|
}
|
|
51915
52968
|
return void 0;
|
|
@@ -51929,7 +52982,14 @@ function callFunction(name, args, nargout) {
|
|
|
51929
52982
|
workspaceEnv: this.workspaceEnv,
|
|
51930
52983
|
evalInLocalScope: (codeArg, fileName) => this.evalInLocalScope(codeArg, fileName),
|
|
51931
52984
|
callFunction: (n, a, no) => this.callFunction(n, a, no),
|
|
51932
|
-
rt: this.rt
|
|
52985
|
+
rt: this.rt,
|
|
52986
|
+
lookupWorkspaceFile: (n) => {
|
|
52987
|
+
const entry = this.ctx.registry.filesByFuncName.get(n);
|
|
52988
|
+
if (entry) return entry.fileName;
|
|
52989
|
+
const classInfo = this.ctx.getClassInfo(n);
|
|
52990
|
+
if (classInfo) return classInfo.fileName;
|
|
52991
|
+
return void 0;
|
|
52992
|
+
}
|
|
51933
52993
|
};
|
|
51934
52994
|
const result = specialHandler(ctx, args, nargout);
|
|
51935
52995
|
if (result !== FALL_THROUGH) return result;
|
|
@@ -51963,13 +53023,18 @@ function interpretTarget(target, args, nargout) {
|
|
|
51963
53023
|
const argTypes = margs.map(inferJitType);
|
|
51964
53024
|
const resolution = ib.resolve(argTypes, nargout);
|
|
51965
53025
|
if (resolution) {
|
|
53026
|
+
const isVoid = resolution.outputTypes.length === 0;
|
|
53027
|
+
if (isVoid && nargout > 0) {
|
|
53028
|
+
throw new RuntimeError("Too many output arguments.");
|
|
53029
|
+
}
|
|
51966
53030
|
if (this.rt.profilingEnabled) {
|
|
51967
53031
|
this.rt.profileEnter("builtin:interp:" + target.name);
|
|
51968
|
-
const
|
|
53032
|
+
const result2 = resolution.apply(margs, nargout);
|
|
51969
53033
|
this.rt.profileLeave();
|
|
51970
|
-
return
|
|
53034
|
+
return isVoid ? void 0 : result2;
|
|
51971
53035
|
}
|
|
51972
|
-
|
|
53036
|
+
const result = resolution.apply(margs, nargout);
|
|
53037
|
+
return isVoid ? void 0 : result;
|
|
51973
53038
|
}
|
|
51974
53039
|
}
|
|
51975
53040
|
const builtin = this.rt.builtins[target.name];
|
|
@@ -52061,7 +53126,19 @@ function interpretLocalFunction(target, args, nargout) {
|
|
|
52061
53126
|
function interpretWorkspaceFunction(target, args, nargout) {
|
|
52062
53127
|
const dotIdx = target.name.lastIndexOf(".");
|
|
52063
53128
|
const primaryName = dotIdx >= 0 ? target.name.slice(dotIdx + 1) : target.name;
|
|
52064
|
-
|
|
53129
|
+
let fn = this.findFunctionInWorkspaceFile(target.name, primaryName);
|
|
53130
|
+
if (!fn) {
|
|
53131
|
+
const entry = this.ctx.registry.filesByFuncName.get(target.name);
|
|
53132
|
+
if (entry) {
|
|
53133
|
+
const ast = this.ctx.getCachedAST(entry.fileName);
|
|
53134
|
+
for (const stmt of ast.body) {
|
|
53135
|
+
if (stmt.type === "Function") {
|
|
53136
|
+
fn = funcDefFromStmt(stmt);
|
|
53137
|
+
break;
|
|
53138
|
+
}
|
|
53139
|
+
}
|
|
53140
|
+
}
|
|
53141
|
+
}
|
|
52065
53142
|
if (!fn) {
|
|
52066
53143
|
const entry = this.ctx.registry.filesByFuncName.get(target.name);
|
|
52067
53144
|
if (entry) {
|
|
@@ -52205,6 +53282,11 @@ function interpretConstructor(classInfo, args, nargout) {
|
|
|
52205
53282
|
return args[0];
|
|
52206
53283
|
}
|
|
52207
53284
|
function callUserFunction(fn, args, nargout, narginOverride) {
|
|
53285
|
+
const hasVarargoutDecl = fn.outputs.length > 0 && fn.outputs[fn.outputs.length - 1] === "varargout";
|
|
53286
|
+
const declaredRegularOutputs = hasVarargoutDecl ? fn.outputs.length - 1 : fn.outputs.length;
|
|
53287
|
+
if (!hasVarargoutDecl && nargout > declaredRegularOutputs) {
|
|
53288
|
+
throw new RuntimeError("Too many output arguments.");
|
|
53289
|
+
}
|
|
52208
53290
|
if (this.optimization >= 1 && narginOverride === void 0) {
|
|
52209
53291
|
const jitResult = tryJitCall(this, fn, args, nargout);
|
|
52210
53292
|
if (jitResult !== JIT_SKIP) return jitResult;
|
|
@@ -52254,10 +53336,11 @@ function callUserFunction(fn, args, nargout, narginOverride) {
|
|
|
52254
53336
|
}
|
|
52255
53337
|
}
|
|
52256
53338
|
}
|
|
52257
|
-
const hasVarargout =
|
|
53339
|
+
const hasVarargout = hasVarargoutDecl;
|
|
52258
53340
|
const regularOutputs = hasVarargout ? fn.outputs.slice(0, -1) : fn.outputs;
|
|
53341
|
+
const collectCount = nargout === 0 && regularOutputs.length > 0 ? 1 : Math.min(regularOutputs.length, nargout);
|
|
52259
53342
|
const outputs = [];
|
|
52260
|
-
for (let i = 0; i <
|
|
53343
|
+
for (let i = 0; i < collectCount; i++) {
|
|
52261
53344
|
const val = this.env.get(regularOutputs[i]);
|
|
52262
53345
|
if (val === void 0 && nargout >= i + 1) {
|
|
52263
53346
|
throw new RuntimeError(
|
|
@@ -53827,10 +54910,17 @@ function executeCode(source, options = {}, workspaceFiles, mainFileName = "scrip
|
|
|
53827
54910
|
if (options.log) {
|
|
53828
54911
|
options.log("AST parsed, starting interpretation");
|
|
53829
54912
|
}
|
|
54913
|
+
const isRepl = mainFileName === "repl";
|
|
53830
54914
|
const localFunctions = [];
|
|
53831
54915
|
const localClasses = [];
|
|
53832
54916
|
for (const stmt of ast.body) {
|
|
53833
54917
|
if (stmt.type === "Function") {
|
|
54918
|
+
if (isRepl) {
|
|
54919
|
+
throw new RuntimeError(
|
|
54920
|
+
"Function definitions are not supported in the REPL. Save the function to a .m file instead.",
|
|
54921
|
+
stmt.span
|
|
54922
|
+
);
|
|
54923
|
+
}
|
|
53834
54924
|
localFunctions.push(stmt);
|
|
53835
54925
|
} else if (stmt.type === "ClassDef") {
|
|
53836
54926
|
localClasses.push(stmt);
|
|
@@ -53851,6 +54941,31 @@ function executeCode(source, options = {}, workspaceFiles, mainFileName = "scrip
|
|
|
53851
54941
|
}
|
|
53852
54942
|
}
|
|
53853
54943
|
}
|
|
54944
|
+
let implicitCwdPath = null;
|
|
54945
|
+
if (options.implicitCwdPath !== null && options.system && options.fileIO?.scanDirectory) {
|
|
54946
|
+
try {
|
|
54947
|
+
const cwd = options.implicitCwdPath ?? options.system.cwd();
|
|
54948
|
+
const absCwd = options.fileIO.resolvePath?.(cwd) ?? cwd;
|
|
54949
|
+
const explicitPaths = searchPaths ?? [];
|
|
54950
|
+
if (!explicitPaths.includes(absCwd)) {
|
|
54951
|
+
implicitCwdPath = absCwd;
|
|
54952
|
+
const prefix = absCwd.endsWith("/") ? absCwd : absCwd + "/";
|
|
54953
|
+
const alreadyHave = mWorkspaceFiles.some(
|
|
54954
|
+
(f) => f.name === absCwd || f.name.startsWith(prefix)
|
|
54955
|
+
);
|
|
54956
|
+
if (!alreadyHave) {
|
|
54957
|
+
const cwdFiles = options.fileIO.scanDirectory(absCwd);
|
|
54958
|
+
for (const f of cwdFiles) {
|
|
54959
|
+
if (f.name.endsWith(".m")) {
|
|
54960
|
+
mWorkspaceFiles.push(f);
|
|
54961
|
+
}
|
|
54962
|
+
}
|
|
54963
|
+
}
|
|
54964
|
+
}
|
|
54965
|
+
} catch {
|
|
54966
|
+
implicitCwdPath = null;
|
|
54967
|
+
}
|
|
54968
|
+
}
|
|
53854
54969
|
const jsUserFunctions = loadJsUserFunctions(
|
|
53855
54970
|
jsWorkspaceFiles,
|
|
53856
54971
|
wasmWorkspaceFiles,
|
|
@@ -53868,6 +54983,9 @@ function executeCode(source, options = {}, workspaceFiles, mainFileName = "scrip
|
|
|
53868
54983
|
stdlibShimNames.add(shimName);
|
|
53869
54984
|
}
|
|
53870
54985
|
ctx.registry.searchPaths = [...searchPaths ?? [], SHIM_SEARCH_PATH];
|
|
54986
|
+
if (implicitCwdPath !== null) {
|
|
54987
|
+
ctx.registry.searchPaths.unshift(implicitCwdPath);
|
|
54988
|
+
}
|
|
53871
54989
|
ctx.fileASTCache.set(mainFileName, ast);
|
|
53872
54990
|
const skippedFiles = /* @__PURE__ */ new Set();
|
|
53873
54991
|
for (const f of mWorkspaceFiles) {
|
|
@@ -53901,6 +55019,11 @@ function executeCode(source, options = {}, workspaceFiles, mainFileName = "scrip
|
|
|
53901
55019
|
ctx.registerWorkspaceFiles(mWorkspaceFiles);
|
|
53902
55020
|
}
|
|
53903
55021
|
const functionIndex = ctx.buildFunctionIndex(jsUserFunctionNames);
|
|
55022
|
+
const savedSpecialBuiltins = /* @__PURE__ */ new Map();
|
|
55023
|
+
for (const name of SPECIAL_BUILTIN_NAMES) {
|
|
55024
|
+
const existing = getIBuiltin(name);
|
|
55025
|
+
if (existing) savedSpecialBuiltins.set(name, existing);
|
|
55026
|
+
}
|
|
53904
55027
|
const rt = new Runtime(options, options.initialVariableValues);
|
|
53905
55028
|
const savedIBuiltins = /* @__PURE__ */ new Map();
|
|
53906
55029
|
for (const ib of jsUserFunctions) {
|
|
@@ -53942,13 +55065,39 @@ ${jsCode}`
|
|
|
53942
55065
|
interpreter.installRuntimeCallbacks();
|
|
53943
55066
|
rt.searchPaths = ctx.registry.searchPaths;
|
|
53944
55067
|
let pathsModified = false;
|
|
55068
|
+
const rebuildWorkspace = () => {
|
|
55069
|
+
const paths = ctx.registry.searchPaths;
|
|
55070
|
+
const priorityOf = (name) => {
|
|
55071
|
+
let bestIdx = paths.length;
|
|
55072
|
+
let bestLen = -1;
|
|
55073
|
+
for (let i = 0; i < paths.length; i++) {
|
|
55074
|
+
const p2 = paths[i];
|
|
55075
|
+
const withSep = p2.endsWith("/") ? p2 : p2 + "/";
|
|
55076
|
+
if (name === p2 || name.startsWith(withSep)) {
|
|
55077
|
+
if (p2.length > bestLen) {
|
|
55078
|
+
bestLen = p2.length;
|
|
55079
|
+
bestIdx = i;
|
|
55080
|
+
}
|
|
55081
|
+
}
|
|
55082
|
+
}
|
|
55083
|
+
return bestIdx;
|
|
55084
|
+
};
|
|
55085
|
+
mWorkspaceFiles.sort((a, b) => priorityOf(a.name) - priorityOf(b.name));
|
|
55086
|
+
ctx.clearWorkspaceRegistrations();
|
|
55087
|
+
ctx.registerWorkspaceFiles(mWorkspaceFiles);
|
|
55088
|
+
const newIndex = ctx.buildFunctionIndex(jsUserFunctionNames);
|
|
55089
|
+
interpreter.functionIndex = newIndex;
|
|
55090
|
+
interpreter.clearAllCaches();
|
|
55091
|
+
pathsModified = true;
|
|
55092
|
+
};
|
|
53945
55093
|
rt.onPathChange = (action, dir, position) => {
|
|
53946
55094
|
const fileIO = options.fileIO;
|
|
53947
55095
|
const absDir = fileIO?.resolvePath?.(dir) ?? dir;
|
|
53948
55096
|
if (action === "add") {
|
|
53949
55097
|
if (ctx.registry.searchPaths.includes(absDir)) return;
|
|
53950
55098
|
if (position === "begin") {
|
|
53951
|
-
ctx.registry.searchPaths
|
|
55099
|
+
const cwdIsFirst = implicitCwdPath !== null && ctx.registry.searchPaths[0] === implicitCwdPath;
|
|
55100
|
+
ctx.registry.searchPaths.splice(cwdIsFirst ? 1 : 0, 0, absDir);
|
|
53952
55101
|
} else {
|
|
53953
55102
|
const shimIdx = ctx.registry.searchPaths.indexOf(SHIM_SEARCH_PATH);
|
|
53954
55103
|
if (shimIdx >= 0) {
|
|
@@ -53966,10 +55115,14 @@ ${jsCode}`
|
|
|
53966
55115
|
try {
|
|
53967
55116
|
ctx.fileASTCache.set(f.name, parseMFile(f.source, f.name));
|
|
53968
55117
|
} catch (e) {
|
|
53969
|
-
if (e instanceof SyntaxError
|
|
53970
|
-
|
|
55118
|
+
if (e instanceof SyntaxError) {
|
|
55119
|
+
console.warn(
|
|
55120
|
+
`Warning: skipping ${f.name} (syntax error at line ${e.line ?? "?"})`
|
|
55121
|
+
);
|
|
55122
|
+
} else {
|
|
55123
|
+
console.warn(`Warning: skipping ${f.name} (parse error)`);
|
|
53971
55124
|
}
|
|
53972
|
-
|
|
55125
|
+
continue;
|
|
53973
55126
|
}
|
|
53974
55127
|
interpreter.fileSources.set(f.name, f.source);
|
|
53975
55128
|
mWorkspaceFiles.push(f);
|
|
@@ -54009,26 +55162,76 @@ ${jsCode}`
|
|
|
54009
55162
|
}
|
|
54010
55163
|
}
|
|
54011
55164
|
}
|
|
54012
|
-
|
|
54013
|
-
|
|
54014
|
-
|
|
54015
|
-
|
|
54016
|
-
|
|
54017
|
-
|
|
54018
|
-
|
|
55165
|
+
rebuildWorkspace();
|
|
55166
|
+
};
|
|
55167
|
+
rt.onCwdChange = (newCwd) => {
|
|
55168
|
+
const fileIO = options.fileIO;
|
|
55169
|
+
const absNewCwd = fileIO?.resolvePath?.(newCwd) ?? newCwd;
|
|
55170
|
+
if (implicitCwdPath === absNewCwd) return;
|
|
55171
|
+
if (implicitCwdPath !== null) {
|
|
55172
|
+
const oldPrefix = implicitCwdPath.endsWith("/") ? implicitCwdPath : implicitCwdPath + "/";
|
|
55173
|
+
const deeperPaths = ctx.registry.searchPaths.filter(
|
|
55174
|
+
(p2) => p2 !== implicitCwdPath && p2 !== SHIM_SEARCH_PATH && (p2 === implicitCwdPath || p2.startsWith(oldPrefix))
|
|
54019
55175
|
);
|
|
54020
|
-
const
|
|
54021
|
-
|
|
54022
|
-
|
|
54023
|
-
|
|
54024
|
-
|
|
54025
|
-
|
|
54026
|
-
|
|
54027
|
-
|
|
54028
|
-
|
|
54029
|
-
|
|
55176
|
+
const fileBelongsToDeeperPath = (fname) => {
|
|
55177
|
+
for (const p2 of deeperPaths) {
|
|
55178
|
+
const withSep = p2.endsWith("/") ? p2 : p2 + "/";
|
|
55179
|
+
if (fname === p2 || fname.startsWith(withSep)) return true;
|
|
55180
|
+
}
|
|
55181
|
+
return false;
|
|
55182
|
+
};
|
|
55183
|
+
for (let i = mWorkspaceFiles.length - 1; i >= 0; i--) {
|
|
55184
|
+
const fname = mWorkspaceFiles[i].name;
|
|
55185
|
+
if ((fname === implicitCwdPath || fname.startsWith(oldPrefix)) && !fileBelongsToDeeperPath(fname)) {
|
|
55186
|
+
ctx.fileASTCache.delete(fname);
|
|
55187
|
+
interpreter.fileSources.delete(fname);
|
|
55188
|
+
mWorkspaceFiles.splice(i, 1);
|
|
55189
|
+
}
|
|
55190
|
+
}
|
|
55191
|
+
const oldIdx = ctx.registry.searchPaths.indexOf(implicitCwdPath);
|
|
55192
|
+
if (oldIdx >= 0) ctx.registry.searchPaths.splice(oldIdx, 1);
|
|
55193
|
+
implicitCwdPath = null;
|
|
55194
|
+
}
|
|
55195
|
+
if (ctx.registry.searchPaths.includes(absNewCwd)) {
|
|
55196
|
+
rebuildWorkspace();
|
|
55197
|
+
return;
|
|
55198
|
+
}
|
|
55199
|
+
ctx.registry.searchPaths.unshift(absNewCwd);
|
|
55200
|
+
implicitCwdPath = absNewCwd;
|
|
55201
|
+
if (fileIO?.scanDirectory) {
|
|
55202
|
+
let newFiles = [];
|
|
55203
|
+
try {
|
|
55204
|
+
newFiles = fileIO.scanDirectory(absNewCwd);
|
|
55205
|
+
} catch {
|
|
55206
|
+
}
|
|
55207
|
+
for (const f of newFiles) {
|
|
55208
|
+
if (f.name.endsWith(".m") && !ctx.fileASTCache.has(f.name)) {
|
|
55209
|
+
try {
|
|
55210
|
+
ctx.fileASTCache.set(f.name, parseMFile(f.source, f.name));
|
|
55211
|
+
} catch (e) {
|
|
55212
|
+
if (e instanceof SyntaxError) {
|
|
55213
|
+
console.warn(
|
|
55214
|
+
`Warning: skipping ${f.name} (syntax error at line ${e.line ?? "?"})`
|
|
55215
|
+
);
|
|
55216
|
+
} else {
|
|
55217
|
+
console.warn(`Warning: skipping ${f.name} (parse error)`);
|
|
55218
|
+
}
|
|
55219
|
+
continue;
|
|
55220
|
+
}
|
|
55221
|
+
interpreter.fileSources.set(f.name, f.source);
|
|
55222
|
+
mWorkspaceFiles.push(f);
|
|
55223
|
+
}
|
|
55224
|
+
}
|
|
55225
|
+
}
|
|
55226
|
+
rebuildWorkspace();
|
|
54030
55227
|
};
|
|
54031
55228
|
rt.evalLocalCallback = (code, initialVars, onOutput, fileName) => {
|
|
55229
|
+
const nestedSearchPaths = ctx.registry.searchPaths.filter(
|
|
55230
|
+
(p2) => p2 !== SHIM_SEARCH_PATH && p2 !== implicitCwdPath
|
|
55231
|
+
);
|
|
55232
|
+
const nestedWorkspaceFiles = mWorkspaceFiles.filter(
|
|
55233
|
+
(f) => !stdlibShimNames.has(f.name)
|
|
55234
|
+
);
|
|
54032
55235
|
const evalResult = executeCode(
|
|
54033
55236
|
code,
|
|
54034
55237
|
{
|
|
@@ -54036,11 +55239,18 @@ ${jsCode}`
|
|
|
54036
55239
|
displayResults: false,
|
|
54037
55240
|
initialVariableValues: initialVars,
|
|
54038
55241
|
fileIO: options.fileIO,
|
|
54039
|
-
|
|
55242
|
+
system: options.system,
|
|
55243
|
+
onInput: options.onInput,
|
|
55244
|
+
implicitCwdPath
|
|
54040
55245
|
},
|
|
54041
|
-
|
|
54042
|
-
fileName
|
|
55246
|
+
nestedWorkspaceFiles,
|
|
55247
|
+
fileName,
|
|
55248
|
+
nestedSearchPaths,
|
|
55249
|
+
nativeBridge2
|
|
54043
55250
|
);
|
|
55251
|
+
if (evalResult.implicitCwdPath !== void 0) {
|
|
55252
|
+
implicitCwdPath = evalResult.implicitCwdPath;
|
|
55253
|
+
}
|
|
54044
55254
|
return {
|
|
54045
55255
|
returnValue: evalResult.returnValue,
|
|
54046
55256
|
variableValues: evalResult.variableValues,
|
|
@@ -54056,7 +55266,7 @@ ${jsCode}`
|
|
|
54056
55266
|
output: rt.outputLines,
|
|
54057
55267
|
generatedJS: jitSections.length > 0 ? `// Interpreter mode \u2014 JIT compiled sections:
|
|
54058
55268
|
|
|
54059
|
-
${jitSections.join("\n\n")}` : "//
|
|
55269
|
+
${jitSections.join("\n\n")}` : "// No JS generated",
|
|
54060
55270
|
plotInstructions: rt.plotInstructions,
|
|
54061
55271
|
returnValue: interpreter.ans ?? RTV.num(0),
|
|
54062
55272
|
variableValues: interpreter.getVariableValues(),
|
|
@@ -54072,17 +55282,18 @@ ${jitSections.join("\n\n")}` : "// interpreted mode \u2014 no JS generated",
|
|
|
54072
55282
|
}
|
|
54073
55283
|
if (pathsModified) {
|
|
54074
55284
|
result.searchPaths = ctx.registry.searchPaths.filter(
|
|
54075
|
-
(p2) => p2 !== SHIM_SEARCH_PATH
|
|
55285
|
+
(p2) => p2 !== SHIM_SEARCH_PATH && p2 !== implicitCwdPath
|
|
54076
55286
|
);
|
|
54077
55287
|
result.workspaceFiles = mWorkspaceFiles.filter(
|
|
54078
55288
|
(f) => !stdlibShimNames.has(f.name)
|
|
54079
55289
|
);
|
|
54080
55290
|
}
|
|
55291
|
+
result.implicitCwdPath = implicitCwdPath;
|
|
54081
55292
|
return result;
|
|
54082
55293
|
} catch (e) {
|
|
54083
55294
|
const generatedJS = jitSections.length > 0 ? `// Interpreter mode \u2014 JIT compiled sections:
|
|
54084
55295
|
|
|
54085
|
-
${jitSections.join("\n\n")}` : "//
|
|
55296
|
+
${jitSections.join("\n\n")}` : "// No JS generated";
|
|
54086
55297
|
if (e instanceof RuntimeError) {
|
|
54087
55298
|
if (e.line === null && rt.$file && rt.$line > 0) {
|
|
54088
55299
|
e.file = rt.$file;
|
|
@@ -54113,6 +55324,9 @@ ${jitSections.join("\n\n")}` : "// interpreted mode \u2014 no JS generated";
|
|
|
54113
55324
|
unregisterIBuiltin(ib.name);
|
|
54114
55325
|
}
|
|
54115
55326
|
}
|
|
55327
|
+
for (const [, ib] of savedSpecialBuiltins) {
|
|
55328
|
+
registerDynamicIBuiltin(ib);
|
|
55329
|
+
}
|
|
54116
55330
|
}
|
|
54117
55331
|
}
|
|
54118
55332
|
|
|
@@ -54130,9 +55344,11 @@ import {
|
|
|
54130
55344
|
unlinkSync,
|
|
54131
55345
|
readdirSync as readdirSync2,
|
|
54132
55346
|
rmSync,
|
|
54133
|
-
rmdirSync
|
|
55347
|
+
rmdirSync,
|
|
55348
|
+
renameSync,
|
|
55349
|
+
chmodSync
|
|
54134
55350
|
} from "fs";
|
|
54135
|
-
import {
|
|
55351
|
+
import { unzipSync } from "fflate";
|
|
54136
55352
|
import { execFileSync } from "child_process";
|
|
54137
55353
|
import { homedir, tmpdir } from "os";
|
|
54138
55354
|
import { join as join3, resolve, dirname, basename } from "path";
|
|
@@ -54189,6 +55405,18 @@ function expandTilde(filepath) {
|
|
|
54189
55405
|
}
|
|
54190
55406
|
return filepath;
|
|
54191
55407
|
}
|
|
55408
|
+
function copyDirRecursive(src, dst) {
|
|
55409
|
+
mkdirSync(dst, { recursive: true });
|
|
55410
|
+
for (const entry of readdirSync2(src, { withFileTypes: true })) {
|
|
55411
|
+
const s = join3(src, entry.name);
|
|
55412
|
+
const d = join3(dst, entry.name);
|
|
55413
|
+
if (entry.isDirectory()) {
|
|
55414
|
+
copyDirRecursive(s, d);
|
|
55415
|
+
} else {
|
|
55416
|
+
writeFileSync(d, readFileSync3(s));
|
|
55417
|
+
}
|
|
55418
|
+
}
|
|
55419
|
+
}
|
|
54192
55420
|
function permissionToFlags(permission) {
|
|
54193
55421
|
switch (permission) {
|
|
54194
55422
|
case "r":
|
|
@@ -54208,6 +55436,21 @@ function permissionToFlags(permission) {
|
|
|
54208
55436
|
}
|
|
54209
55437
|
}
|
|
54210
55438
|
var READ_CHUNK_SIZE = 8192;
|
|
55439
|
+
function buildFetchOptions(options) {
|
|
55440
|
+
const init = {};
|
|
55441
|
+
if (options?.requestMethod) {
|
|
55442
|
+
init.method = options.requestMethod.toUpperCase();
|
|
55443
|
+
}
|
|
55444
|
+
const headers = {};
|
|
55445
|
+
if (options?.username && options?.password) {
|
|
55446
|
+
headers["Authorization"] = "Basic " + Buffer.from(`${options.username}:${options.password}`).toString("base64");
|
|
55447
|
+
}
|
|
55448
|
+
if (options?.keyName && options?.keyValue) {
|
|
55449
|
+
headers[options.keyName] = options.keyValue;
|
|
55450
|
+
}
|
|
55451
|
+
if (Object.keys(headers).length > 0) init.headers = headers;
|
|
55452
|
+
return init;
|
|
55453
|
+
}
|
|
54211
55454
|
var NodeFileIOAdapter = class {
|
|
54212
55455
|
nextFid = 3;
|
|
54213
55456
|
// 0=stdin, 1=stdout, 2=stderr reserved
|
|
@@ -54381,35 +55624,43 @@ var NodeFileIOAdapter = class {
|
|
|
54381
55624
|
tempdir() {
|
|
54382
55625
|
return tmpdir();
|
|
54383
55626
|
}
|
|
54384
|
-
websave(url, filename) {
|
|
55627
|
+
websave(url, filename, options) {
|
|
54385
55628
|
const dest = expandTilde(filename);
|
|
55629
|
+
const timeoutMs = options?.timeout ? Math.round(options.timeout * 1e3) : 3e4;
|
|
55630
|
+
const fetchOpts = buildFetchOptions(options);
|
|
54386
55631
|
const script = `
|
|
54387
|
-
|
|
54388
|
-
|
|
55632
|
+
const ac = new AbortController();
|
|
55633
|
+
const t = setTimeout(() => ac.abort(), ${timeoutMs});
|
|
55634
|
+
fetch(${JSON.stringify(url)}, { ...${JSON.stringify(fetchOpts)}, signal: ac.signal })
|
|
55635
|
+
.then(r => { clearTimeout(t); if (!r.ok) throw new Error('HTTP ' + r.status); return r.arrayBuffer(); })
|
|
54389
55636
|
.then(buf => require('fs').writeFileSync(${JSON.stringify(dest)}, Buffer.from(buf)))
|
|
54390
55637
|
.catch(e => { process.stderr.write(e.message + '\\n'); process.exit(1); });
|
|
54391
55638
|
`;
|
|
54392
55639
|
try {
|
|
54393
55640
|
execFileSync(process.execPath, ["-e", script], {
|
|
54394
55641
|
stdio: ["ignore", "ignore", "pipe"],
|
|
54395
|
-
timeout:
|
|
55642
|
+
timeout: timeoutMs + 5e3
|
|
54396
55643
|
});
|
|
54397
55644
|
} catch (e) {
|
|
54398
55645
|
const msg = e instanceof Error && "stderr" in e ? e.stderr.toString().trim() : String(e);
|
|
54399
55646
|
throw new Error(`websave: failed to download ${url}: ${msg}`);
|
|
54400
55647
|
}
|
|
54401
55648
|
}
|
|
54402
|
-
webread(url) {
|
|
55649
|
+
webread(url, options) {
|
|
55650
|
+
const timeoutMs = options?.timeout ? Math.round(options.timeout * 1e3) : 3e4;
|
|
55651
|
+
const fetchOpts = buildFetchOptions(options);
|
|
54403
55652
|
const script = `
|
|
54404
|
-
|
|
54405
|
-
|
|
55653
|
+
const ac = new AbortController();
|
|
55654
|
+
const t = setTimeout(() => ac.abort(), ${timeoutMs});
|
|
55655
|
+
fetch(${JSON.stringify(url)}, { ...${JSON.stringify(fetchOpts)}, signal: ac.signal })
|
|
55656
|
+
.then(r => { clearTimeout(t); if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); })
|
|
54406
55657
|
.then(t => process.stdout.write(t))
|
|
54407
55658
|
.catch(e => { process.stderr.write(e.message + '\\n'); process.exit(1); });
|
|
54408
55659
|
`;
|
|
54409
55660
|
try {
|
|
54410
55661
|
const result = execFileSync(process.execPath, ["-e", script], {
|
|
54411
55662
|
stdio: ["ignore", "pipe", "pipe"],
|
|
54412
|
-
timeout:
|
|
55663
|
+
timeout: timeoutMs + 5e3,
|
|
54413
55664
|
maxBuffer: 50 * 1024 * 1024
|
|
54414
55665
|
});
|
|
54415
55666
|
return result.toString();
|
|
@@ -54431,6 +55682,59 @@ var NodeFileIOAdapter = class {
|
|
|
54431
55682
|
return false;
|
|
54432
55683
|
}
|
|
54433
55684
|
}
|
|
55685
|
+
movefile(source, destination, force) {
|
|
55686
|
+
try {
|
|
55687
|
+
const src = expandTilde(source);
|
|
55688
|
+
const srcStat = statSync2(src);
|
|
55689
|
+
let dst = expandTilde(destination);
|
|
55690
|
+
let dstType = null;
|
|
55691
|
+
try {
|
|
55692
|
+
const s = statSync2(dst);
|
|
55693
|
+
dstType = s.isDirectory() ? "dir" : "file";
|
|
55694
|
+
} catch {
|
|
55695
|
+
dstType = null;
|
|
55696
|
+
}
|
|
55697
|
+
if (dstType === "dir") {
|
|
55698
|
+
dst = join3(dst, basename(src));
|
|
55699
|
+
try {
|
|
55700
|
+
dstType = statSync2(dst).isDirectory() ? "dir" : "file";
|
|
55701
|
+
} catch {
|
|
55702
|
+
dstType = null;
|
|
55703
|
+
}
|
|
55704
|
+
}
|
|
55705
|
+
if (dstType === "file" && force) {
|
|
55706
|
+
try {
|
|
55707
|
+
chmodSync(dst, 438);
|
|
55708
|
+
} catch {
|
|
55709
|
+
}
|
|
55710
|
+
}
|
|
55711
|
+
if (srcStat.isDirectory() && dstType === "file") {
|
|
55712
|
+
return false;
|
|
55713
|
+
}
|
|
55714
|
+
const parent = dirname(dst);
|
|
55715
|
+
if (parent && parent !== "." && parent !== "/") {
|
|
55716
|
+
try {
|
|
55717
|
+
mkdirSync(parent, { recursive: true });
|
|
55718
|
+
} catch {
|
|
55719
|
+
}
|
|
55720
|
+
}
|
|
55721
|
+
try {
|
|
55722
|
+
renameSync(src, dst);
|
|
55723
|
+
return true;
|
|
55724
|
+
} catch {
|
|
55725
|
+
if (srcStat.isDirectory()) {
|
|
55726
|
+
copyDirRecursive(src, dst);
|
|
55727
|
+
rmSync(src, { recursive: true });
|
|
55728
|
+
} else {
|
|
55729
|
+
writeFileSync(dst, readFileSync3(src));
|
|
55730
|
+
unlinkSync(src);
|
|
55731
|
+
}
|
|
55732
|
+
return true;
|
|
55733
|
+
}
|
|
55734
|
+
} catch {
|
|
55735
|
+
return false;
|
|
55736
|
+
}
|
|
55737
|
+
}
|
|
54434
55738
|
deleteFile(pattern) {
|
|
54435
55739
|
const p2 = expandTilde(pattern);
|
|
54436
55740
|
if (p2.includes("*") || p2.includes("?")) {
|
|
@@ -54466,56 +55770,18 @@ var NodeFileIOAdapter = class {
|
|
|
54466
55770
|
const dest = resolve(expandTilde(outputfolder));
|
|
54467
55771
|
mkdirSync(dest, { recursive: true });
|
|
54468
55772
|
const buf = readFileSync3(src);
|
|
54469
|
-
|
|
54470
|
-
|
|
54471
|
-
|
|
54472
|
-
eocdOffset = i;
|
|
54473
|
-
break;
|
|
54474
|
-
}
|
|
54475
|
-
}
|
|
54476
|
-
if (eocdOffset === -1) throw new Error("unzip: invalid ZIP file");
|
|
54477
|
-
const cdOffset = buf.readUInt32LE(eocdOffset + 16);
|
|
54478
|
-
const cdEntries = buf.readUInt16LE(eocdOffset + 10);
|
|
55773
|
+
const files = unzipSync(
|
|
55774
|
+
new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength)
|
|
55775
|
+
);
|
|
54479
55776
|
const extracted = [];
|
|
54480
|
-
|
|
54481
|
-
for (let i = 0; i < cdEntries; i++) {
|
|
54482
|
-
if (buf.readUInt32LE(pos) !== 33639248)
|
|
54483
|
-
throw new Error("unzip: corrupt central directory");
|
|
54484
|
-
const method = buf.readUInt16LE(pos + 10);
|
|
54485
|
-
const nameLen = buf.readUInt16LE(pos + 28);
|
|
54486
|
-
const extraLen = buf.readUInt16LE(pos + 30);
|
|
54487
|
-
const commentLen = buf.readUInt16LE(pos + 32);
|
|
54488
|
-
const localHeaderOffset = buf.readUInt32LE(pos + 42);
|
|
54489
|
-
const entryName = buf.toString("utf-8", pos + 46, pos + 46 + nameLen);
|
|
54490
|
-
pos += 46 + nameLen + extraLen + commentLen;
|
|
55777
|
+
for (const [entryName, data] of Object.entries(files)) {
|
|
54491
55778
|
if (entryName.endsWith("/")) {
|
|
54492
55779
|
mkdirSync(join3(dest, entryName), { recursive: true });
|
|
54493
55780
|
continue;
|
|
54494
55781
|
}
|
|
54495
|
-
const localPos = localHeaderOffset;
|
|
54496
|
-
if (buf.readUInt32LE(localPos) !== 67324752)
|
|
54497
|
-
throw new Error("unzip: corrupt local header");
|
|
54498
|
-
const localNameLen = buf.readUInt16LE(localPos + 26);
|
|
54499
|
-
const localExtraLen = buf.readUInt16LE(localPos + 28);
|
|
54500
|
-
const compressedSize = buf.readUInt32LE(localPos + 18);
|
|
54501
|
-
const dataStart = localPos + 30 + localNameLen + localExtraLen;
|
|
54502
|
-
const compressedData = buf.subarray(
|
|
54503
|
-
dataStart,
|
|
54504
|
-
dataStart + compressedSize
|
|
54505
|
-
);
|
|
54506
|
-
let fileData;
|
|
54507
|
-
if (method === 0) {
|
|
54508
|
-
fileData = Buffer.from(compressedData);
|
|
54509
|
-
} else if (method === 8) {
|
|
54510
|
-
fileData = inflateRawSync(compressedData);
|
|
54511
|
-
} else {
|
|
54512
|
-
throw new Error(
|
|
54513
|
-
`unzip: unsupported compression method ${method} for ${entryName}`
|
|
54514
|
-
);
|
|
54515
|
-
}
|
|
54516
55782
|
const outPath = join3(dest, entryName);
|
|
54517
55783
|
mkdirSync(dirname(outPath), { recursive: true });
|
|
54518
|
-
writeFileSync(outPath,
|
|
55784
|
+
writeFileSync(outPath, data);
|
|
54519
55785
|
extracted.push(outPath);
|
|
54520
55786
|
}
|
|
54521
55787
|
return extracted;
|
|
@@ -54796,6 +56062,7 @@ function saveHistoryEntry(entry, hist) {
|
|
|
54796
56062
|
async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nativeBridge2, optimization) {
|
|
54797
56063
|
let variableValues = {};
|
|
54798
56064
|
let holdState = false;
|
|
56065
|
+
let implicitCwdPath;
|
|
54799
56066
|
const workspaceFiles = [...initialWorkspaceFiles];
|
|
54800
56067
|
const searchPaths = [...initialSearchPaths ?? []];
|
|
54801
56068
|
const fileIO = new NodeFileIOAdapter();
|
|
@@ -54848,7 +56115,8 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nat
|
|
|
54848
56115
|
initialHoldState: holdState,
|
|
54849
56116
|
optimization,
|
|
54850
56117
|
fileIO,
|
|
54851
|
-
system
|
|
56118
|
+
system,
|
|
56119
|
+
implicitCwdPath
|
|
54852
56120
|
},
|
|
54853
56121
|
workspaceFiles,
|
|
54854
56122
|
"repl",
|
|
@@ -54863,6 +56131,9 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nat
|
|
|
54863
56131
|
workspaceFiles.length = 0;
|
|
54864
56132
|
workspaceFiles.push(...result.workspaceFiles ?? []);
|
|
54865
56133
|
}
|
|
56134
|
+
if (result.implicitCwdPath !== void 0) {
|
|
56135
|
+
implicitCwdPath = result.implicitCwdPath;
|
|
56136
|
+
}
|
|
54866
56137
|
if (result.plotInstructions.length > 0 && onDrawnow) {
|
|
54867
56138
|
onDrawnow(result.plotInstructions);
|
|
54868
56139
|
}
|
|
@@ -54961,7 +56232,8 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nat
|
|
|
54961
56232
|
initialHoldState: holdState,
|
|
54962
56233
|
optimization,
|
|
54963
56234
|
fileIO,
|
|
54964
|
-
system
|
|
56235
|
+
system,
|
|
56236
|
+
implicitCwdPath
|
|
54965
56237
|
},
|
|
54966
56238
|
workspaceFiles,
|
|
54967
56239
|
"repl",
|
|
@@ -54976,6 +56248,9 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nat
|
|
|
54976
56248
|
workspaceFiles.length = 0;
|
|
54977
56249
|
workspaceFiles.push(...result.workspaceFiles ?? []);
|
|
54978
56250
|
}
|
|
56251
|
+
if (result.implicitCwdPath !== void 0) {
|
|
56252
|
+
implicitCwdPath = result.implicitCwdPath;
|
|
56253
|
+
}
|
|
54979
56254
|
if (result.plotInstructions.length > 0 && onDrawnow) {
|
|
54980
56255
|
onDrawnow(result.plotInstructions);
|
|
54981
56256
|
}
|
|
@@ -55241,65 +56516,15 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nat
|
|
|
55241
56516
|
}
|
|
55242
56517
|
|
|
55243
56518
|
// src/vfs/unzipToFiles.ts
|
|
55244
|
-
import {
|
|
55245
|
-
var TEXT_DECODER = new TextDecoder("utf-8");
|
|
56519
|
+
import { unzipSync as unzipSync2 } from "fflate";
|
|
55246
56520
|
function unzipToFiles(zipData) {
|
|
55247
|
-
|
|
55248
|
-
|
|
55249
|
-
|
|
55250
|
-
|
|
55251
|
-
|
|
55252
|
-
}
|
|
55253
|
-
}
|
|
55254
|
-
if (eocdOffset === -1) throw new Error("Invalid ZIP file");
|
|
55255
|
-
const view = new DataView(
|
|
55256
|
-
zipData.buffer,
|
|
55257
|
-
zipData.byteOffset,
|
|
55258
|
-
zipData.byteLength
|
|
55259
|
-
);
|
|
55260
|
-
const cdOffset = view.getUint32(eocdOffset + 16, true);
|
|
55261
|
-
const cdEntries = view.getUint16(eocdOffset + 10, true);
|
|
55262
|
-
const files = [];
|
|
55263
|
-
let pos = cdOffset;
|
|
55264
|
-
for (let i = 0; i < cdEntries; i++) {
|
|
55265
|
-
if (view.getUint32(pos, true) !== 33639248) {
|
|
55266
|
-
throw new Error("Corrupt ZIP central directory");
|
|
55267
|
-
}
|
|
55268
|
-
const method = view.getUint16(pos + 10, true);
|
|
55269
|
-
const nameLen = view.getUint16(pos + 28, true);
|
|
55270
|
-
const extraLen = view.getUint16(pos + 30, true);
|
|
55271
|
-
const commentLen = view.getUint16(pos + 32, true);
|
|
55272
|
-
const localHeaderOffset = view.getUint32(pos + 42, true);
|
|
55273
|
-
const entryName = TEXT_DECODER.decode(
|
|
55274
|
-
zipData.subarray(pos + 46, pos + 46 + nameLen)
|
|
55275
|
-
);
|
|
55276
|
-
pos += 46 + nameLen + extraLen + commentLen;
|
|
55277
|
-
if (entryName.endsWith("/")) continue;
|
|
55278
|
-
const localPos = localHeaderOffset;
|
|
55279
|
-
if (view.getUint32(localPos, true) !== 67324752) {
|
|
55280
|
-
throw new Error("Corrupt ZIP local header");
|
|
55281
|
-
}
|
|
55282
|
-
const localNameLen = view.getUint16(localPos + 26, true);
|
|
55283
|
-
const localExtraLen = view.getUint16(localPos + 28, true);
|
|
55284
|
-
const compressedSize = view.getUint32(localPos + 18, true);
|
|
55285
|
-
const dataStart = localPos + 30 + localNameLen + localExtraLen;
|
|
55286
|
-
const compressedData = zipData.subarray(
|
|
55287
|
-
dataStart,
|
|
55288
|
-
dataStart + compressedSize
|
|
55289
|
-
);
|
|
55290
|
-
let content;
|
|
55291
|
-
if (method === 0) {
|
|
55292
|
-
content = new Uint8Array(compressedData);
|
|
55293
|
-
} else if (method === 8) {
|
|
55294
|
-
content = inflateSync(compressedData);
|
|
55295
|
-
} else {
|
|
55296
|
-
throw new Error(
|
|
55297
|
-
`Unsupported ZIP compression method ${method} for ${entryName}`
|
|
55298
|
-
);
|
|
55299
|
-
}
|
|
55300
|
-
files.push({ path: entryName, content });
|
|
56521
|
+
const files = unzipSync2(zipData);
|
|
56522
|
+
const out = [];
|
|
56523
|
+
for (const [path, content] of Object.entries(files)) {
|
|
56524
|
+
if (path.endsWith("/")) continue;
|
|
56525
|
+
out.push({ path, content });
|
|
55301
56526
|
}
|
|
55302
|
-
return
|
|
56527
|
+
return out;
|
|
55303
56528
|
}
|
|
55304
56529
|
|
|
55305
56530
|
// src/cli.ts
|
|
@@ -55527,7 +56752,6 @@ Options (for run and eval):
|
|
|
55527
56752
|
--path <dir> Add extra workspace directory
|
|
55528
56753
|
--plot Enable plot server
|
|
55529
56754
|
--plot-port <port> Set plot server port (implies --plot)
|
|
55530
|
-
--add-script-path Add the script's directory to the workspace (run only)
|
|
55531
56755
|
--opt <level> Optimization level (0=none, 1=JIT scalar functions; default: 1)
|
|
55532
56756
|
|
|
55533
56757
|
Environment variables:
|
|
@@ -55541,7 +56765,6 @@ function parseOptions(args) {
|
|
|
55541
56765
|
stream: false,
|
|
55542
56766
|
plot: false,
|
|
55543
56767
|
plotPort: void 0,
|
|
55544
|
-
addScriptPath: false,
|
|
55545
56768
|
extraPaths: [],
|
|
55546
56769
|
positional: [],
|
|
55547
56770
|
profileOutput: void 0,
|
|
@@ -55581,9 +56804,6 @@ function parseOptions(args) {
|
|
|
55581
56804
|
case "--plot":
|
|
55582
56805
|
opts.plot = true;
|
|
55583
56806
|
break;
|
|
55584
|
-
case "--add-script-path":
|
|
55585
|
-
opts.addScriptPath = true;
|
|
55586
|
-
break;
|
|
55587
56807
|
case "--plot-port":
|
|
55588
56808
|
i++;
|
|
55589
56809
|
if (i >= args.length) {
|
|
@@ -55649,13 +56869,9 @@ async function cmdRun(args) {
|
|
|
55649
56869
|
const filepath = resolve2(process.cwd(), opts.positional[0]);
|
|
55650
56870
|
const code = readFileSync5(filepath, "utf-8");
|
|
55651
56871
|
const mainFileName = filepath;
|
|
56872
|
+
process.chdir(dirname2(filepath));
|
|
55652
56873
|
const searchPaths = [];
|
|
55653
|
-
|
|
55654
|
-
if (opts.addScriptPath) {
|
|
55655
|
-
const scriptDir = dirname2(filepath);
|
|
55656
|
-
searchPaths.push(scriptDir);
|
|
55657
|
-
workspaceFiles = scanMFiles(scriptDir, filepath);
|
|
55658
|
-
}
|
|
56874
|
+
const workspaceFiles = [];
|
|
55659
56875
|
for (const p2 of opts.extraPaths) {
|
|
55660
56876
|
searchPaths.push(p2);
|
|
55661
56877
|
workspaceFiles.push(...scanMFiles(p2));
|