vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
use super::{append_wgsl, emit_expr_string};
use crate::ir::model::expr::Expr;
use crate::ir::model::program::Program;
use crate::ir::model::types::AtomicOp;
use crate::lower::wgsl::{Error, LowerCtx};

pub(super) fn emit_atomic_expr(
    out: &mut String,
    op: AtomicOp,
    buffer: &str,
    index: &Expr,
    expected: Option<&Expr>,
    value: &Expr,
    program: &Program,
    ctx: &LowerCtx<'_>,
) -> Result<(), Error> {
    if op != AtomicOp::CompareExchange && expected.is_some() {
        return Err(Error::lowering(
            "non-compare-exchange atomic includes an expected value. Fix: use Expr::Atomic.expected only with AtomicOp::CompareExchange.",
        ));
    }

    let fn_name = match &op {
        AtomicOp::Add => "add",
        AtomicOp::Or => "or",
        AtomicOp::And => "and",
        AtomicOp::Xor => "xor",
        AtomicOp::Min => "min",
        AtomicOp::Max => "max",
        AtomicOp::Exchange => "exchange",
        AtomicOp::CompareExchange => "compare_exchange",
    };
    append_wgsl(out, format_args!("_vyre_atomic_{fn_name}_{buffer}("))?;
    emit_expr_string(out, index, program, ctx)?;
    out.push_str(", ");
    if op == AtomicOp::CompareExchange {
        let expected = expected.ok_or_else(|| {
            Error::lowering(
                "compare-exchange atomic is missing expected value. Fix: set Expr::Atomic.expected for AtomicOp::CompareExchange.",
            )
        })?;
        emit_expr_string(out, expected, program, ctx)?;
        out.push_str(", ");
    }
    emit_expr_string(out, value, program, ctx)?;
    out.push(')');
    Ok(())
}