1/**
2 * The numbl compiler surface this project depends on.
3 *
4 * We reach past numbl's published entry points into its JIT internals (parser,
5 * lowerer, IR, inline pass, builtin registry), which its package `exports` map
6 * does not expose. Those imports resolve through the `numbl-src` alias in
7 * vite.config.ts; these declarations are what TypeScript checks against.
8 *
9 * This follows turing-surface's arrangement (see its src/mgpu/numbl.d.ts for
10 * the rationale); the surface here is wider because the sandbox lowers whole
11 * scripts rather than individual functions, and patches builtin type rules.
12 *
13 * Only the nodes the WGSL backend actually walks are spelled out; every other
14 * IR kind is collapsed into a catch-all so that unhandled constructs are
15 * rejected with a message instead of being silently mis-compiled.
16 */
18declare module 'numbl-src/numbl-core/jit/lowering/types.ts' {
19 export type Sign =
20 | 'positive' | 'nonneg' | 'negative' | 'nonpositive'
21 | 'zero' | 'nonzero' | 'unknown';
23 export type DimInfo = { kind: 'exact'; value: number } | { kind: 'unknown' };
25 export type NumericExact =
26 | number
27 | Float64Array
28 | { re: number; im: number }
29 | { re: Float64Array; im: Float64Array };
31 export interface NumericType {
32 kind: 'Numeric';
33 elem: 'double' | 'logical' | 'char' | string;
34 isComplex: boolean;
35 dims: DimInfo[];
36 /** Present iff every dim is exact. */
37 shape?: number[];
38 sign: Sign;
39 exact?: NumericExact;
40 }
42 /** Everything the WGSL backend rejects. */
43 export interface NonNumericType {
44 kind: 'Void' | 'Unknown' | 'String' | 'Handle' | 'Struct' | 'Class' | 'Cell';
45 }
47 export type Type = NumericType | NonNumericType;
49 export function isMultiElement(t: NumericType): boolean;
50 export function isNumeric(t: Type): t is NumericType;
51 export function isScalar(t: NumericType): boolean;
52 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
53 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
54}
56declare module 'numbl-src/numbl-core/jit/lowering/ir.ts' {
57 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
59 export interface Span {
60 file: string;
61 start: number;
62 end: number;
63 }
65 export interface NumLit {
66 kind: 'NumLit';
67 value: number;
68 ty: Type;
69 span: Span;
70 }
71 export interface StringLit {
72 kind: 'StringLit';
73 value: string;
74 ty: Type;
75 span: Span;
76 }
77 export interface Var {
78 kind: 'Var';
79 name: string;
80 cName: string;
81 ty: Type;
82 span: Span;
83 }
84 export interface Binary {
85 kind: 'Binary';
86 builtin: string;
87 left: IRExpr;
88 right: IRExpr;
89 ty: Type;
90 span: Span;
91 }
92 export interface Unary {
93 kind: 'Unary';
94 builtin: string;
95 operand: IRExpr;
96 ty: Type;
97 span: Span;
98 }
99 export interface Call {
100 kind: 'Call';
101 cName: string;
102 name: string;
103 args: IRExpr[];
104 ty: Type;
105 span: Span;
106 }
107 /** One slot of an `IndexSlice`'s subscript list. Only the full colon
108 * (`A(:)`) is executed by this backend; the other shapes exist so they can
109 * be rejected with a source location. */
110 export type IndexSliceArg =
111 | { kind: 'Colon' }
112 | { kind: 'Range' | 'Scalar' | 'Gather'; [k: string]: unknown };
113 export interface IndexSlice {
114 kind: 'IndexSlice';
115 base: IRExpr;
116 index: ReadonlyArray<IndexSliceArg>;
117 ty: Type;
118 span: Span;
119 }
120 export interface MakeRange {
121 kind: 'MakeRange';
122 start: IRExpr;
123 step: IRExpr;
124 end: IRExpr;
125 ty: Type;
126 span: Span;
127 }
128 /** Any other IR expression kind — rejected by the WGSL emitter. */
129 export interface OtherExpr {
130 kind:
131 | 'ImagLit' | 'TensorBuild' | 'TensorConcat' | 'CellLit'
132 | 'CellEmpty' | 'CellIndexLoad' | 'HandleLit' | 'HandleCaptureLoad'
133 | 'StructLit' | 'MemberLoad' | 'IndexLoad' | 'EndRef';
134 ty: Type;
135 span: Span;
136 }
138 export type IRExpr =
139 | NumLit | StringLit | Var | Binary | Unary | Call
140 | IndexSlice | MakeRange | OtherExpr;
142 export interface Assign {
143 kind: 'Assign';
144 name: string;
145 cName: string;
146 ty: Type;
147 expr: IRExpr;
148 span: Span;
149 }
150 export interface ExprStmt {
151 kind: 'ExprStmt';
152 expr: IRExpr;
153 span: Span;
154 }
155 /** A counted loop. `step` is already a literal number in the IR — numbl
156 * rejects a non-literal step during lowering — while `start` and `end` are
157 * expressions that must carry an exact value for the planner to accept the
158 * loop. */
159 export interface For {
160 kind: 'For';
161 /** Loop variable, as written in the .m. */
162 varName: string;
163 /** Loop variable's cName, the key kernels read its value under. */
164 cVar: string;
165 start: IRExpr;
166 step: number;
167 end: IRExpr;
168 body: IRStmt[];
169 span: Span;
170 }
171 /** Any other IR statement kind — rejected by the planner. */
172 export interface OtherStmt {
173 kind:
174 | 'If' | 'While' | 'ReturnFromFunction' | 'Break'
175 | 'Continue' | 'TypeComment' | 'MemberStore' | 'MultiAssignCall'
176 | 'IndexStore' | 'IndexSliceStore' | 'CellIndexStore';
177 span: Span;
178 }
180 export type IRStmt = Assign | ExprStmt | For | OtherStmt;
182 export interface IRFunc {
183 name: string;
184 cName: string;
185 params: string[];
186 cParams: string[];
187 paramTypes: Type[];
188 outputs: string[];
189 cOutputs: string[];
190 outputTypes: Type[];
191 body: IRStmt[];
192 span: Span;
193 }
195 export interface IRProgram {
196 topLevelStmts: IRStmt[];
197 functions: Map<string, IRFunc>;
198 }
199}
201declare module 'numbl-src/numbl-core/parser/index.ts' {
202 /** Parser statement. Only the fields the sandbox reads (statement span and
203 * the `;` suppression flag, which decides MATLAB-style display) are
204 * declared. Control-flow statements (`for`, `if`, ...) carry no
205 * `suppressed` flag. */
206 export interface AstStatement {
207 type: string;
208 suppressed?: boolean;
209 span: { start: number; end: number };
210 }
211 export interface AbstractSyntaxTree {
212 body: AstStatement[];
213 }
214 export function parseMFile(input: string, fileName?: string): AbstractSyntaxTree;
215 export class SyntaxError extends Error {}
216}
218declare module 'numbl-src/numbl-core/jit/index.ts' {
219 import type { AbstractSyntaxTree } from 'numbl-src/numbl-core/parser/index.ts';
220 import type { IRProgram, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
221 import type { NumericType, Sign } from 'numbl-src/numbl-core/jit/lowering/types.ts';
223 export interface WorkspaceFile {
224 name: string;
225 source: string;
226 ast?: AbstractSyntaxTree;
227 }
229 export class Workspace {
230 constructor(mainFile: string, searchPaths?: ReadonlyArray<string>);
231 addFile(file: WorkspaceFile): void;
232 finalize(): void;
233 }
235 export class Lowerer {
236 constructor(workspace: Workspace);
237 lowerProgram(ast: AbstractSyntaxTree): IRProgram;
238 }
240 /** Thrown for MATLAB the JIT pipeline cannot lower; carries a source span. */
241 export class UnsupportedConstruct extends Error {
242 span?: Span;
243 }
244 export class JitTypeError extends Error {
245 span?: Span;
246 }
248 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
249 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
250 export function isMultiElement(t: NumericType): boolean;
251}
253declare module 'numbl-src/numbl-core/jit/codegen/inlinePass.ts' {
254 import type { IRProgram } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
255 /** Folds single-use ANF temps into their consumer, in place. */
256 export function inlinePass(prog: IRProgram): void;
257}
259declare module 'numbl-src/numbl-core/jit/builtins/index.ts' {
260 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
262 /** A JIT builtin. Beyond `name` and `transfer` the object carries emit hooks
263 * and interpreter call hooks the sandbox never invokes (only numbl's own
264 * backends do); the index signature carries them through when patching. */
265 export interface Builtin {
266 name: string;
267 /** Safe to evaluate one output element from one input element per slot. */
268 elementwise?: boolean;
269 transfer(argTypes: Type[], nargout: number): Type[];
270 [k: string]: unknown;
271 }
272 export function getBuiltin(name: string): Builtin | undefined;
273 /** Overwrites any existing builtin of the same name (by design). */
274 export function registerBuiltin(b: Builtin): void;
275}