vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
struct Params {
    token_count: u32,
    transition_count: u32,
    start_state: u32,
    accept_state: u32,
    max_stack: u32,
    max_callbacks: u32,
};

@group(0) @binding(0) var<storage, read> tokens: array<u32>;
@group(0) @binding(1) var<storage, read> transitions: array<vec4<u32>>;
@group(0) @binding(2) var<storage, read> transition_push: array<u32>;
@group(0) @binding(3) var<storage, read_write> callbacks: array<u32>;
@group(0) @binding(4) var<storage, read_write> result: array<u32>;
@group(0) @binding(5) var<uniform> params: Params;

var<workgroup> stack: array<u32, 256>;

@compute @workgroup_size(1)
fn compiler_primitives_recursive_descent() {
    var state = params.start_state;
    var sp = 0u;
    var callback_count = 0u;
    var pos = 0u;
    loop {
        if (pos >= params.token_count) { break; }
        let token = tokens[pos];
        var found = false;
        var chosen = vec4<u32>(0u);
        var chosen_push = 0xffffffffu;
        var i = 0u;
        loop {
            if (i >= params.transition_count) { break; }
            let t = transitions[i];
            if (t.x == state && t.y == token) {
                found = true;
                chosen = t;
                chosen_push = transition_push[i];
                break;
            }
            i = i + 1u;
        }
        if (!found) {
            result[0] = 1u;
            result[1] = pos;
            return;
        }
        if (chosen_push != 0xffffffffu) {
            if (sp >= params.max_stack || sp >= 256u) {
                result[0] = 2u;
                result[1] = pos;
                return;
            }
            stack[sp] = chosen_push;
            sp = sp + 1u;
        }
        if (chosen.w != 0u) {
            if (callback_count >= params.max_callbacks) {
                result[0] = 3u;
                result[1] = pos;
                return;
            }
            callbacks[callback_count] = chosen.w;
            callback_count = callback_count + 1u;
        }
        if (chosen.z == 0xffffffffu) {
            if (sp == 0u) {
                result[0] = 4u;
                result[1] = pos;
                return;
            }
            sp = sp - 1u;
            state = stack[sp];
        } else {
            state = chosen.z;
        }
        pos = pos + 1u;
    }
    if (state != params.accept_state) {
        result[0] = 5u;
        result[1] = state;
        return;
    }
    result[0] = 0u;
    result[1] = callback_count;
    result[2] = pos;
}