numbl 0.4.9 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-browser/browser/protocol.d.ts +10 -0
- package/dist-browser/browser/session.d.ts +6 -1
- package/dist-browser/browser.js +22 -2
- package/dist-browser/numbl-core/interpreter/interpreter.d.ts +2 -0
- package/dist-browser/numbl-core/interpreter/interpreterFunctions.d.ts +8 -0
- package/dist-browser/numbl-core/lowering/classInfo.d.ts +6 -0
- package/dist-browser/numbl-core/parser/ClassParser.d.ts +5 -0
- package/dist-browser/numbl-core/parser/types.d.ts +7 -1
- package/dist-browser/numbl-core/runtime/runtimeEnum.d.ts +33 -0
- package/dist-browser/numbl-core/runtime/types.d.ts +5 -1
- package/dist-browser/numbl-core/version.d.ts +1 -1
- package/dist-cli/cli.js +295 -10
- package/dist-lib/lib.js +294 -9
- package/dist-lib/numbl-core/interpreter/interpreter.d.ts +2 -0
- package/dist-lib/numbl-core/interpreter/interpreterFunctions.d.ts +8 -0
- package/dist-lib/numbl-core/lowering/classInfo.d.ts +6 -0
- package/dist-lib/numbl-core/parser/ClassParser.d.ts +5 -0
- package/dist-lib/numbl-core/parser/types.d.ts +7 -1
- package/dist-lib/numbl-core/runtime/runtimeEnum.d.ts +33 -0
- package/dist-lib/numbl-core/runtime/types.d.ts +5 -1
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-site-viewer/assets/{index-CT9HA1Pn.js → index-fhKbvuOM.js} +286 -286
- package/dist-site-viewer/assets/{numbl-worker-CYPflGmm.js → numbl-worker-BFP9xj5e.js} +98 -98
- package/dist-site-viewer/index.html +1 -1
- package/package.json +1 -1
|
@@ -180,6 +180,8 @@ export declare class Interpreter {
|
|
|
180
180
|
}>, args: unknown[], nargout: number) => unknown;
|
|
181
181
|
instantiateClass: (className: string, args: unknown[], nargout: number) => unknown;
|
|
182
182
|
interpretConstructor: (classInfo: ClassInfo, args: unknown[], nargout: number) => unknown;
|
|
183
|
+
interpretEnumMember: (className: string, memberName: string) => RuntimeValue | null;
|
|
184
|
+
convertToEnum: (className: string, classInfo: ClassInfo, args: unknown[]) => RuntimeValue;
|
|
183
185
|
callUserFunction: (fn: FunctionDef, args: unknown[], nargout: number, narginOverride?: number) => unknown;
|
|
184
186
|
callNestedFunction: (fn: FunctionDef, parentEnv: Environment, args: unknown[], nargout: number) => unknown;
|
|
185
187
|
withFileContext: <T>(file: string, className: string | undefined, methodName: string | undefined, fn: () => T) => T;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Augments the Interpreter class via prototype assignment.
|
|
4
4
|
*/
|
|
5
5
|
import type { Expr } from "../parser/types.js";
|
|
6
|
+
import type { RuntimeValue } from "../runtime/types.js";
|
|
6
7
|
import { type ResolvedTarget } from "../functionResolve.js";
|
|
7
8
|
import type { ClassInfo } from "../lowering/classInfo.js";
|
|
8
9
|
import { Environment, type FunctionDef } from "./types.js";
|
|
@@ -30,6 +31,13 @@ export declare function interpretClassMethod(this: Interpreter, target: Extract<
|
|
|
30
31
|
export declare function interpretPrivateFunction(this: Interpreter, target: Extract<ResolvedTarget, {
|
|
31
32
|
kind: "privateFunction";
|
|
32
33
|
}>, args: unknown[], nargout: number): unknown;
|
|
34
|
+
/** Resolve `ClassName.MemberName` to an enumeration-member instance. Returns
|
|
35
|
+
* null when `className` is not an enumeration or has no such member. */
|
|
36
|
+
export declare function interpretEnumMember(this: Interpreter, className: string, memberName: string): RuntimeValue | null;
|
|
37
|
+
/** Enumeration constructor-as-converter: `ClassName(x)` for an enumeration
|
|
38
|
+
* with no explicit constructor. Converts x — a member, a numeric value, a
|
|
39
|
+
* char/string member name, or an array thereof — to member(s). */
|
|
40
|
+
export declare function convertToEnum(this: Interpreter, className: string, classInfo: ClassInfo, args: unknown[]): RuntimeValue;
|
|
33
41
|
export declare function instantiateClass(this: Interpreter, className: string, args: unknown[], nargout: number): unknown;
|
|
34
42
|
export declare function interpretConstructor(this: Interpreter, classInfo: ClassInfo, args: unknown[], nargout: number): unknown;
|
|
35
43
|
export declare function callUserFunction(this: Interpreter, fn: FunctionDef, args: unknown[], nargout: number, narginOverride?: number): unknown;
|
|
@@ -18,6 +18,12 @@ export interface ClassInfo {
|
|
|
18
18
|
methodNames: Set<string>;
|
|
19
19
|
staticMethodNames: Set<string>;
|
|
20
20
|
constructorName: string | null;
|
|
21
|
+
/** Enumeration members in declaration order (name + constructor-arg
|
|
22
|
+
* exprs), or null when the class is not an enumeration. */
|
|
23
|
+
enumMembers: {
|
|
24
|
+
name: string;
|
|
25
|
+
args: Expr[];
|
|
26
|
+
}[] | null;
|
|
21
27
|
ast: (Stmt & {
|
|
22
28
|
type: "ClassDef";
|
|
23
29
|
}) | null;
|
|
@@ -7,6 +7,11 @@ export declare class ClassParser extends FunctionParser {
|
|
|
7
7
|
parseImport(): Stmt;
|
|
8
8
|
parseClassDef(): Stmt;
|
|
9
9
|
private parseNameBlock;
|
|
10
|
+
/** Parse an `enumeration ... end` member list. Each member is a bare
|
|
11
|
+
* identifier optionally followed by a parenthesized argument list
|
|
12
|
+
* (`quad (0)`, `Error (1, 0, 0)`). Members are separated by `;`/`,`/
|
|
13
|
+
* newline. The args are evaluated later (at member construction). */
|
|
14
|
+
private parseEnumerationBlock;
|
|
10
15
|
private parsePropertiesNamesBlock;
|
|
11
16
|
/** Consume a balanced `open ... close` run (handling nesting). Assumes the
|
|
12
17
|
* next token is `open`; no-op otherwise. */
|
|
@@ -194,7 +194,13 @@ export type ClassMember = {
|
|
|
194
194
|
} | {
|
|
195
195
|
type: "Enumeration";
|
|
196
196
|
attributes: Attr[];
|
|
197
|
-
|
|
197
|
+
/** Enumeration members in declaration order. Each has a name and an
|
|
198
|
+
* optional argument list (`quad (0)` → args `[0]`). Args are passed
|
|
199
|
+
* to the constructor / first superclass to build the member value. */
|
|
200
|
+
members: {
|
|
201
|
+
name: string;
|
|
202
|
+
args: Expr[];
|
|
203
|
+
}[];
|
|
198
204
|
} | {
|
|
199
205
|
type: "Arguments";
|
|
200
206
|
attributes: Attr[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumeration-class value semantics.
|
|
3
|
+
*
|
|
4
|
+
* An enumeration member is represented as a `RuntimeClassInstance` whose
|
|
5
|
+
* `_enumMember` field holds the member name and whose `_builtinData` holds the
|
|
6
|
+
* underlying (superclass) numeric value — e.g. for `classdef patchtype < uint32`
|
|
7
|
+
* the member `tri (1)` is stored with `_enumMember = "tri"`, `_builtinData = 1`.
|
|
8
|
+
*
|
|
9
|
+
* MATLAB comparison rules (verified against R2025b):
|
|
10
|
+
* - enum == enum → compare underlying values (inherited from the numeric
|
|
11
|
+
* superclass); falls back to name equality for plain
|
|
12
|
+
* enumerations that carry no superclass value.
|
|
13
|
+
* - enum == numeric → compare underlying value to the number.
|
|
14
|
+
* - enum == char/str → compare the member NAME to the text (a non-matching
|
|
15
|
+
* name yields false, never an error), NOT an
|
|
16
|
+
* element-wise char-code comparison.
|
|
17
|
+
* Comparisons are element-wise with scalar broadcasting; arrays of members
|
|
18
|
+
* produce a logical array the size of the member array.
|
|
19
|
+
*/
|
|
20
|
+
import { type RuntimeValue, type RuntimeClassInstance } from "./types.js";
|
|
21
|
+
/** True if `v` is a single enumeration-member instance. */
|
|
22
|
+
export declare function isEnumInstance(v: RuntimeValue): v is RuntimeClassInstance;
|
|
23
|
+
/** True if `v` is an enumeration member or an array of enumeration members. */
|
|
24
|
+
export declare function isEnumValue(v: RuntimeValue): boolean;
|
|
25
|
+
/** Compare one enumeration member `e` against a scalar operand `other`
|
|
26
|
+
* (another member, a number, or char/string text). */
|
|
27
|
+
export declare function enumScalarEquals(e: RuntimeClassInstance, other: RuntimeValue): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Element-wise `==` / `~=` for enumeration operands. Returns a logical result
|
|
30
|
+
* (a boolean for scalars, a logical tensor for arrays), or null if the op is
|
|
31
|
+
* not equality/inequality or neither operand is an enumeration value.
|
|
32
|
+
*/
|
|
33
|
+
export declare function enumEqualityOp(op: string, a: RuntimeValue, b: RuntimeValue): RuntimeValue | null;
|
|
@@ -123,7 +123,11 @@ export declare class RuntimeClassInstance extends Refcounted {
|
|
|
123
123
|
/** For classes that inherit from built-in types (e.g. classdef Foo < double),
|
|
124
124
|
* stores the underlying built-in data. */
|
|
125
125
|
_builtinData: RuntimeValue | undefined;
|
|
126
|
-
|
|
126
|
+
/** For enumeration-class members: the member name (e.g. "tri"). When set,
|
|
127
|
+
* this instance is an enumeration member and `_builtinData` holds its
|
|
128
|
+
* underlying (superclass) value. Drives ==/~=, switch, and char coercion. */
|
|
129
|
+
_enumMember: string | undefined;
|
|
130
|
+
constructor(className: string, fields: Map<string, RuntimeValue>, isHandleClass: boolean, _builtinData?: RuntimeValue, _enumMember?: string);
|
|
127
131
|
/** Set/replace a field value (handle-class in-place mutation), with
|
|
128
132
|
* proper decref-old / incref-new bookkeeping. Used for handle-class
|
|
129
133
|
* field assigns; value-class field assigns construct a new instance. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Numbl version, used for JIT disk cache invalidation. */
|
|
2
|
-
export declare const NUMBL_VERSION = "0.4.
|
|
2
|
+
export declare const NUMBL_VERSION = "0.4.11";
|
package/dist-cli/cli.js
CHANGED
|
@@ -848,12 +848,17 @@ var RuntimeClassInstance = class extends Refcounted {
|
|
|
848
848
|
/** For classes that inherit from built-in types (e.g. classdef Foo < double),
|
|
849
849
|
* stores the underlying built-in data. */
|
|
850
850
|
_builtinData;
|
|
851
|
-
|
|
851
|
+
/** For enumeration-class members: the member name (e.g. "tri"). When set,
|
|
852
|
+
* this instance is an enumeration member and `_builtinData` holds its
|
|
853
|
+
* underlying (superclass) value. Drives ==/~=, switch, and char coercion. */
|
|
854
|
+
_enumMember;
|
|
855
|
+
constructor(className, fields, isHandleClass2, _builtinData, _enumMember) {
|
|
852
856
|
super();
|
|
853
857
|
this.className = className;
|
|
854
858
|
this.fields = fields;
|
|
855
859
|
this.isHandleClass = isHandleClass2;
|
|
856
860
|
this._builtinData = _builtinData;
|
|
861
|
+
this._enumMember = _enumMember;
|
|
857
862
|
for (const v of fields.values()) incref(v);
|
|
858
863
|
if (_builtinData !== void 0) incref(_builtinData);
|
|
859
864
|
}
|
|
@@ -21670,6 +21675,10 @@ var valuesAreEqual = (a, b) => {
|
|
|
21670
21675
|
return a === b;
|
|
21671
21676
|
}
|
|
21672
21677
|
case "class_instance": {
|
|
21678
|
+
const bi = b;
|
|
21679
|
+
if (a._enumMember !== void 0 || bi._enumMember !== void 0) {
|
|
21680
|
+
return a._enumMember === bi._enumMember && a.className === bi.className;
|
|
21681
|
+
}
|
|
21673
21682
|
return a === b;
|
|
21674
21683
|
}
|
|
21675
21684
|
case "complex_number": {
|
|
@@ -22138,6 +22147,19 @@ function assignSlice(base, rowIndices, colIndices, rhs, curRows) {
|
|
|
22138
22147
|
if (isRuntimeTensor(rhs)) {
|
|
22139
22148
|
const nR = rowIndices.length;
|
|
22140
22149
|
const nC = colIndices.length;
|
|
22150
|
+
if (rhs.data.length === 1) {
|
|
22151
|
+
const re = rhs.data[0];
|
|
22152
|
+
const im = rhs.imag ? rhs.imag[0] : 0;
|
|
22153
|
+
if (im !== 0 || base.imag) ensureImag(base);
|
|
22154
|
+
for (const r of rowIndices) {
|
|
22155
|
+
for (const c of colIndices) {
|
|
22156
|
+
const li = colMajorIndex(r, c, curRows);
|
|
22157
|
+
base.data[li] = re;
|
|
22158
|
+
if (base.imag) base.imag[li] = im;
|
|
22159
|
+
}
|
|
22160
|
+
}
|
|
22161
|
+
return;
|
|
22162
|
+
}
|
|
22141
22163
|
const [rhsRows, rhsCols] = tensorSize2D(rhs);
|
|
22142
22164
|
const shapeMatches = rhsRows === nR && rhsCols === nC;
|
|
22143
22165
|
const sliceIsVector = nR === 1 || nC === 1;
|
|
@@ -29191,6 +29213,15 @@ function inferJitType(value) {
|
|
|
29191
29213
|
fields
|
|
29192
29214
|
};
|
|
29193
29215
|
}
|
|
29216
|
+
if (isRuntimeClassInstanceArray(value)) {
|
|
29217
|
+
const arr = value;
|
|
29218
|
+
return {
|
|
29219
|
+
kind: "class_instance",
|
|
29220
|
+
className: arr.className,
|
|
29221
|
+
isHandleClass: false,
|
|
29222
|
+
fields: {}
|
|
29223
|
+
};
|
|
29224
|
+
}
|
|
29194
29225
|
if (typeof value === "object" && value !== null && value.kind === "function") {
|
|
29195
29226
|
return { kind: "function_handle" };
|
|
29196
29227
|
}
|
|
@@ -32946,11 +32977,15 @@ var ClassParser = class extends FunctionParser {
|
|
|
32946
32977
|
} else if (tok === 20 /* Enumeration */) {
|
|
32947
32978
|
this.pos++;
|
|
32948
32979
|
const attrs = this.parseOptionalAttrList();
|
|
32949
|
-
const
|
|
32980
|
+
const enumMembers = this.parseEnumerationBlock();
|
|
32950
32981
|
if (!this.consume(15 /* End */)) {
|
|
32951
32982
|
throw this.error("expected 'end' after enumeration");
|
|
32952
32983
|
}
|
|
32953
|
-
members.push({
|
|
32984
|
+
members.push({
|
|
32985
|
+
type: "Enumeration",
|
|
32986
|
+
attributes: attrs,
|
|
32987
|
+
members: enumMembers
|
|
32988
|
+
});
|
|
32954
32989
|
} else if (tok === 21 /* Arguments */) {
|
|
32955
32990
|
this.pos++;
|
|
32956
32991
|
const attrs = this.parseOptionalAttrList();
|
|
@@ -32991,6 +33026,38 @@ var ClassParser = class extends FunctionParser {
|
|
|
32991
33026
|
}
|
|
32992
33027
|
return names;
|
|
32993
33028
|
}
|
|
33029
|
+
/** Parse an `enumeration ... end` member list. Each member is a bare
|
|
33030
|
+
* identifier optionally followed by a parenthesized argument list
|
|
33031
|
+
* (`quad (0)`, `Error (1, 0, 0)`). Members are separated by `;`/`,`/
|
|
33032
|
+
* newline. The args are evaluated later (at member construction). */
|
|
33033
|
+
parseEnumerationBlock() {
|
|
33034
|
+
const members = [];
|
|
33035
|
+
while (this.peekToken() !== void 0) {
|
|
33036
|
+
if (this.peekToken() === 15 /* End */) break;
|
|
33037
|
+
if (this.consume(49 /* Semicolon */) || this.consume(47 /* Comma */) || this.consume(68 /* Newline */)) {
|
|
33038
|
+
continue;
|
|
33039
|
+
}
|
|
33040
|
+
if (this.peekToken() !== 4 /* Ident */) break;
|
|
33041
|
+
const name = this.expectIdent();
|
|
33042
|
+
const args = [];
|
|
33043
|
+
if (this.consume(50 /* LParen */)) {
|
|
33044
|
+
if (this.peekToken() !== 51 /* RParen */) {
|
|
33045
|
+
args.push(this.parseExpr());
|
|
33046
|
+
while (this.consume(47 /* Comma */)) {
|
|
33047
|
+
args.push(this.parseExpr());
|
|
33048
|
+
}
|
|
33049
|
+
}
|
|
33050
|
+
if (!this.consume(51 /* RParen */)) {
|
|
33051
|
+
throw this.errorWithExpected(
|
|
33052
|
+
"expected ')' after enumeration member arguments",
|
|
33053
|
+
")"
|
|
33054
|
+
);
|
|
33055
|
+
}
|
|
33056
|
+
}
|
|
33057
|
+
members.push({ name, args });
|
|
33058
|
+
}
|
|
33059
|
+
return members;
|
|
33060
|
+
}
|
|
32994
33061
|
parsePropertiesNamesBlock() {
|
|
32995
33062
|
const props = [];
|
|
32996
33063
|
while (this.peekToken() !== void 0) {
|
|
@@ -33832,6 +33899,96 @@ function getConstant(name) {
|
|
|
33832
33899
|
var COLON_SENTINEL = /* @__PURE__ */ Symbol("COLON");
|
|
33833
33900
|
var END_SENTINEL = /* @__PURE__ */ Symbol("END");
|
|
33834
33901
|
|
|
33902
|
+
// src/numbl-core/runtime/runtimeEnum.ts
|
|
33903
|
+
function isEnumInstance(v) {
|
|
33904
|
+
return isRuntimeClassInstance(v) && v._enumMember !== void 0;
|
|
33905
|
+
}
|
|
33906
|
+
function isEnumValue(v) {
|
|
33907
|
+
if (isEnumInstance(v)) return true;
|
|
33908
|
+
if (isRuntimeClassInstanceArray(v))
|
|
33909
|
+
return v.elements.some((e) => e._enumMember !== void 0);
|
|
33910
|
+
return false;
|
|
33911
|
+
}
|
|
33912
|
+
function asText(v) {
|
|
33913
|
+
if (isRuntimeChar(v)) return v.value;
|
|
33914
|
+
if (isRuntimeString(v)) return v;
|
|
33915
|
+
return null;
|
|
33916
|
+
}
|
|
33917
|
+
function enumScalarEquals(e, other) {
|
|
33918
|
+
const text = asText(other);
|
|
33919
|
+
if (text !== null) return e._enumMember === text;
|
|
33920
|
+
if (isEnumInstance(other)) {
|
|
33921
|
+
if (e._builtinData !== void 0 && other._builtinData !== void 0) {
|
|
33922
|
+
return toNumber(e._builtinData) === toNumber(other._builtinData);
|
|
33923
|
+
}
|
|
33924
|
+
return e._enumMember === other._enumMember;
|
|
33925
|
+
}
|
|
33926
|
+
if (e._builtinData !== void 0) {
|
|
33927
|
+
if (isRuntimeNumber(other)) return toNumber(e._builtinData) === other;
|
|
33928
|
+
if (isRuntimeLogical(other))
|
|
33929
|
+
return toNumber(e._builtinData) === (other ? 1 : 0);
|
|
33930
|
+
}
|
|
33931
|
+
return false;
|
|
33932
|
+
}
|
|
33933
|
+
function decompose(v) {
|
|
33934
|
+
if (isEnumInstance(v)) return { elems: [v], shape: [1, 1] };
|
|
33935
|
+
if (isRuntimeClassInstanceArray(v))
|
|
33936
|
+
return { elems: [...v.elements], shape: v.shape };
|
|
33937
|
+
if (isRuntimeChar(v)) return { elems: [v], shape: [1, 1] };
|
|
33938
|
+
if (isRuntimeString(v)) return { elems: [v], shape: [1, 1] };
|
|
33939
|
+
if (isRuntimeStringArray(v))
|
|
33940
|
+
return { elems: v.data.map((s) => s), shape: v.shape };
|
|
33941
|
+
if (isRuntimeNumber(v) || isRuntimeLogical(v))
|
|
33942
|
+
return { elems: [v], shape: [1, 1] };
|
|
33943
|
+
if (isRuntimeTensor(v)) {
|
|
33944
|
+
const shape = [v.shape[0] ?? 0, v.shape[1] ?? 1];
|
|
33945
|
+
return { elems: Array.from(v.data, (x) => x), shape };
|
|
33946
|
+
}
|
|
33947
|
+
return null;
|
|
33948
|
+
}
|
|
33949
|
+
function elementEquals(x, y) {
|
|
33950
|
+
if (isEnumInstance(x)) return enumScalarEquals(x, y);
|
|
33951
|
+
if (isEnumInstance(y)) return enumScalarEquals(y, x);
|
|
33952
|
+
return false;
|
|
33953
|
+
}
|
|
33954
|
+
function enumEqualityOp(op, a, b) {
|
|
33955
|
+
if (op !== "Equal" /* Equal */ && op !== "NotEqual" /* NotEqual */)
|
|
33956
|
+
return null;
|
|
33957
|
+
if (!isEnumValue(a) && !isEnumValue(b)) return null;
|
|
33958
|
+
const oa = decompose(a);
|
|
33959
|
+
const ob = decompose(b);
|
|
33960
|
+
if (!oa || !ob) return null;
|
|
33961
|
+
const na = oa.elems.length;
|
|
33962
|
+
const nb = ob.elems.length;
|
|
33963
|
+
let n;
|
|
33964
|
+
let shape;
|
|
33965
|
+
if (na === nb) {
|
|
33966
|
+
n = na;
|
|
33967
|
+
shape = oa.shape;
|
|
33968
|
+
} else if (na === 1) {
|
|
33969
|
+
n = nb;
|
|
33970
|
+
shape = ob.shape;
|
|
33971
|
+
} else if (nb === 1) {
|
|
33972
|
+
n = na;
|
|
33973
|
+
shape = oa.shape;
|
|
33974
|
+
} else {
|
|
33975
|
+
throw new RuntimeError("Array dimensions must match for comparison");
|
|
33976
|
+
}
|
|
33977
|
+
const negate = op === "NotEqual" /* NotEqual */;
|
|
33978
|
+
const out = new Float64Array(n);
|
|
33979
|
+
for (let i = 0; i < n; i++) {
|
|
33980
|
+
const eq2 = elementEquals(
|
|
33981
|
+
oa.elems[na === 1 ? 0 : i],
|
|
33982
|
+
ob.elems[nb === 1 ? 0 : i]
|
|
33983
|
+
);
|
|
33984
|
+
out[i] = (negate ? !eq2 : eq2) ? 1 : 0;
|
|
33985
|
+
}
|
|
33986
|
+
if (n === 1) return RTV.logical(out[0] === 1);
|
|
33987
|
+
const t = RTV.tensor(out, [shape[0], shape[1]]);
|
|
33988
|
+
t._isLogical = true;
|
|
33989
|
+
return t;
|
|
33990
|
+
}
|
|
33991
|
+
|
|
33835
33992
|
// src/numbl-core/runtime/runtimeHelpers.ts
|
|
33836
33993
|
function isDeferredRange(v) {
|
|
33837
33994
|
return typeof v === "object" && v !== null && v["_deferredRange"] === true;
|
|
@@ -33856,6 +34013,8 @@ function ensureRuntimeValue(v) {
|
|
|
33856
34013
|
return v;
|
|
33857
34014
|
}
|
|
33858
34015
|
function switchValuesMatch(a, b) {
|
|
34016
|
+
if (isEnumInstance(a)) return enumScalarEquals(a, b);
|
|
34017
|
+
if (isEnumInstance(b)) return enumScalarEquals(b, a);
|
|
33859
34018
|
if ((isRuntimeChar(a) || isRuntimeString(a)) && (isRuntimeChar(b) || isRuntimeString(b))) {
|
|
33860
34019
|
return (typeof a === "string" ? a : a.value) === (typeof b === "string" ? b : b.value);
|
|
33861
34020
|
}
|
|
@@ -37293,7 +37452,16 @@ function indexStore(rt, base, indices, rhs, skipSubsasgn = false) {
|
|
|
37293
37452
|
}
|
|
37294
37453
|
existing[k] = rhsInst;
|
|
37295
37454
|
if (existing.length === 1) return existing[0];
|
|
37296
|
-
|
|
37455
|
+
const origShape = isRuntimeClassInstanceArray(mv) ? mv.shape : null;
|
|
37456
|
+
let shape;
|
|
37457
|
+
if (origShape && existing.length === origShape[0] * origShape[1]) {
|
|
37458
|
+
shape = origShape;
|
|
37459
|
+
} else if (origShape && origShape[1] === 1) {
|
|
37460
|
+
shape = [existing.length, 1];
|
|
37461
|
+
} else {
|
|
37462
|
+
shape = [1, existing.length];
|
|
37463
|
+
}
|
|
37464
|
+
return RTV.classInstanceArray(className, existing, shape);
|
|
37297
37465
|
}
|
|
37298
37466
|
}
|
|
37299
37467
|
if (isRuntimeClassInstance(mv)) {
|
|
@@ -46532,6 +46700,8 @@ function sparseToDense2(S) {
|
|
|
46532
46700
|
return RTV.tensor(data, [S.m, S.n], imag2);
|
|
46533
46701
|
}
|
|
46534
46702
|
function valuesEqualSimple(a, b) {
|
|
46703
|
+
if (isEnumInstance(a)) return enumScalarEquals(a, b);
|
|
46704
|
+
if (isEnumInstance(b)) return enumScalarEquals(b, a);
|
|
46535
46705
|
{
|
|
46536
46706
|
const aText = textValue(a);
|
|
46537
46707
|
const bText = textValue(b);
|
|
@@ -54720,7 +54890,8 @@ function copyClassInstance(inst) {
|
|
|
54720
54890
|
inst.className,
|
|
54721
54891
|
new Map(inst.fields),
|
|
54722
54892
|
inst.isHandleClass,
|
|
54723
|
-
inst._builtinData
|
|
54893
|
+
inst._builtinData,
|
|
54894
|
+
inst._enumMember
|
|
54724
54895
|
);
|
|
54725
54896
|
}
|
|
54726
54897
|
function repelemObjects(v, repArgs) {
|
|
@@ -57808,6 +57979,15 @@ defineBuiltin({
|
|
|
57808
57979
|
});
|
|
57809
57980
|
|
|
57810
57981
|
// src/numbl-core/interpreter/builtins/type-constructors.ts
|
|
57982
|
+
function classInstanceArrayNumeric(v) {
|
|
57983
|
+
if (!isRuntimeClassInstanceArray(v)) return null;
|
|
57984
|
+
const data = allocFloat64Array(v.elements.length);
|
|
57985
|
+
for (let i = 0; i < v.elements.length; i++) {
|
|
57986
|
+
const bd = v.elements[i]._builtinData;
|
|
57987
|
+
data[i] = bd !== void 0 ? toNumber(bd) : NaN;
|
|
57988
|
+
}
|
|
57989
|
+
return RTV.tensor(data, [v.shape[0], v.shape[1]]);
|
|
57990
|
+
}
|
|
57811
57991
|
function parseDoubleText(s) {
|
|
57812
57992
|
const t = s.trim();
|
|
57813
57993
|
if (t === "") return NaN;
|
|
@@ -57862,6 +58042,8 @@ defineBuiltin({
|
|
|
57862
58042
|
if (isRuntimeClassInstance(v) && v._builtinData !== void 0) {
|
|
57863
58043
|
return v._builtinData;
|
|
57864
58044
|
}
|
|
58045
|
+
const arr = classInstanceArrayNumeric(v);
|
|
58046
|
+
if (arr) return arr;
|
|
57865
58047
|
return RTV.num(toNumber(v));
|
|
57866
58048
|
}
|
|
57867
58049
|
}
|
|
@@ -57889,6 +58071,8 @@ function singleApply(v) {
|
|
|
57889
58071
|
}
|
|
57890
58072
|
if (isRuntimeClassInstance(v) && v._builtinData !== void 0)
|
|
57891
58073
|
return singleApply(v._builtinData);
|
|
58074
|
+
const arr = classInstanceArrayNumeric(v);
|
|
58075
|
+
if (arr) return singleApply(arr);
|
|
57892
58076
|
return RTV.num(Math.fround(toNumber(v)));
|
|
57893
58077
|
}
|
|
57894
58078
|
defineBuiltin({
|
|
@@ -57948,7 +58132,7 @@ for (const { name, min: min2, max: max2 } of INT_RANGES) {
|
|
|
57948
58132
|
match: (argTypes) => {
|
|
57949
58133
|
if (argTypes.length !== 1) return null;
|
|
57950
58134
|
const a = argTypes[0];
|
|
57951
|
-
if (a.kind === "number" || a.kind === "boolean" || a.kind === "char" || a.kind === "complex_or_number")
|
|
58135
|
+
if (a.kind === "number" || a.kind === "boolean" || a.kind === "char" || a.kind === "complex_or_number" || a.kind === "class_instance")
|
|
57952
58136
|
return [{ kind: "number" }];
|
|
57953
58137
|
if (a.kind === "tensor")
|
|
57954
58138
|
return [
|
|
@@ -57962,7 +58146,7 @@ for (const { name, min: min2, max: max2 } of INT_RANGES) {
|
|
|
57962
58146
|
return null;
|
|
57963
58147
|
},
|
|
57964
58148
|
apply: (args) => {
|
|
57965
|
-
const v = args[0];
|
|
58149
|
+
const v = isRuntimeClassInstance(args[0]) && args[0]._builtinData !== void 0 ? args[0]._builtinData : classInstanceArrayNumeric(args[0]) ?? args[0];
|
|
57966
58150
|
if (isRuntimeNumber(v))
|
|
57967
58151
|
return RTV.num(saturateRoundToward(v, min2, max2));
|
|
57968
58152
|
if (isRuntimeLogical(v)) return RTV.num(v ? 1 : 0);
|
|
@@ -58217,7 +58401,7 @@ defineBuiltin({
|
|
|
58217
58401
|
match: (argTypes) => {
|
|
58218
58402
|
if (argTypes.length !== 1) return null;
|
|
58219
58403
|
const a = argTypes[0];
|
|
58220
|
-
if (a.kind === "number" || a.kind === "boolean")
|
|
58404
|
+
if (a.kind === "number" || a.kind === "boolean" || a.kind === "class_instance")
|
|
58221
58405
|
return [{ kind: "boolean" }];
|
|
58222
58406
|
if (a.kind === "tensor")
|
|
58223
58407
|
return [
|
|
@@ -58232,7 +58416,7 @@ defineBuiltin({
|
|
|
58232
58416
|
return null;
|
|
58233
58417
|
},
|
|
58234
58418
|
apply: (args) => {
|
|
58235
|
-
const v = args[0];
|
|
58419
|
+
const v = isRuntimeClassInstance(args[0]) && args[0]._builtinData !== void 0 ? args[0]._builtinData : classInstanceArrayNumeric(args[0]) ?? args[0];
|
|
58236
58420
|
if (isRuntimeTensor(v)) {
|
|
58237
58421
|
const result = allocFloat64Array(v.data.length);
|
|
58238
58422
|
for (let i = 0; i < v.data.length; i++) {
|
|
@@ -63891,7 +64075,7 @@ function getSourceLine(getSource, file, line) {
|
|
|
63891
64075
|
}
|
|
63892
64076
|
|
|
63893
64077
|
// src/numbl-core/version.ts
|
|
63894
|
-
var NUMBL_VERSION = "0.4.
|
|
64078
|
+
var NUMBL_VERSION = "0.4.11";
|
|
63895
64079
|
|
|
63896
64080
|
// src/cli-repl.ts
|
|
63897
64081
|
import { createInterface } from "readline";
|
|
@@ -66402,6 +66586,8 @@ function evalBinary(expr) {
|
|
|
66402
66586
|
const right = this.evalExpr(expr.right);
|
|
66403
66587
|
const lv = ensureRuntimeValue(left);
|
|
66404
66588
|
const rv = ensureRuntimeValue(right);
|
|
66589
|
+
const enumResult = enumEqualityOp(expr.op, lv, rv);
|
|
66590
|
+
if (enumResult !== null) return enumResult;
|
|
66405
66591
|
if (isRuntimeClassInstance(lv) || isRuntimeClassInstance(rv)) {
|
|
66406
66592
|
return this.rt.binop(expr.op, left, right);
|
|
66407
66593
|
}
|
|
@@ -66506,6 +66692,8 @@ function evalMember(expr, nargout) {
|
|
|
66506
66692
|
if (lastDot > 0) {
|
|
66507
66693
|
const prefix = dottedName.slice(0, lastDot);
|
|
66508
66694
|
const methodName = dottedName.slice(lastDot + 1);
|
|
66695
|
+
const enumMember = this.interpretEnumMember(prefix, methodName);
|
|
66696
|
+
if (enumMember !== null) return enumMember;
|
|
66509
66697
|
if (this.functionIndex.classStaticMethods.get(prefix)?.has(methodName) || // Implicit static `ClassName.empty` (handled by interpretClassMethod)
|
|
66510
66698
|
methodName === "empty" && this.functionIndex.workspaceClasses.has(prefix)) {
|
|
66511
66699
|
const target = {
|
|
@@ -66965,6 +67153,7 @@ __export(interpreterFunctions_exports, {
|
|
|
66965
67153
|
callNestedFunction: () => callNestedFunction,
|
|
66966
67154
|
callUserFunction: () => callUserFunction,
|
|
66967
67155
|
collectClassProperties: () => collectClassProperties,
|
|
67156
|
+
convertToEnum: () => convertToEnum,
|
|
66968
67157
|
declaredNargin: () => declaredNargin,
|
|
66969
67158
|
evalInLocalScope: () => evalInLocalScope,
|
|
66970
67159
|
findExternalMethod: () => findExternalMethod,
|
|
@@ -66976,6 +67165,7 @@ __export(interpreterFunctions_exports, {
|
|
|
66976
67165
|
instantiateClass: () => instantiateClass,
|
|
66977
67166
|
interpretClassMethod: () => interpretClassMethod,
|
|
66978
67167
|
interpretConstructor: () => interpretConstructor,
|
|
67168
|
+
interpretEnumMember: () => interpretEnumMember,
|
|
66979
67169
|
interpretJsUserFunction: () => interpretJsUserFunction,
|
|
66980
67170
|
interpretLocalFunction: () => interpretLocalFunction,
|
|
66981
67171
|
interpretPrivateFunction: () => interpretPrivateFunction,
|
|
@@ -67805,11 +67995,95 @@ function interpretPrivateFunction(target, args, nargout) {
|
|
|
67805
67995
|
}
|
|
67806
67996
|
throw new RuntimeError(`Private function '${target.name}' not found`);
|
|
67807
67997
|
}
|
|
67998
|
+
var NUMERIC_ENUM_SUPERS = /* @__PURE__ */ new Set([
|
|
67999
|
+
"double",
|
|
68000
|
+
"single",
|
|
68001
|
+
"int8",
|
|
68002
|
+
"int16",
|
|
68003
|
+
"int32",
|
|
68004
|
+
"int64",
|
|
68005
|
+
"uint8",
|
|
68006
|
+
"uint16",
|
|
68007
|
+
"uint32",
|
|
68008
|
+
"uint64",
|
|
68009
|
+
"logical",
|
|
68010
|
+
"char"
|
|
68011
|
+
]);
|
|
68012
|
+
function enumUnderlyingValue(interp, classInfo, argExprs) {
|
|
68013
|
+
if (argExprs.length === 0) return void 0;
|
|
68014
|
+
const first = ensureRuntimeValue(interp.evalExpr(argExprs[0]));
|
|
68015
|
+
const sc = classInfo.superClass;
|
|
68016
|
+
if (sc && NUMERIC_ENUM_SUPERS.has(sc)) {
|
|
68017
|
+
return ensureRuntimeValue(interp.rt.callBuiltin(sc, 1, [first]));
|
|
68018
|
+
}
|
|
68019
|
+
return first;
|
|
68020
|
+
}
|
|
68021
|
+
function interpretEnumMember(className, memberName) {
|
|
68022
|
+
const classInfo = this.ctx.getClassInfo(className);
|
|
68023
|
+
if (!classInfo || !classInfo.enumMembers) return null;
|
|
68024
|
+
const memberDef = classInfo.enumMembers.find((m) => m.name === memberName);
|
|
68025
|
+
if (!memberDef) return null;
|
|
68026
|
+
const value = enumUnderlyingValue(this, classInfo, memberDef.args);
|
|
68027
|
+
return new RuntimeClassInstance(
|
|
68028
|
+
className,
|
|
68029
|
+
/* @__PURE__ */ new Map(),
|
|
68030
|
+
false,
|
|
68031
|
+
value,
|
|
68032
|
+
memberName
|
|
68033
|
+
);
|
|
68034
|
+
}
|
|
68035
|
+
function convertToEnum(className, classInfo, args) {
|
|
68036
|
+
if (args.length === 0) {
|
|
68037
|
+
throw new RuntimeError(
|
|
68038
|
+
`${className}: enumeration requires an argument to construct`
|
|
68039
|
+
);
|
|
68040
|
+
}
|
|
68041
|
+
const val = ensureRuntimeValue(args[0]);
|
|
68042
|
+
if (isRuntimeClassInstance(val) && val._enumMember !== void 0) return val;
|
|
68043
|
+
if (isRuntimeClassInstanceArray(val)) return val;
|
|
68044
|
+
const members = classInfo.enumMembers.map((m) => ({
|
|
68045
|
+
name: m.name,
|
|
68046
|
+
value: enumUnderlyingValue(this, classInfo, m.args)
|
|
68047
|
+
}));
|
|
68048
|
+
const makeMember = (name, value) => new RuntimeClassInstance(className, /* @__PURE__ */ new Map(), false, value, name);
|
|
68049
|
+
const fromName = (text) => {
|
|
68050
|
+
const m = members.find((mm) => mm.name === text);
|
|
68051
|
+
if (!m)
|
|
68052
|
+
throw new RuntimeError(
|
|
68053
|
+
`'${text}' is not a valid member of enumeration '${className}'`
|
|
68054
|
+
);
|
|
68055
|
+
return makeMember(m.name, m.value);
|
|
68056
|
+
};
|
|
68057
|
+
const fromNumber = (num) => {
|
|
68058
|
+
const m = members.find(
|
|
68059
|
+
(mm) => mm.value !== void 0 && toNumber(mm.value) === num
|
|
68060
|
+
);
|
|
68061
|
+
if (!m)
|
|
68062
|
+
throw new RuntimeError(
|
|
68063
|
+
`${num} is not a valid underlying value for enumeration '${className}'`
|
|
68064
|
+
);
|
|
68065
|
+
return makeMember(m.name, m.value);
|
|
68066
|
+
};
|
|
68067
|
+
if (isRuntimeChar(val)) return fromName(val.value);
|
|
68068
|
+
if (isRuntimeString(val)) return fromName(val);
|
|
68069
|
+
if (isRuntimeNumber(val)) return fromNumber(val);
|
|
68070
|
+
if (isRuntimeLogical(val)) return fromNumber(val ? 1 : 0);
|
|
68071
|
+
if (isRuntimeTensor(val)) {
|
|
68072
|
+
const elems = Array.from(val.data, (x) => fromNumber(x));
|
|
68073
|
+
if (elems.length === 1) return elems[0];
|
|
68074
|
+
const shape = [val.shape[0] ?? 0, val.shape[1] ?? 1];
|
|
68075
|
+
return RTV.classInstanceArray(className, elems, shape);
|
|
68076
|
+
}
|
|
68077
|
+
throw new RuntimeError(`Cannot convert value to enumeration '${className}'`);
|
|
68078
|
+
}
|
|
67808
68079
|
function instantiateClass(className, args, nargout) {
|
|
67809
68080
|
const classInfo = this.ctx.getClassInfo(className);
|
|
67810
68081
|
if (!classInfo) {
|
|
67811
68082
|
return this.rt.callClassMethod(className, className, nargout, args);
|
|
67812
68083
|
}
|
|
68084
|
+
if (classInfo.enumMembers && args.length > 0) {
|
|
68085
|
+
return this.convertToEnum(className, classInfo, args);
|
|
68086
|
+
}
|
|
67813
68087
|
if (classInfo.isOldStyle) {
|
|
67814
68088
|
const ctorName = classInfo.constructorName ?? className;
|
|
67815
68089
|
const ctorFn = this.findExternalMethod(classInfo, ctorName);
|
|
@@ -68610,6 +68884,7 @@ function extractClassInfo(classDef, qualifiedName, fileName, source) {
|
|
|
68610
68884
|
const methodNames = /* @__PURE__ */ new Set();
|
|
68611
68885
|
const staticMethodNames = /* @__PURE__ */ new Set();
|
|
68612
68886
|
let constructorName = null;
|
|
68887
|
+
let enumMembers = null;
|
|
68613
68888
|
const dotIdx = qualifiedName.lastIndexOf(".");
|
|
68614
68889
|
const baseName = dotIdx >= 0 ? qualifiedName.slice(dotIdx + 1) : qualifiedName;
|
|
68615
68890
|
for (const member of classDef.members) {
|
|
@@ -68651,6 +68926,8 @@ function extractClassInfo(classDef, qualifiedName, fileName, source) {
|
|
|
68651
68926
|
}
|
|
68652
68927
|
}
|
|
68653
68928
|
}
|
|
68929
|
+
} else if (member.type === "Enumeration") {
|
|
68930
|
+
enumMembers = member.members.map((m) => ({ name: m.name, args: m.args }));
|
|
68654
68931
|
}
|
|
68655
68932
|
}
|
|
68656
68933
|
const inferiorClasses = [];
|
|
@@ -68673,6 +68950,7 @@ function extractClassInfo(classDef, qualifiedName, fileName, source) {
|
|
|
68673
68950
|
methodNames,
|
|
68674
68951
|
staticMethodNames,
|
|
68675
68952
|
constructorName,
|
|
68953
|
+
enumMembers,
|
|
68676
68954
|
inferiorClasses,
|
|
68677
68955
|
ast: classDef,
|
|
68678
68956
|
externalMethodFiles: /* @__PURE__ */ new Map()
|
|
@@ -68703,6 +68981,7 @@ function makeOldStyleClassInfo(qualifiedName, baseName, constructorFile, methodF
|
|
|
68703
68981
|
methodNames,
|
|
68704
68982
|
staticMethodNames: /* @__PURE__ */ new Set(),
|
|
68705
68983
|
constructorName: baseName,
|
|
68984
|
+
enumMembers: null,
|
|
68706
68985
|
inferiorClasses: [],
|
|
68707
68986
|
ast: null,
|
|
68708
68987
|
isOldStyle: true,
|
|
@@ -94502,6 +94781,12 @@ function assertNoNonVoidBareExprStmts2(spec) {
|
|
|
94502
94781
|
|
|
94503
94782
|
// src/numbl-core/jit/lowering/classDefs.ts
|
|
94504
94783
|
function registerClassDef(s, file, externalMethods) {
|
|
94784
|
+
if (s.members.some((m) => m.type === "Enumeration")) {
|
|
94785
|
+
throw new UnsupportedConstruct(
|
|
94786
|
+
`classdef '${s.name}' is an enumeration; enumeration classes are interpreter-only in the JIT`,
|
|
94787
|
+
s.span
|
|
94788
|
+
);
|
|
94789
|
+
}
|
|
94505
94790
|
if (s.classAttributes.length > 0) {
|
|
94506
94791
|
throw new UnsupportedConstruct(
|
|
94507
94792
|
`classdef '${s.name}' has class attributes; not supported in v1`,
|