#[path = "../c_ast_gpu_parity_support/mod.rs"]
mod c_ast_gpu_parity_support;
use c_ast_gpu_parity_support::{
assert_full_pipeline_parity, build_fixture, row_indices, Fixture, FixtureToken,
};
use vyre_libs::parsing::c::lex::tokens::*;
use vyre_libs::parsing::c::parse::vast::{
reference_c11_annotate_typedef_names, reference_c11_build_vast_nodes,
reference_c11_classify_vast_node_kinds, C_AST_KIND_ASSIGN_EXPR, C_AST_KIND_ATTRIBUTE_USED,
C_AST_KIND_BREAK_STMT, C_AST_KIND_CASE_STMT, C_AST_KIND_COMPOUND_LITERAL_EXPR,
C_AST_KIND_CONTINUE_STMT, C_AST_KIND_DEFAULT_STMT, C_AST_KIND_DO_STMT, C_AST_KIND_FOR_STMT,
C_AST_KIND_FUNCTION_DECLARATOR, C_AST_KIND_FUNCTION_DEFINITION, C_AST_KIND_GNU_ATTRIBUTE,
C_AST_KIND_GOTO_STMT, C_AST_KIND_INITIALIZER_LIST, C_AST_KIND_INLINE_ASM,
C_AST_KIND_POINTER_DECL, C_AST_KIND_RETURN_STMT, C_AST_KIND_SWITCH_STMT, C_AST_KIND_WHILE_STMT,
};
use vyre_primitives::predicate::node_kind;
fn classify(fix: &Fixture) -> Vec<u8> {
let raw = reference_c11_build_vast_nodes(&fix.tok_types, &fix.tok_starts, &fix.tok_lens);
let annotated = reference_c11_annotate_typedef_names(&raw, fix.source.as_bytes());
reference_c11_classify_vast_node_kinds(&annotated)
}
fn fixture_designated_initializer_struct() -> Fixture {
build_fixture(&[
FixtureToken::new("struct", TOK_IDENTIFIER),
FixtureToken::new("S", TOK_IDENTIFIER),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("a", TOK_IDENTIFIER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("b", TOK_IDENTIFIER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("struct", TOK_IDENTIFIER),
FixtureToken::new("S", TOK_IDENTIFIER),
FixtureToken::new("s", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new(".", TOK_DOT),
FixtureToken::new("a", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("1", TOK_INTEGER),
FixtureToken::new(",", TOK_COMMA),
FixtureToken::new(".", TOK_DOT),
FixtureToken::new("b", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("2", TOK_INTEGER),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new(";", TOK_SEMICOLON),
])
}
fn fixture_designated_initializer_nested_array() -> Fixture {
build_fixture(&[
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("a", TOK_IDENTIFIER),
FixtureToken::new("[", TOK_LBRACKET),
FixtureToken::new("2", TOK_INTEGER),
FixtureToken::new("]", TOK_RBRACKET),
FixtureToken::new("[", TOK_LBRACKET),
FixtureToken::new("3", TOK_INTEGER),
FixtureToken::new("]", TOK_RBRACKET),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("[", TOK_LBRACKET),
FixtureToken::new("0", TOK_INTEGER),
FixtureToken::new("]", TOK_RBRACKET),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("[", TOK_LBRACKET),
FixtureToken::new("1", TOK_INTEGER),
FixtureToken::new("]", TOK_RBRACKET),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("42", TOK_INTEGER),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new(";", TOK_SEMICOLON),
])
}
fn fixture_compound_literal() -> Fixture {
build_fixture(&[
FixtureToken::new("void", TOK_IDENTIFIER),
FixtureToken::new("f", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("*", TOK_STAR),
FixtureToken::new("p", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("[", TOK_LBRACKET),
FixtureToken::new("]", TOK_RBRACKET),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("1", TOK_INTEGER),
FixtureToken::new(",", TOK_COMMA),
FixtureToken::new("2", TOK_INTEGER),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("g", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("struct", TOK_IDENTIFIER),
FixtureToken::new("S", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new(".", TOK_DOT),
FixtureToken::new("x", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("3", TOK_INTEGER),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
])
}
fn fixture_nested_declarator() -> Fixture {
build_fixture(&[
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("*", TOK_STAR),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("*", TOK_STAR),
FixtureToken::new("p", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("[", TOK_LBRACKET),
FixtureToken::new("3", TOK_INTEGER),
FixtureToken::new("]", TOK_RBRACKET),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new(";", TOK_SEMICOLON),
])
}
fn fixture_asm_attribute_interaction() -> Fixture {
build_fixture(&[
FixtureToken::new("__attribute__", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("used", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("x", TOK_IDENTIFIER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("void", TOK_IDENTIFIER),
FixtureToken::new("f", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("void", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("__asm__", TOK_IDENTIFIER),
FixtureToken::new("volatile", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("\"nop\"", TOK_STRING),
FixtureToken::new(":", TOK_COLON),
FixtureToken::new(":", TOK_COLON),
FixtureToken::new(":", TOK_COLON),
FixtureToken::new("\"memory\"", TOK_STRING),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
])
}
fn fixture_control_flow_all() -> Fixture {
build_fixture(&[
FixtureToken::new("void", TOK_IDENTIFIER),
FixtureToken::new("f", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("for", TOK_FOR),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("i", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("0", TOK_INTEGER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("i", TOK_IDENTIFIER),
FixtureToken::new("<", TOK_LT),
FixtureToken::new("10", TOK_INTEGER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("i", TOK_IDENTIFIER),
FixtureToken::new("++", TOK_INC),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("while", TOK_WHILE),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("cond", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("do", TOK_DO),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("break", TOK_BREAK),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new("while", TOK_WHILE),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("0", TOK_INTEGER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("continue", TOK_CONTINUE),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new("switch", TOK_SWITCH),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("v", TOK_IDENTIFIER),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("case", TOK_CASE),
FixtureToken::new("1", TOK_INTEGER),
FixtureToken::new(":", TOK_COLON),
FixtureToken::new("goto", TOK_GOTO),
FixtureToken::new("end", TOK_IDENTIFIER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("default", TOK_DEFAULT),
FixtureToken::new(":", TOK_COLON),
FixtureToken::new("return", TOK_RETURN),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new("end", TOK_IDENTIFIER),
FixtureToken::new(":", TOK_COLON),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
])
}
fn fixture_typedef_shadowing() -> Fixture {
build_fixture(&[
FixtureToken::new("typedef", TOK_IDENTIFIER),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("T", TOK_IDENTIFIER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("void", TOK_IDENTIFIER),
FixtureToken::new("f", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("T", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("1", TOK_INTEGER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("T", TOK_IDENTIFIER),
FixtureToken::new("++", TOK_INC),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new("void", TOK_IDENTIFIER),
FixtureToken::new("g", TOK_IDENTIFIER),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("T", TOK_IDENTIFIER),
FixtureToken::new("x", TOK_IDENTIFIER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
])
}
fn fixture_statement_expression() -> Fixture {
build_fixture(&[
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("x", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("(", TOK_LPAREN),
FixtureToken::new("{", TOK_LBRACE),
FixtureToken::new("int", TOK_IDENTIFIER),
FixtureToken::new("y", TOK_IDENTIFIER),
FixtureToken::new("=", TOK_ASSIGN),
FixtureToken::new("1", TOK_INTEGER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("y", TOK_IDENTIFIER),
FixtureToken::new("+", TOK_PLUS),
FixtureToken::new("2", TOK_INTEGER),
FixtureToken::new(";", TOK_SEMICOLON),
FixtureToken::new("}", TOK_RBRACE),
FixtureToken::new(")", TOK_RPAREN),
FixtureToken::new(";", TOK_SEMICOLON),
])
}
#[test]
fn designated_initializer_struct_parity_and_shape() {
let fix = fixture_designated_initializer_struct();
assert_full_pipeline_parity(&fix, "designated_initializer_struct");
let typed = classify(&fix);
assert!(
!typed.is_empty(),
"fixture must produce non-empty typed VAST"
);
let lists = row_indices(&typed, C_AST_KIND_INITIALIZER_LIST);
assert!(
!lists.is_empty(),
"struct initializer must contain INITIALIZER_LIST"
);
let assigns = row_indices(&typed, C_AST_KIND_ASSIGN_EXPR);
assert!(
assigns.len() >= 2,
"two designated assignments must exist, got {}",
assigns.len()
);
}
#[test]
fn designated_initializer_nested_array_parity_and_shape() {
let fix = fixture_designated_initializer_nested_array();
assert_full_pipeline_parity(&fix, "designated_initializer_nested_array");
let typed = classify(&fix);
assert!(
!typed.is_empty(),
"fixture must produce non-empty typed VAST"
);
let lists = row_indices(&typed, C_AST_KIND_INITIALIZER_LIST);
assert!(
lists.len() >= 2,
"nested array initializer must contain at least 2 INITIALIZER_LIST rows, got {}",
lists.len()
);
}
#[test]
fn compound_literal_parity_and_shape() {
let fix = fixture_compound_literal();
assert_full_pipeline_parity(&fix, "compound_literal");
let typed = classify(&fix);
assert!(
!typed.is_empty(),
"fixture must produce non-empty typed VAST"
);
let compounds = row_indices(&typed, C_AST_KIND_COMPOUND_LITERAL_EXPR);
assert!(
compounds.len() >= 2,
"compound literal fixture must contain at least 2 COMPOUND_LITERAL_EXPR rows, got {}",
compounds.len()
);
let lists = row_indices(&typed, C_AST_KIND_INITIALIZER_LIST);
assert!(
!lists.is_empty(),
"compound literal must contain INITIALIZER_LIST"
);
}