use super::gpu_directive_parse_shared::{
directive_program_from_parse, push_c_identifier_span, push_directive_row_bounds,
push_hash_and_keyword_start, push_keyword_end, push_ws_skip_from_expr, DirectiveOutputColumn,
DirectiveThreadLayout,
};
use crate::parsing::c::lex::tokens::TOK_PP_UNDEF;
use vyre::ir::{Expr, Node, Program};
pub const OP_ID: &str = "vyre-libs::parsing::c::preprocess::gpu_undef_parse_v2";
pub const BINDING_TOK_STARTS: u32 = 0;
pub const BINDING_TOK_LENS: u32 = 1;
pub const BINDING_DIRECTIVE_KINDS: u32 = 2;
pub const BINDING_SOURCE: u32 = 3;
pub const BINDING_NAME_START_OUT: u32 = 4;
pub const BINDING_NAME_LEN_OUT: u32 = 5;
const OUTPUT_COLUMNS: [DirectiveOutputColumn; 2] = [
DirectiveOutputColumn {
name: "undef_name_start_out",
binding: BINDING_NAME_START_OUT,
},
DirectiveOutputColumn {
name: "undef_name_len_out",
binding: BINDING_NAME_LEN_OUT,
},
];
const UNDEF_KW_LEN: u32 = 5;
#[must_use]
pub fn gpu_undef_parse(num_tokens: u32, source_len: u32) -> Program {
let t = Expr::var("t");
let mut parse: Vec<Node> = Vec::new();
push_directive_row_bounds(&mut parse);
push_hash_and_keyword_start(&mut parse);
push_keyword_end(&mut parse, Expr::u32(UNDEF_KW_LEN));
push_ws_skip_from_expr(
&mut parse,
"np",
Expr::var("post_kw"),
"name_skip",
"name_start_val",
);
push_c_identifier_span(&mut parse, "name_start_val", "name_len_val", "name_done");
parse.push(Node::let_bind(
"valid_name",
Expr::select(
Expr::ne(Expr::var("name_len_val"), Expr::u32(0)),
Expr::u32(1),
Expr::u32(0),
),
));
parse.push(Node::if_then(
Expr::eq(
Expr::bitand(Expr::var("found_hash"), Expr::var("valid_name")),
Expr::u32(1),
),
vec![
Node::store(
"undef_name_start_out",
t.clone(),
Expr::var("name_start_val"),
),
Node::store("undef_name_len_out", t.clone(), Expr::var("name_len_val")),
],
));
directive_program_from_parse(
OP_ID,
num_tokens,
source_len,
&OUTPUT_COLUMNS,
DirectiveThreadLayout::InvocationId,
Expr::eq(Expr::var("kind"), Expr::u32(TOK_PP_UNDEF)),
parse,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn op_id_is_canonical_and_stable() {
assert_eq!(
OP_ID,
"vyre-libs::parsing::c::preprocess::gpu_undef_parse_v2"
);
}
#[test]
fn build_program_returns_well_formed_program() {
let p = gpu_undef_parse(8, 64);
assert_eq!(p.buffers().len(), 6);
assert_eq!(p.workgroup_size(), [256, 1, 1]);
}
}