Expand description
Pass: lift assignment-as-expression out of mid-statement positions.
HLSL accepts lerp(a, tmp = GetBlur1(uv), b) — the inner tmp = …
assigns and yields the new value as the call arg. WGSL has no
assignment expression and rejects the source at parse time with
“expected ) after call arguments; found Eq” (when our HLSL parser
is the one rejecting) or with invalid type for binary operator /
similar (when naga sees lerp(a, =, b)).
Rewrite shape: for each enclosing statement that contains one or more
embedded Expr::Assign sub-expressions, emit
- an insertion at the statement’s start with the assignment lifted to
a standalone
<target> = <value>;(preserving the HLSL side effect), - a replacement at the assignment’s position with just the target text (so the surrounding call’s arg count is preserved).
Only fires when the parser produces an Expr::Assign outside the
top-level Stmt::Assign slot — i.e. nested inside a Stmt::Return
value, an Stmt::LocalDecl init, an Stmt::Expr (typically a bare
call), or another Expr::Call’s arg list. Direct Stmt::Assigns are
already top-level and don’t need lifting.
Limitations:
- Nested
(x = y = z)chains in a call arg lift only the outermost level; the inner chain would re-enter [parse_expr] without going through this pass. Rare in the corpus. - The lifted assignment runs at the start of the enclosing statement, which is the HLSL evaluation order for the single-assignment case (call args evaluate left-to-right; the assigning arg’s side effect happens before the call). For multiple assigns in the same statement we emit them in source order, which still matches left-to-right.
Constants§
Functions§
- assign_
op_ 🔒str - collect_
embedded 🔒 - find_
return_ 🔒keyword_ before - Walk back from byte position
expr_startover whitespace, then check for thereturnkeyword. Returns the keyword’s start position when found,Noneotherwise (which keeps the caller from emitting a misplaced prelude). - rewrite_
embedded_ 🔒assigns - slice 🔒
- stmt_
span_ 🔒start - walk_
block 🔒 - walk_
stmt 🔒