///|
fn WgslIrLowerer::lower_update_statement(
self : WgslIrLowerer,
target : @ast.WgslExprRef?,
function : Function,
scope : WgslIrFunctionScope,
block : Block,
increment : Bool,
) -> Unit raise WgslIrLowerError {
guard target is Some(target_ref) else {
raise UnsupportedStatement("update without target")
}
let pointer = self.lower_function_lvalue_ref(target_ref, function, scope)
self.lower_update_handle(pointer, function, scope, block, increment)
}
///|
fn WgslIrLowerer::lower_update_handle(
self : WgslIrLowerer,
pointer : Handle,
function : Function,
scope : WgslIrFunctionScope,
block : Block,
increment : Bool,
) -> Unit raise WgslIrLowerError {
let one = function.expressions.append(
Literal(self.update_unit_literal(function, pointer)),
)
let loaded = function.expressions.append(Load(pointer))
let loaded = self.materialize_function_expression(
function, scope, block, loaded,
)
let op = if increment { BinaryOperator::Add } else { Subtract }
let value = function.expressions.append(Binary(op, loaded, one))
block.push(Store(pointer, value))
}
///|
fn WgslIrLowerer::update_unit_literal(
self : WgslIrLowerer,
function : Function,
pointer : Handle,
) -> Literal {
guard self.function_expression_type(function, pointer) is Some(pointer_ty) else {
return I32(1)
}
let value_ty = self.deref_pointer_type_handle(pointer_ty)
match self.shader_module.types.get(value_ty) {
Some(ty) =>
match ty.inner {
Scalar(scalar) =>
match scalar.kind {
Uint => U32(1)
Sint => I32(1)
AbstractInt => AbstractInt(1)
_ => I32(1)
}
_ => I32(1)
}
None => I32(1)
}
}