Stmt
On this page

Stmt

Type in IR

Every statement shape the IR can hold: the ordered readonly Stmt[] that makes up a FuncDecl.body.

import type { Stmt } from 'typeshade'

The signature, the description and the examples come from the compiler's own source at commit 26de7be8.

Syntax

type Stmt =
| {
readonly s: 'let';
readonly name: string;
readonly expr: Expr;
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'var';
readonly name: string;
readonly type: ShaderType;
readonly init?: Expr;
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'assign';
readonly target: Expr;
readonly expr: Expr;
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'assignOp';
readonly target: Expr;
readonly bop: BinOp;
readonly expr: Expr;
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'if';
readonly arms: ReadonlyArray<{ readonly cond: Expr; readonly body: readonly Stmt[] }>;
readonly elseBody?: readonly Stmt[];
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'return';
readonly expr?: Expr;
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'for';
readonly init: Stmt;
readonly cond: Expr;
readonly update: Stmt;
readonly body: readonly Stmt[];
/** What the front end proved counts this loop (Rule 7.5): present on a `for` and a
* `for…of` it lowered, absent on a `while`, which is a `for` over a synthetic counter,
* and on a pass-synthesised loop. The independence proof of a kernel function's loop
* (Rule 8.22) reads it rather than guessing from the counter's name. */
readonly counted?: {
/** The counter's IR name. */
readonly name: string;
readonly op: 'add' | 'mul' | 'div';
/** The addend of an additive step (`i++` is `1`, `i -= 2` is `-2`), and the factor or
* divisor of a multiplicative one. */
readonly step: number;
/** Present when the header folds to constants, absent for a runtime start or bound. */
readonly start?: number;
readonly bound?: number;
readonly trips?: number;
};
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| {
readonly s: 'switch';
readonly scrut: Expr;
/** One clause per entry. `values` is the SELECTORS that share the clause's body, in
* source order: WGSL spells them `case 0, 1: { … }` and GLSL ES 3.00
* `case 0: case 1: { … }`, which is why the IR carries the list rather than one
* number and a fall-through. Never empty. */
readonly cases: ReadonlyArray<{
readonly values: readonly number[];
readonly body: readonly Stmt[];
}>;
readonly defaultBody?: readonly Stmt[];
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| { readonly s: 'break'; readonly span?: SourceSpan }
| { readonly s: 'continue'; readonly span?: SourceSpan }
| { readonly s: 'discard'; readonly span?: SourceSpan }
| {
/** A call kept for its effect and nothing else: `store(gid.x);` today, and the
* `workgroupBarrier();`, `textureStore(...)` and `atomicAdd(...)` family it makes a place
* for. `expr` is the `call` the front end lowered; an op other than `call` reaches here
* only through a pass that folded one, and both emitters still spell it. WGSL takes a
* user function's dropped result bare and needs `_ = ` before a value-returning builtin;
* GLSL ES 3.00 takes the bare call in every case; the CPU backends evaluate it for its
* effect. A pass that assumes expressions are pure must treat this statement as the
* one place an effect is kept on purpose (see `passes/effects.ts`). */
readonly s: 'call';
readonly expr: Expr;
/** Where this statement came from in its authored `"use typeshade"` source; absent on
* an EDSL-authored or pass-synthesised statement. Read it with {@link sourceSpanOf}. */
readonly span?: SourceSpan;
}
| { readonly s: 'placeholder'; readonly tag: string; readonly span?: SourceSpan }
| { readonly s: 'raw'; readonly wgsl: string; readonly glsl?: string; readonly span?: SourceSpan }
| {
readonly s: 'raw';
readonly wgsl?: string;
readonly glsl: string;
readonly span?: SourceSpan;
};

Description

Like Expr, it is a discriminated union (on s) with no class behind it, so tsc checks a backend’s emit switch for exhaustiveness and a pass can rebuild a body by mapping over plain data. You do not build these object literals directly; the Builder handed to an fn body as its second callback argument pushes them one at a time (b.let(...), b.var(...), b.if(...), b.ret(...), …), so a body is always assembled in source order.

In the guide

See also

Source

src/core/ir/nodes.ts, line 199, at commit 26de7be8

Edit this page Report a problem