/ concept-collection / turing-surface
Sign in
concept-collection / turing-surface
261 lines · 7.8 KBCodeBlameHistory
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), which its package `exports` map does not expose.
6 * Those imports resolve through the `numbl-src` alias in vite.config.ts; these
7 * declarations are what TypeScript checks against.
8 *
9 * Declaring the surface here rather than type-checking numbl's sources
10 * directly keeps this project's compiler settings independent of numbl's, and
11 * pins the exact contract we rely on. If numbl changes one of these shapes,
12 * the build breaks here with a clear diff rather than deep inside its tree.
13 *
14 * Only the nodes the WGSL backend actually walks are spelled out; every other
15 * IR kind is collapsed into a catch-all so that unhandled constructs are
16 * rejected with a message instead of being silently mis-compiled.
17 */
19declare module 'numbl-src/numbl-core/jit/lowering/types.ts' {
20 export type Sign =
21 | 'positive' | 'nonneg' | 'negative' | 'nonpositive'
22 | 'zero' | 'nonzero' | 'unknown';
24 export type DimInfo = { kind: 'exact'; value: number } | { kind: 'unknown' };
26 export type NumericExact =
27 | number
28 | Float64Array
29 | { re: number; im: number }
30 | { re: Float64Array; im: Float64Array };
32 export interface NumericType {
33 kind: 'Numeric';
34 elem: 'double' | 'logical' | 'char' | string;
35 isComplex: boolean;
36 dims: DimInfo[];
37 /** Present iff every dim is exact. */
38 shape?: number[];
39 sign: Sign;
40 exact?: NumericExact;
41 }
43 /** Everything the WGSL backend rejects. */
44 export interface NonNumericType {
45 kind: 'Void' | 'Unknown' | 'String' | 'Handle' | 'Struct' | 'Class' | 'Cell';
46 }
48 export type Type = NumericType | NonNumericType;
50 export function isMultiElement(t: NumericType): boolean;
51 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
52 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
55declare module 'numbl-src/numbl-core/jit/lowering/ir.ts' {
56 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
58 export interface Span {
59 file: string;
60 start: number;
61 end: number;
62 }
64 export interface NumLit {
65 kind: 'NumLit';
66 value: number;
67 ty: Type;
68 span: Span;
69 }
70 export interface Var {
71 kind: 'Var';
72 name: string;
73 cName: string;
74 ty: Type;
75 span: Span;
76 }
77 export interface Binary {
78 kind: 'Binary';
79 builtin: string;
80 left: IRExpr;
81 right: IRExpr;
82 ty: Type;
83 span: Span;
84 }
85 export interface Unary {
86 kind: 'Unary';
87 builtin: string;
88 operand: IRExpr;
89 ty: Type;
90 span: Span;
91 }
92 export interface Call {
93 kind: 'Call';
94 cName: string;
95 name: string;
96 args: IRExpr[];
97 ty: Type;
98 span: Span;
99 }
100 /** Any other IR expression kind — rejected by the WGSL emitter. */
101 export interface OtherExpr {
102 kind:
103 | 'ImagLit' | 'StringLit' | 'TensorBuild' | 'TensorConcat' | 'CellLit'
104 | 'CellEmpty' | 'CellIndexLoad' | 'HandleLit' | 'HandleCaptureLoad'
105 | 'StructLit' | 'MemberLoad' | 'IndexLoad' | 'IndexSlice' | 'EndRef'
106 | 'MakeRange';
107 ty: Type;
108 span: Span;
109 }
111 export type IRExpr = NumLit | Var | Binary | Unary | Call | OtherExpr;
113 export interface Assign {
114 kind: 'Assign';
115 name: string;
116 cName: string;
117 ty: Type;
118 expr: IRExpr;
119 span: Span;
120 }
121 /**
122 * A counted loop. The planner unrolls it, so only the fields that decide
123 * the trip count and the loop variable's value are spelled out. `step` is
124 * already a literal number in the IR — numbl rejects a non-literal step
125 * during lowering — while `start` and `end` are expressions that must carry
126 * an exact value for the planner to accept the loop.
127 */
128 export interface For {
129 kind: 'For';
130 /** Loop variable, as written in the .m. */
131 varName: string;
132 /** Loop variable's cName, the key the planner binds its value under. */
133 cVar: string;
134 start: IRExpr;
135 step: number;
136 end: IRExpr;
137 body: IRStmt[];
138 span: Span;
139 }
140 /** Any other IR statement kind — rejected by the planner. */
141 export interface OtherStmt {
142 kind:
143 | 'ExprStmt' | 'If' | 'While' | 'ReturnFromFunction' | 'Break'
144 | 'Continue' | 'TypeComment' | 'MemberStore' | 'MultiAssignCall'
145 | 'IndexStore' | 'IndexSliceStore' | 'CellIndexStore';
146 span: Span;
147 }
149 export type IRStmt = Assign | For | OtherStmt;
151 export interface IRFunc {
152 name: string;
153 cName: string;
154 /** Parameter source names. */
155 params: string[];
156 /** Parameter cNames, parallel to `params`. */
157 cParams: string[];
158 paramTypes: Type[];
159 /** Output source names. */
160 outputs: string[];
161 /** Output cNames, parallel to `outputs`. */
162 cOutputs: string[];
163 outputTypes: Type[];
164 body: IRStmt[];
165 span: Span;
166 }
168 export interface IRProgram {
169 topLevelStmts: IRStmt[];
170 functions: Map<string, IRFunc>;
171 }
174declare module 'numbl-src/numbl-core/parser/index.ts' {
175 export interface AbstractSyntaxTree {
176 body: unknown[];
177 }
178 export function parseMFile(input: string, fileName?: string): AbstractSyntaxTree;
179 export class SyntaxError extends Error {}
182declare module 'numbl-src/numbl-core/jit/index.ts' {
183 import type { AbstractSyntaxTree } from 'numbl-src/numbl-core/parser/index.ts';
184 import type { IRProgram, IRFunc, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
185 import type { Type, NumericType, Sign } from 'numbl-src/numbl-core/jit/lowering/types.ts';
187 export interface WorkspaceFile {
188 name: string;
189 source: string;
190 ast?: AbstractSyntaxTree;
191 }
193 export class Workspace {
194 constructor(mainFile: string, searchPaths?: ReadonlyArray<string>);
195 addFile(file: WorkspaceFile): void;
196 finalize(): void;
197 }
199 export interface EnvEntry {
200 cName: string;
201 ty: Type;
202 maybeUnassigned?: boolean;
203 }
205 export class Lowerer {
206 constructor(workspace: Workspace);
207 /** Pre-bindable variable scope: seed host-provided values here. */
208 env: Map<string, EnvEntry>;
209 specializations: Map<string, IRFunc>;
210 lowerProgram(ast: AbstractSyntaxTree): IRProgram;
211 }
213 /** Thrown for MATLAB the JIT pipeline cannot lower; carries a source span. */
214 export class UnsupportedConstruct extends Error {
215 span?: Span;
216 }
217 export class JitTypeError extends Error {
218 span?: Span;
219 }
221 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
222 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
223 export function isMultiElement(t: NumericType): boolean;
226declare module 'numbl-src/numbl-core/jit/lowering/specialize.ts' {
227 import type { Lowerer } from 'numbl-src/numbl-core/jit/index.ts';
228 import type { IRFunc, IRExpr, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
229 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
231 /**
232 * Lower one user function for a concrete argument-type signature. Called with
233 * a `Lowerer` as `this` (numbl's own JIT does the same), so specializations
234 * accumulate in `lowerer.specializations`.
235 */
236 export function specializeUserFunction(
237 this: Lowerer,
238 decl: unknown,
239 argTypes: Type[],
240 specSource?: string,
241 definingFile?: string,
242 preSeedOutput?: { name: string; ty: Type; initExpr: IRExpr },
243 nargout?: number,
244 callSiteSpan?: Span,
245 ): IRFunc;
248declare module 'numbl-src/numbl-core/jit/codegen/inlinePass.ts' {
249 import type { IRProgram } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
250 /** Folds single-use ANF temps into their consumer, in place. */
251 export function inlinePass(prog: IRProgram): void;
254declare module 'numbl-src/numbl-core/jit/builtins/index.ts' {
255 export interface Builtin {
256 name: string;
257 /** Safe to evaluate one output element from one input element per slot. */
258 elementwise?: boolean;
259 }
260 export function getBuiltin(name: string): Builtin | undefined;
moveopenescclose