Let()
함수, 작성 분류
Bind a value to an immutable local, emitting let name = expr; into the innermost active scope.
import { Let } from 'typeshade'
시그니처, 설명, 예제는 커밋 c66579bf의 컴파일러 소스에서 그대로 가져온 영어 원문입니다.
구문
function Let<K extends string>(value: ReadonlyNode<K>): ReadonlyNode<K>;function Let<K extends string>(name: string, value: ReadonlyNode<K>): ReadonlyNode<K>;매개변수
valueReadonlyNode<K>the expression to bind.
namethe emitted binding name. Omit it and the builder generates one.
반환값
ReadonlyNode<K>
a read-only node reading the binding.
설명
Bind a value to an immutable local, emitting let name = expr; into the innermost active
scope. It is the ambient counterpart of Builder.let, resolving the innermost active
builder itself so a body reads plainly without threading b through every nested
If or Loop callback.
It returns the read-only node type, so binding.assign(...) is a tsc error. To mutate,
declare with Var. Read APIs take the read-only type too, so a Let result flows
everywhere a value is read.
Most intermediates need no wrapper at all: author a plain const and the emit decides
between inlining, a shared let and a var. The case where a Let is load-bearing is a
loop that mutates a var. Common-subexpression elimination cannot cache a subexpression
that reads a mutated var, because its value differs per read site, so a value derived from
that var re-emits at every read unless it is materialised. Inside such a loop, wrap
anything derived from the mutated var that you read more than once.
예제
예제
import { fn, Loop, Let, If, Break, length, f32, u32, f32T, vec3fT } from 'typeshade'
const march = fn('march', { ro: vec3fT, rd: vec3fT }, f32T, ({ ro, rd }) => { const t = f32(0) // mutated below, so the emit materialises it as a var Loop(u32(0), (i) => i.lt(u32(72)), () => { const p = ro.add(rd.mul(t)) const d = Let(length(p).sub(1)) // computed once; without Let it re-emits per read If(d.lt(0.001), () => Break()) t.assign(t.add(d)) }) return t})관련 가이드
함께 보기
소스
src/core/ir/builder.ts, 1611행, 커밋 c66579bf 기준