ReadonlyNode
이 페이지에서

ReadonlyNode

클래스, IR 분류

The read-only base of every value node: every literal, parameter, constRef and Let() binding is a ReadonlyNode.

import { ReadonlyNode } from 'typeshade'

시그니처, 설명, 예제는 커밋 c66579bf의 컴파일러 소스에서 그대로 가져온 영어 원문입니다.

구문

class ReadonlyNode<K extends string = string>

예외

TypeShadeError

SD0004 from an arithmetic or comparison method whose two operands have incompatible types (vec3<f32> against vec2<f32>, say). The Node<K> phantom key catches most of these at tsc time; this is the runtime check for an operand typed ReadonlyNode<string> or built dynamically.

설명

The read-only base of every value node: every literal, parameter, constRef and Let() binding is a ReadonlyNode. It carries the full chainable API, arithmetic (.add, .sub, …), comparison, swizzles, .at() and .select(), and no .assign(); that method lives only on the mutable Node subtype. Write a helper’s operand type as ReadonlyNode<K> whenever the value is only read: it then accepts a Let, a parameter and a Var alike, since Node is a subtype of this class.

생성자

new ReadonlyNode(readonly expr: Expr)

인스턴스 속성

__k선택 사항읽기 전용 K

Phantom type key. Optional and never assigned, so it carries K covariantly at the type level (a Node<'vec3<f32>'> is not assignable where a Node<'vec2<f32>'> is wanted) at no runtime cost. It is a plain optional field and must stay one: Babel’s TypeScript transform rejects declare class fields.

type읽기 전용 ShaderType
x읽기 전용 Node<ElemKey<K>>
y읽기 전용 Node<ElemKey<K>>
z읽기 전용 Node<ElemKey<K>>
w읽기 전용 Node<ElemKey<K>>
r읽기 전용 Node<ElemKey<K>>
g읽기 전용 Node<ElemKey<K>>
b읽기 전용 Node<ElemKey<K>>
a읽기 전용 Node<ElemKey<K>>
rgb읽기 전용 Node<SwizzleKey<K, 'rgb'>>
xy읽기 전용 Node<SwizzleKey<K, 'xy'>>
xyz읽기 전용 Node<SwizzleKey<K, 'xyz'>>
zyx읽기 전용 Node<SwizzleKey<K, 'zyx'>>
zxy읽기 전용 Node<SwizzleKey<K, 'zxy'>>
yzx읽기 전용 Node<SwizzleKey<K, 'yzx'>>
bgr읽기 전용 Node<SwizzleKey<K, 'bgr'>>
bgra읽기 전용 Node<SwizzleKey<K, 'bgra'>>

인스턴스 메서드

add <K2 extends `vec${number}<${K}>`>(this: ReadonlyNode<NonComposite<K>>, o: ReadonlyNode<K2>): Node<K2>
add (this: ReadonlyNode<'f32'>, o: ReadonlyNode<'f64'>): Node<'f64'>
add (o: ArithArg<K>): Node<K>
add (o: NodeLike): Node
sub <K2 extends `vec${number}<${K}>`>(this: ReadonlyNode<NonComposite<K>>, o: ReadonlyNode<K2>): Node<K2>
sub (this: ReadonlyNode<'f32'>, o: ReadonlyNode<'f64'>): Node<'f64'>
sub (o: ArithArg<K>): Node<K>
sub (o: NodeLike): Node
mul <K2 extends `vec${number}<${K}>`>(this: ReadonlyNode<NonComposite<K>>, o: ReadonlyNode<K2>): Node<K2>
mul (this: ReadonlyNode<'f32'>, o: ReadonlyNode<'f64'>): Node<'f64'>
mul (o: ArithArg<K>): Node<K>
mul (o: NodeLike): Node
div <K2 extends `vec${number}<${K}>`>(this: ReadonlyNode<NonComposite<K>>, o: ReadonlyNode<K2>): Node<K2>
div (this: ReadonlyNode<'f32'>, o: ReadonlyNode<'f64'>): Node<'f64'>
div (o: ArithArg<K>): Node<K>
div (o: NodeLike): Node
mod <K2 extends `vec${number}<${K}>`>(this: ReadonlyNode<NonComposite<K>>, o: ReadonlyNode<K2>): Node<K2>
mod (o: ArithArg<K>): Node<K>
mod (o: NodeLike): Node
neg (): Node<K>
lt (this: ReadonlyNode<NonComposite<K>>, o: CmpArg<K>): Node<'bool'>
gt (this: ReadonlyNode<NonComposite<K>>, o: CmpArg<K>): Node<'bool'>
le (this: ReadonlyNode<NonComposite<K>>, o: CmpArg<K>): Node<'bool'>
ge (this: ReadonlyNode<NonComposite<K>>, o: CmpArg<K>): Node<'bool'>
eq (this: ReadonlyNode<NonComposite<K>>, o: CmpArg<K>): Node<'bool'>
ne (this: ReadonlyNode<NonComposite<K>>, o: CmpArg<K>): Node<'bool'>
and (o: ReadonlyNode<'bool'>): Node<'bool'>
or (o: ReadonlyNode<'bool'>): Node<'bool'>
not (this: ReadonlyNode<'bool'>): Node<'bool'>

Logical negation, the ! of both targets. It completes the .and / .or set, which until now could say every boolean expression except the simplest one.

The node it builds is this == false, which is what the "use typeshade" compiler lowers a source-level !a to. That is the point: the two authoring surfaces meet in the IR, so a helper moved from one to the other keeps its emit. The emitted text is (a == false) rather than !a.

bitAnd (o: ReadonlyNode<K & ('i32' | 'u32')> | number): Node<K>
bitOr (o: ReadonlyNode<K & ('i32' | 'u32')> | number): Node<K>
bitXor (o: ReadonlyNode<K & ('i32' | 'u32')> | number): Node<K>
shl (o: ReadonlyNode<'u32'> | number): Node<K>
shr (o: ReadonlyNode<'u32'> | number): Node<K>
comp (field: 'x' | 'y' | 'z' | 'w'): Node<ElemKey<K>>

Vector component access: .x, .y, .z or .w, returning the element scalar.

swizzle <S extends string>(comps: S): Node<SwizzleKey<K, S>>

Vector swizzle: .rgb, .xy, .a, and so on. One component gives a scalar; N components give a vecN of the same element type. The result key is inferred from the components string, so v4.swizzle('yxz') is Node<'vec3<f32>'> for an f32 source and element-typed for u32 and i32 vectors too. The components are validated: xyzw or rgba, one set per swizzle, each within the source’s component count.

swizzle (comps: string): Node
f32 (this: ReadonlyNode<NonComposite<K>>): Node<'f32'>

Convert this scalar to f32, the method form of toF32. Emits f32(x) on WGSL and float(x) on GLSL, and narrows an f64 exactly (the sum of its hi and lo halves).

i32 (this: ReadonlyNode<NonComposite<K>>): Node<'i32'>

Convert this scalar to i32, the method form of toI32. Emits i32(x) on WGSL and int(x) on GLSL.

u32 (this: ReadonlyNode<NonComposite<K>>): Node<'u32'>

Convert this scalar to u32, the method form of toU32. Emits u32(x) on WGSL and uint(x) on GLSL.

f64 (this: ReadonlyNode<'f32'>): Node<'f64'>

Widen this f32 to the emulated double f64, exactly — the result is the pair (x, 0.0). The method form of toF64, and bounded to an f32 receiver for the same reason that is: no other scalar has an exact widening the fp64 lowering implements.

at <T extends ShaderType>(idx: ReadonlyNode<ScalarKey> | number, elem: T): Node<KeyOf<T>>

Array index, base[idx]. A JS number index lifts to a u32 literal, since WGSL indices are integers.

The element token is optional on an array-keyed node: xs.at(i) reads the element from the array’s own key, so an array<f32, 4> indexes to Node<'f32'> with nothing restated. It is the spelling a storageBuffer handle’s .at(i) already had, and the one the "use typeshade" surface’s xs[i] matches. Forgetting the token used to be a runtime TypeError rather than a tsc error, since the element ShaderType was the only place the type came from.

Pass the token for a node whose key does not carry the element — a widened ReadonlyNode<string>, or a struct read the phantom key cannot see into.

at (this: ReadonlyNode<`array<${string}>`>, idx: ReadonlyNode<ScalarKey> | number): Node<ArrayElemKey<K>>
at (idx: ReadonlyNode<ScalarKey> | number, elem?: ShaderType): Node
select (this: ReadonlyNode<'bool'>, a: number, b: number): Node<'f32'>

this ? a : b, valid only on a bool node (enforced through the this: bound). Both branches must share a key. Emits WGSL select(b, a, this).

select <R extends string>(this: ReadonlyNode<'bool'>, a: ReadonlyNode<R> | number, b: ReadonlyNode<R> | number): Node<R>
select <R extends string = 'f32'>(this: ReadonlyNode<'bool'>, a: ReadonlyNode<R> | number, b: ReadonlyNode<R> | number): Node<R>

함께 보기

소스

src/core/ir/node.ts, 346행, 커밋 c66579bf 기준

이 페이지 편집 문제 보고