diff --git a/stage0/zig0_bridge.zig b/stage0/zig0_bridge.zig deleted file mode 100644 index 6c681749d8..0000000000 --- a/stage0/zig0_bridge.zig +++ /dev/null @@ -1,706 +0,0 @@ -const std = @import("std"); -const Ast = std.zig.Ast; -const Allocator = std.mem.Allocator; -const Token = std.zig.Token; - -pub const enabled = true; - -pub const c = @cImport({ - @cInclude("ast.h"); - @cInclude("tokenizer.h"); -}); - -pub fn zigToken(token: c_uint) Token.Tag { - return switch (token) { - c.TOKEN_INVALID => .invalid, - c.TOKEN_INVALID_PERIODASTERISKS => .invalid_periodasterisks, - c.TOKEN_IDENTIFIER => .identifier, - c.TOKEN_STRING_LITERAL => .string_literal, - c.TOKEN_MULTILINE_STRING_LITERAL_LINE => .multiline_string_literal_line, - c.TOKEN_CHAR_LITERAL => .char_literal, - c.TOKEN_EOF => .eof, - c.TOKEN_BUILTIN => .builtin, - c.TOKEN_BANG => .bang, - c.TOKEN_PIPE => .pipe, - c.TOKEN_PIPE_PIPE => .pipe_pipe, - c.TOKEN_PIPE_EQUAL => .pipe_equal, - c.TOKEN_EQUAL => .equal, - c.TOKEN_EQUAL_EQUAL => .equal_equal, - c.TOKEN_EQUAL_ANGLE_BRACKET_RIGHT => .equal_angle_bracket_right, - c.TOKEN_BANG_EQUAL => .bang_equal, - c.TOKEN_L_PAREN => .l_paren, - c.TOKEN_R_PAREN => .r_paren, - c.TOKEN_SEMICOLON => .semicolon, - c.TOKEN_PERCENT => .percent, - c.TOKEN_PERCENT_EQUAL => .percent_equal, - c.TOKEN_L_BRACE => .l_brace, - c.TOKEN_R_BRACE => .r_brace, - c.TOKEN_L_BRACKET => .l_bracket, - c.TOKEN_R_BRACKET => .r_bracket, - c.TOKEN_PERIOD => .period, - c.TOKEN_PERIOD_ASTERISK => .period_asterisk, - c.TOKEN_ELLIPSIS2 => .ellipsis2, - c.TOKEN_ELLIPSIS3 => .ellipsis3, - c.TOKEN_CARET => .caret, - c.TOKEN_CARET_EQUAL => .caret_equal, - c.TOKEN_PLUS => .plus, - c.TOKEN_PLUS_PLUS => .plus_plus, - c.TOKEN_PLUS_EQUAL => .plus_equal, - c.TOKEN_PLUS_PERCENT => .plus_percent, - c.TOKEN_PLUS_PERCENT_EQUAL => .plus_percent_equal, - c.TOKEN_PLUS_PIPE => .plus_pipe, - c.TOKEN_PLUS_PIPE_EQUAL => .plus_pipe_equal, - c.TOKEN_MINUS => .minus, - c.TOKEN_MINUS_EQUAL => .minus_equal, - c.TOKEN_MINUS_PERCENT => .minus_percent, - c.TOKEN_MINUS_PERCENT_EQUAL => .minus_percent_equal, - c.TOKEN_MINUS_PIPE => .minus_pipe, - c.TOKEN_MINUS_PIPE_EQUAL => .minus_pipe_equal, - c.TOKEN_ASTERISK => .asterisk, - c.TOKEN_ASTERISK_EQUAL => .asterisk_equal, - c.TOKEN_ASTERISK_ASTERISK => .asterisk_asterisk, - c.TOKEN_ASTERISK_PERCENT => .asterisk_percent, - c.TOKEN_ASTERISK_PERCENT_EQUAL => .asterisk_percent_equal, - c.TOKEN_ASTERISK_PIPE => .asterisk_pipe, - c.TOKEN_ASTERISK_PIPE_EQUAL => .asterisk_pipe_equal, - c.TOKEN_ARROW => .arrow, - c.TOKEN_COLON => .colon, - c.TOKEN_SLASH => .slash, - c.TOKEN_SLASH_EQUAL => .slash_equal, - c.TOKEN_COMMA => .comma, - c.TOKEN_AMPERSAND => .ampersand, - c.TOKEN_AMPERSAND_EQUAL => .ampersand_equal, - c.TOKEN_QUESTION_MARK => .question_mark, - c.TOKEN_ANGLE_BRACKET_LEFT => .angle_bracket_left, - c.TOKEN_ANGLE_BRACKET_LEFT_EQUAL => .angle_bracket_left_equal, - c.TOKEN_ANGLE_BRACKET_ANGLE_BRACKET_LEFT => .angle_bracket_angle_bracket_left, - c.TOKEN_ANGLE_BRACKET_ANGLE_BRACKET_LEFT_EQUAL => .angle_bracket_angle_bracket_left_equal, - c.TOKEN_ANGLE_BRACKET_ANGLE_BRACKET_LEFT_PIPE => .angle_bracket_angle_bracket_left_pipe, - c.TOKEN_ANGLE_BRACKET_ANGLE_BRACKET_LEFT_PIPE_EQUAL => .angle_bracket_angle_bracket_left_pipe_equal, - c.TOKEN_ANGLE_BRACKET_RIGHT => .angle_bracket_right, - c.TOKEN_ANGLE_BRACKET_RIGHT_EQUAL => .angle_bracket_right_equal, - c.TOKEN_ANGLE_BRACKET_ANGLE_BRACKET_RIGHT => .angle_bracket_angle_bracket_right, - c.TOKEN_ANGLE_BRACKET_ANGLE_BRACKET_RIGHT_EQUAL => .angle_bracket_angle_bracket_right_equal, - c.TOKEN_TILDE => .tilde, - c.TOKEN_NUMBER_LITERAL => .number_literal, - c.TOKEN_DOC_COMMENT => .doc_comment, - c.TOKEN_CONTAINER_DOC_COMMENT => .container_doc_comment, - c.TOKEN_KEYWORD_ADDRSPACE => .keyword_addrspace, - c.TOKEN_KEYWORD_ALIGN => .keyword_align, - c.TOKEN_KEYWORD_ALLOWZERO => .keyword_allowzero, - c.TOKEN_KEYWORD_AND => .keyword_and, - c.TOKEN_KEYWORD_ANYFRAME => .keyword_anyframe, - c.TOKEN_KEYWORD_ANYTYPE => .keyword_anytype, - c.TOKEN_KEYWORD_ASM => .keyword_asm, - c.TOKEN_KEYWORD_BREAK => .keyword_break, - c.TOKEN_KEYWORD_CALLCONV => .keyword_callconv, - c.TOKEN_KEYWORD_CATCH => .keyword_catch, - c.TOKEN_KEYWORD_COMPTIME => .keyword_comptime, - c.TOKEN_KEYWORD_CONST => .keyword_const, - c.TOKEN_KEYWORD_CONTINUE => .keyword_continue, - c.TOKEN_KEYWORD_DEFER => .keyword_defer, - c.TOKEN_KEYWORD_ELSE => .keyword_else, - c.TOKEN_KEYWORD_ENUM => .keyword_enum, - c.TOKEN_KEYWORD_ERRDEFER => .keyword_errdefer, - c.TOKEN_KEYWORD_ERROR => .keyword_error, - c.TOKEN_KEYWORD_EXPORT => .keyword_export, - c.TOKEN_KEYWORD_EXTERN => .keyword_extern, - c.TOKEN_KEYWORD_FN => .keyword_fn, - c.TOKEN_KEYWORD_FOR => .keyword_for, - c.TOKEN_KEYWORD_IF => .keyword_if, - c.TOKEN_KEYWORD_INLINE => .keyword_inline, - c.TOKEN_KEYWORD_NOALIAS => .keyword_noalias, - c.TOKEN_KEYWORD_NOINLINE => .keyword_noinline, - c.TOKEN_KEYWORD_NOSUSPEND => .keyword_nosuspend, - c.TOKEN_KEYWORD_OPAQUE => .keyword_opaque, - c.TOKEN_KEYWORD_OR => .keyword_or, - c.TOKEN_KEYWORD_ORELSE => .keyword_orelse, - c.TOKEN_KEYWORD_PACKED => .keyword_packed, - c.TOKEN_KEYWORD_PUB => .keyword_pub, - c.TOKEN_KEYWORD_RESUME => .keyword_resume, - c.TOKEN_KEYWORD_RETURN => .keyword_return, - c.TOKEN_KEYWORD_LINKSECTION => .keyword_linksection, - c.TOKEN_KEYWORD_STRUCT => .keyword_struct, - c.TOKEN_KEYWORD_SUSPEND => .keyword_suspend, - c.TOKEN_KEYWORD_SWITCH => .keyword_switch, - c.TOKEN_KEYWORD_TEST => .keyword_test, - c.TOKEN_KEYWORD_THREADLOCAL => .keyword_threadlocal, - c.TOKEN_KEYWORD_TRY => .keyword_try, - c.TOKEN_KEYWORD_UNION => .keyword_union, - c.TOKEN_KEYWORD_UNREACHABLE => .keyword_unreachable, - c.TOKEN_KEYWORD_VAR => .keyword_var, - c.TOKEN_KEYWORD_VOLATILE => .keyword_volatile, - c.TOKEN_KEYWORD_WHILE => .keyword_while, - else => invalid_sentinel, - }; -} - -const invalid_sentinel = @as(Token.Tag, @enumFromInt(std.math.maxInt(@typeInfo(Token.Tag).@"enum".tag_type))); - -pub fn zigNode(token: c_uint) Ast.Node.Tag { - return switch (token) { - c.AST_NODE_ROOT => .root, - c.AST_NODE_TEST_DECL => .test_decl, - c.AST_NODE_GLOBAL_VAR_DECL => .global_var_decl, - c.AST_NODE_LOCAL_VAR_DECL => .local_var_decl, - c.AST_NODE_SIMPLE_VAR_DECL => .simple_var_decl, - c.AST_NODE_ALIGNED_VAR_DECL => .aligned_var_decl, - c.AST_NODE_ERRDEFER => .@"errdefer", - c.AST_NODE_DEFER => .@"defer", - c.AST_NODE_CATCH => .@"catch", - c.AST_NODE_FIELD_ACCESS => .field_access, - c.AST_NODE_UNWRAP_OPTIONAL => .unwrap_optional, - c.AST_NODE_EQUAL_EQUAL => .equal_equal, - c.AST_NODE_BANG_EQUAL => .bang_equal, - c.AST_NODE_LESS_THAN => .less_than, - c.AST_NODE_GREATER_THAN => .greater_than, - c.AST_NODE_LESS_OR_EQUAL => .less_or_equal, - c.AST_NODE_GREATER_OR_EQUAL => .greater_or_equal, - c.AST_NODE_ASSIGN_MUL => .assign_mul, - c.AST_NODE_ASSIGN_DIV => .assign_div, - c.AST_NODE_ASSIGN_MOD => .assign_mod, - c.AST_NODE_ASSIGN_ADD => .assign_add, - c.AST_NODE_ASSIGN_SUB => .assign_sub, - c.AST_NODE_ASSIGN_SHL => .assign_shl, - c.AST_NODE_ASSIGN_SHL_SAT => .assign_shl_sat, - c.AST_NODE_ASSIGN_SHR => .assign_shr, - c.AST_NODE_ASSIGN_BIT_AND => .assign_bit_and, - c.AST_NODE_ASSIGN_BIT_XOR => .assign_bit_xor, - c.AST_NODE_ASSIGN_BIT_OR => .assign_bit_or, - c.AST_NODE_ASSIGN_MUL_WRAP => .assign_mul_wrap, - c.AST_NODE_ASSIGN_ADD_WRAP => .assign_add_wrap, - c.AST_NODE_ASSIGN_SUB_WRAP => .assign_sub_wrap, - c.AST_NODE_ASSIGN_MUL_SAT => .assign_mul_sat, - c.AST_NODE_ASSIGN_ADD_SAT => .assign_add_sat, - c.AST_NODE_ASSIGN_SUB_SAT => .assign_sub_sat, - c.AST_NODE_ASSIGN => .assign, - c.AST_NODE_ASSIGN_DESTRUCTURE => .assign_destructure, - c.AST_NODE_MERGE_ERROR_SETS => .merge_error_sets, - c.AST_NODE_MUL => .mul, - c.AST_NODE_DIV => .div, - c.AST_NODE_MOD => .mod, - c.AST_NODE_ARRAY_MULT => .array_mult, - c.AST_NODE_MUL_WRAP => .mul_wrap, - c.AST_NODE_MUL_SAT => .mul_sat, - c.AST_NODE_ADD => .add, - c.AST_NODE_SUB => .sub, - c.AST_NODE_ARRAY_CAT => .array_cat, - c.AST_NODE_ADD_WRAP => .add_wrap, - c.AST_NODE_SUB_WRAP => .sub_wrap, - c.AST_NODE_ADD_SAT => .add_sat, - c.AST_NODE_SUB_SAT => .sub_sat, - c.AST_NODE_SHL => .shl, - c.AST_NODE_SHL_SAT => .shl_sat, - c.AST_NODE_SHR => .shr, - c.AST_NODE_BIT_AND => .bit_and, - c.AST_NODE_BIT_XOR => .bit_xor, - c.AST_NODE_BIT_OR => .bit_or, - c.AST_NODE_ORELSE => .@"orelse", - c.AST_NODE_BOOL_AND => .bool_and, - c.AST_NODE_BOOL_OR => .bool_or, - c.AST_NODE_BOOL_NOT => .bool_not, - c.AST_NODE_NEGATION => .negation, - c.AST_NODE_BIT_NOT => .bit_not, - c.AST_NODE_NEGATION_WRAP => .negation_wrap, - c.AST_NODE_ADDRESS_OF => .address_of, - c.AST_NODE_TRY => .@"try", - c.AST_NODE_OPTIONAL_TYPE => .optional_type, - c.AST_NODE_ARRAY_TYPE => .array_type, - c.AST_NODE_ARRAY_TYPE_SENTINEL => .array_type_sentinel, - c.AST_NODE_PTR_TYPE_ALIGNED => .ptr_type_aligned, - c.AST_NODE_PTR_TYPE_SENTINEL => .ptr_type_sentinel, - c.AST_NODE_PTR_TYPE => .ptr_type, - c.AST_NODE_PTR_TYPE_BIT_RANGE => .ptr_type_bit_range, - c.AST_NODE_SLICE_OPEN => .slice_open, - c.AST_NODE_SLICE => .slice, - c.AST_NODE_SLICE_SENTINEL => .slice_sentinel, - c.AST_NODE_DEREF => .deref, - c.AST_NODE_ARRAY_ACCESS => .array_access, - c.AST_NODE_ARRAY_INIT_ONE => .array_init_one, - c.AST_NODE_ARRAY_INIT_ONE_COMMA => .array_init_one_comma, - c.AST_NODE_ARRAY_INIT_DOT_TWO => .array_init_dot_two, - c.AST_NODE_ARRAY_INIT_DOT_TWO_COMMA => .array_init_dot_two_comma, - c.AST_NODE_ARRAY_INIT_DOT => .array_init_dot, - c.AST_NODE_ARRAY_INIT_DOT_COMMA => .array_init_dot_comma, - c.AST_NODE_ARRAY_INIT => .array_init, - c.AST_NODE_ARRAY_INIT_COMMA => .array_init_comma, - c.AST_NODE_STRUCT_INIT_ONE => .struct_init_one, - c.AST_NODE_STRUCT_INIT_ONE_COMMA => .struct_init_one_comma, - c.AST_NODE_STRUCT_INIT_DOT_TWO => .struct_init_dot_two, - c.AST_NODE_STRUCT_INIT_DOT_TWO_COMMA => .struct_init_dot_two_comma, - c.AST_NODE_STRUCT_INIT_DOT => .struct_init_dot, - c.AST_NODE_STRUCT_INIT_DOT_COMMA => .struct_init_dot_comma, - c.AST_NODE_STRUCT_INIT => .struct_init, - c.AST_NODE_STRUCT_INIT_COMMA => .struct_init_comma, - c.AST_NODE_CALL_ONE => .call_one, - c.AST_NODE_CALL_ONE_COMMA => .call_one_comma, - c.AST_NODE_CALL => .call, - c.AST_NODE_CALL_COMMA => .call_comma, - c.AST_NODE_SWITCH => .@"switch", - c.AST_NODE_SWITCH_COMMA => .switch_comma, - c.AST_NODE_SWITCH_CASE_ONE => .switch_case_one, - c.AST_NODE_SWITCH_CASE_INLINE_ONE => .switch_case_inline_one, - c.AST_NODE_SWITCH_CASE => .switch_case, - c.AST_NODE_SWITCH_CASE_INLINE => .switch_case_inline, - c.AST_NODE_SWITCH_RANGE => .switch_range, - c.AST_NODE_WHILE_SIMPLE => .while_simple, - c.AST_NODE_WHILE_CONT => .while_cont, - c.AST_NODE_WHILE => .@"while", - c.AST_NODE_FOR_SIMPLE => .for_simple, - c.AST_NODE_FOR => .@"for", - c.AST_NODE_FOR_RANGE => .for_range, - c.AST_NODE_IF_SIMPLE => .if_simple, - c.AST_NODE_IF => .@"if", - c.AST_NODE_SUSPEND => .@"suspend", - c.AST_NODE_RESUME => .@"resume", - c.AST_NODE_CONTINUE => .@"continue", - c.AST_NODE_BREAK => .@"break", - c.AST_NODE_RETURN => .@"return", - c.AST_NODE_FN_PROTO_SIMPLE => .fn_proto_simple, - c.AST_NODE_FN_PROTO_MULTI => .fn_proto_multi, - c.AST_NODE_FN_PROTO_ONE => .fn_proto_one, - c.AST_NODE_FN_PROTO => .fn_proto, - c.AST_NODE_FN_DECL => .fn_decl, - c.AST_NODE_ANYFRAME_TYPE => .anyframe_type, - c.AST_NODE_ANYFRAME_LITERAL => .anyframe_literal, - c.AST_NODE_CHAR_LITERAL => .char_literal, - c.AST_NODE_NUMBER_LITERAL => .number_literal, - c.AST_NODE_UNREACHABLE_LITERAL => .unreachable_literal, - c.AST_NODE_IDENTIFIER => .identifier, - c.AST_NODE_ENUM_LITERAL => .enum_literal, - c.AST_NODE_STRING_LITERAL => .string_literal, - c.AST_NODE_MULTILINE_STRING_LITERAL => .multiline_string_literal, - c.AST_NODE_GROUPED_EXPRESSION => .grouped_expression, - c.AST_NODE_BUILTIN_CALL_TWO => .builtin_call_two, - c.AST_NODE_BUILTIN_CALL_TWO_COMMA => .builtin_call_two_comma, - c.AST_NODE_BUILTIN_CALL => .builtin_call, - c.AST_NODE_BUILTIN_CALL_COMMA => .builtin_call_comma, - c.AST_NODE_ERROR_SET_DECL => .error_set_decl, - c.AST_NODE_CONTAINER_DECL => .container_decl, - c.AST_NODE_CONTAINER_DECL_TRAILING => .container_decl_trailing, - c.AST_NODE_CONTAINER_DECL_TWO => .container_decl_two, - c.AST_NODE_CONTAINER_DECL_TWO_TRAILING => .container_decl_two_trailing, - c.AST_NODE_CONTAINER_DECL_ARG => .container_decl_arg, - c.AST_NODE_CONTAINER_DECL_ARG_TRAILING => .container_decl_arg_trailing, - c.AST_NODE_TAGGED_UNION => .tagged_union, - c.AST_NODE_TAGGED_UNION_TRAILING => .tagged_union_trailing, - c.AST_NODE_TAGGED_UNION_TWO => .tagged_union_two, - c.AST_NODE_TAGGED_UNION_TWO_TRAILING => .tagged_union_two_trailing, - c.AST_NODE_TAGGED_UNION_ENUM_TAG => .tagged_union_enum_tag, - c.AST_NODE_TAGGED_UNION_ENUM_TAG_TRAILING => .tagged_union_enum_tag_trailing, - c.AST_NODE_CONTAINER_FIELD_INIT => .container_field_init, - c.AST_NODE_CONTAINER_FIELD_ALIGN => .container_field_align, - c.AST_NODE_CONTAINER_FIELD => .container_field, - c.AST_NODE_COMPTIME => .@"comptime", - c.AST_NODE_NOSUSPEND => .@"nosuspend", - c.AST_NODE_BLOCK_TWO => .block_two, - c.AST_NODE_BLOCK_TWO_SEMICOLON => .block_two_semicolon, - c.AST_NODE_BLOCK => .block, - c.AST_NODE_BLOCK_SEMICOLON => .block_semicolon, - c.AST_NODE_ASM_SIMPLE => .asm_simple, - c.AST_NODE_ASM_LEGACY => .asm_legacy, - c.AST_NODE_ASM => .@"asm", - c.AST_NODE_ASM_OUTPUT => .asm_output, - c.AST_NODE_ASM_INPUT => .asm_input, - c.AST_NODE_ERROR_VALUE => .error_value, - c.AST_NODE_ERROR_UNION => .error_union, - else => @as(Ast.Node.Tag, @enumFromInt(std.math.maxInt(@typeInfo(Ast.Node.Tag).@"enum".tag_type))), - }; -} - -fn toIndex(v: u32) Ast.Node.Index { - return @enumFromInt(v); -} - -fn toOptIndex(v: u32) Ast.Node.OptionalIndex { - return if (v == 0) .none else @enumFromInt(v); -} - -fn toExtraIndex(v: u32) Ast.ExtraIndex { - return @enumFromInt(v); -} - -fn toOptTokenIndex(v: u32) Ast.OptionalTokenIndex { - return @enumFromInt(v); -} - -fn zigData(tag: Ast.Node.Tag, lhs: u32, rhs: u32) Ast.Node.Data { - return switch (tag) { - // data unused - .identifier, - .string_literal, - .char_literal, - .number_literal, - .unreachable_literal, - .anyframe_literal, - .enum_literal, - .error_value, - => .{ .opt_node_and_opt_node = .{ toOptIndex(lhs), toOptIndex(rhs) } }, - - // .node (single node index) - .@"defer", - .@"comptime", - .@"nosuspend", - .@"suspend", - .@"resume", - .bool_not, - .negation, - .bit_not, - .negation_wrap, - .address_of, - .@"try", - .deref, - .optional_type, - => .{ .node = toIndex(lhs) }, - - // .opt_node (single optional node) - .@"return", - => .{ .opt_node = toOptIndex(lhs) }, - - // .node_and_node - .fn_decl, - .container_field_align, - .error_union, - .@"catch", - .equal_equal, - .bang_equal, - .less_than, - .greater_than, - .less_or_equal, - .greater_or_equal, - .assign_mul, - .assign_div, - .assign_mod, - .assign_add, - .assign_sub, - .assign_shl, - .assign_shl_sat, - .assign_shr, - .assign_bit_and, - .assign_bit_xor, - .assign_bit_or, - .assign_mul_wrap, - .assign_add_wrap, - .assign_sub_wrap, - .assign_mul_sat, - .assign_add_sat, - .assign_sub_sat, - .assign, - .merge_error_sets, - .mul, - .div, - .mod, - .array_mult, - .mul_wrap, - .mul_sat, - .add, - .sub, - .array_cat, - .add_wrap, - .sub_wrap, - .add_sat, - .sub_sat, - .shl, - .shl_sat, - .shr, - .bit_and, - .bit_xor, - .bit_or, - .@"orelse", - .bool_and, - .bool_or, - .array_type, - .array_access, - .switch_range, - => .{ .node_and_node = .{ toIndex(lhs), toIndex(rhs) } }, - - // .opt_node_and_opt_node - .fn_proto_simple, - .simple_var_decl, - .block_two, - .block_two_semicolon, - .builtin_call_two, - .builtin_call_two_comma, - .container_decl_two, - .container_decl_two_trailing, - .tagged_union_two, - .tagged_union_two_trailing, - .struct_init_dot_two, - .struct_init_dot_two_comma, - .array_init_dot_two, - .array_init_dot_two_comma, - => .{ .opt_node_and_opt_node = .{ toOptIndex(lhs), toOptIndex(rhs) } }, - - // .node_and_opt_node - .call_one, - .call_one_comma, - .struct_init_one, - .struct_init_one_comma, - .container_field_init, - .aligned_var_decl, - => .{ .node_and_opt_node = .{ toIndex(lhs), toOptIndex(rhs) } }, - - // .node_and_node (array_init_one uses node_and_node, not - // node_and_opt_node) - .array_init_one, - .array_init_one_comma, - => .{ .node_and_node = .{ toIndex(lhs), toIndex(rhs) } }, - - // .opt_node_and_node - .ptr_type_aligned, - .ptr_type_sentinel, - .switch_case_one, - .switch_case_inline_one, - => .{ .opt_node_and_node = .{ toOptIndex(lhs), toIndex(rhs) } }, - - // .node_and_extra - .call, - .call_comma, - .container_field, - .array_type_sentinel, - .slice, - .slice_sentinel, - .array_init, - .array_init_comma, - .struct_init, - .struct_init_comma, - .@"switch", - .switch_comma, - .container_decl_arg, - .container_decl_arg_trailing, - .tagged_union_enum_tag, - .tagged_union_enum_tag_trailing, - .@"asm", - => .{ .node_and_extra = .{ toIndex(lhs), toExtraIndex(rhs) } }, - - // .extra_and_node - .assign_destructure, - .switch_case, - .switch_case_inline, - .ptr_type, - .ptr_type_bit_range, - => .{ .extra_and_node = .{ toExtraIndex(lhs), toIndex(rhs) } }, - - // .extra_and_opt_node - .global_var_decl, - .local_var_decl, - .fn_proto_multi, - .fn_proto_one, - .fn_proto, - => .{ .extra_and_opt_node = .{ toExtraIndex(lhs), toOptIndex(rhs) } }, - - // .extra_range (SubRange) - .root, - .block, - .block_semicolon, - .builtin_call, - .builtin_call_comma, - .container_decl, - .container_decl_trailing, - .tagged_union, - .tagged_union_trailing, - .array_init_dot, - .array_init_dot_comma, - .struct_init_dot, - .struct_init_dot_comma, - => .{ .extra_range = .{ .start = toExtraIndex(lhs), .end = toExtraIndex(rhs) } }, - - // .node_and_token - .grouped_expression, - .asm_input, - .asm_simple, - .field_access, - .unwrap_optional, - => .{ .node_and_token = .{ toIndex(lhs), rhs } }, - - // .opt_node_and_token - .asm_output, - => .{ .opt_node_and_token = .{ toOptIndex(lhs), rhs } }, - - // .opt_token_and_node - .test_decl, - .@"errdefer", - => .{ .opt_token_and_node = .{ toOptTokenIndex(lhs), toIndex(rhs) } }, - - // .opt_token_and_opt_node - .@"break", - .@"continue", - => .{ .opt_token_and_opt_node = .{ toOptTokenIndex(lhs), toOptIndex(rhs) } }, - - // .token_and_token - .error_set_decl, - .multiline_string_literal, - => .{ .token_and_token = .{ lhs, rhs } }, - - // .token_and_node - .anyframe_type, - => .{ .token_and_node = .{ lhs, toIndex(rhs) } }, - - // .node_and_node for slice_open (lhs[rhs..]) - .slice_open, - => .{ .node_and_node = .{ toIndex(lhs), toIndex(rhs) } }, - - .while_simple, - .for_simple, - .if_simple, - => .{ .node_and_node = .{ toIndex(lhs), toIndex(rhs) } }, - - .while_cont, - .@"while", - .@"if", - => .{ .node_and_extra = .{ toIndex(lhs), toExtraIndex(rhs) } }, - - .for_range, - => .{ .node_and_opt_node = .{ toIndex(lhs), toOptIndex(rhs) } }, - - .@"for", - => .{ .@"for" = .{ toExtraIndex(lhs), @bitCast(rhs) } }, - - .asm_legacy, - => .{ .node_and_extra = .{ toIndex(lhs), toExtraIndex(rhs) } }, - }; -} - -// zigAst converts a c.Ast to std.Zig.Ast. The resulting Ast should be freed with deinit(). -pub fn zigAst(gpa: Allocator, c_ast: c.Ast) !Ast { - var tokens = Ast.TokenList{}; - try tokens.resize(gpa, c_ast.tokens.len); - errdefer tokens.deinit(gpa); - - for (0..c_ast.tokens.len) |i| - tokens.set(i, .{ - .tag = zigToken(c_ast.tokens.tags[i]), - .start = c_ast.tokens.starts[i], - }); - - var nodes = Ast.NodeList{}; - try nodes.resize(gpa, c_ast.nodes.len); - errdefer nodes.deinit(gpa); - - for (0..c_ast.nodes.len) |i| { - const tag = zigNode(c_ast.nodes.tags[i]); - nodes.set(i, .{ - .tag = tag, - .main_token = c_ast.nodes.main_tokens[i], - .data = zigData(tag, c_ast.nodes.datas[i].lhs, c_ast.nodes.datas[i].rhs), - }); - } - - const extra_data = try gpa.alloc(u32, c_ast.extra_data.len); - errdefer gpa.free(extra_data); - @memcpy(extra_data, c_ast.extra_data.arr[0..c_ast.extra_data.len]); - - const errors = if (c_ast.has_error) blk: { - const errs = try gpa.alloc(Ast.Error, 1); - errs[0] = .{ .tag = .expected_token, .token = 0, .extra = .{ .none = {} } }; - break :blk errs; - } else try gpa.alloc(Ast.Error, 0); - errdefer gpa.free(errors); - - return Ast{ - .source = c_ast.source[0..c_ast.source_len :0], - .mode = .zig, - .tokens = tokens.slice(), - .nodes = nodes.slice(), - .extra_data = extra_data, - .errors = errors, - }; -} - -// Returns the number of meaningful u32 fields in Node.Data for a given tag. -// 0 = data is undefined/unused, 1 = only first u32 is meaningful, 2 = both meaningful. -fn dataFieldCount(tag: Ast.Node.Tag) u2 { - return switch (tag) { - // data unused (undefined in Zig parser) - .identifier, - .string_literal, - .char_literal, - .number_literal, - .unreachable_literal, - .anyframe_literal, - .enum_literal, - .error_value, - => 0, - - // .node or .opt_node — only first u32 - .@"defer", - .@"comptime", - .@"nosuspend", - .@"suspend", - .@"resume", - .bool_not, - .negation, - .bit_not, - .negation_wrap, - .address_of, - .@"try", - .deref, - .optional_type, - .@"return", - => 1, - - // everything else — both u32 fields - else => 2, - }; -} - -pub fn expectAstConsistent(c_tree: Ast, zig_tree: Ast, source: [:0]const u8) !void { - _ = source; - const print = std.debug.print; - - if (c_tree.tokens.len != zig_tree.tokens.len) { - print("token count mismatch: c={d} zig={d}\n", .{ c_tree.tokens.len, zig_tree.tokens.len }); - return error.TestExpectedEqual; - } - for (0..c_tree.tokens.len) |i| { - if (c_tree.tokens.items(.start)[i] != zig_tree.tokens.items(.start)[i]) { - print("token[{d}] start mismatch: c={d} zig={d}\n", .{ i, c_tree.tokens.items(.start)[i], zig_tree.tokens.items(.start)[i] }); - return error.TestExpectedEqual; - } - if (c_tree.tokens.items(.tag)[i] != zig_tree.tokens.items(.tag)[i]) { - print("token[{d}] tag mismatch: c={s} zig={s}\n", .{ i, @tagName(c_tree.tokens.items(.tag)[i]), @tagName(zig_tree.tokens.items(.tag)[i]) }); - return error.TestExpectedEqual; - } - } - - if (c_tree.nodes.len != zig_tree.nodes.len) { - print("node count mismatch: c={d} zig={d}\n", .{ c_tree.nodes.len, zig_tree.nodes.len }); - return error.TestExpectedEqual; - } - for (0..c_tree.nodes.len) |i| { - const c_tag = c_tree.nodes.items(.tag)[i]; - const z_tag = zig_tree.nodes.items(.tag)[i]; - if (c_tag != z_tag) { - print("node[{d}] tag mismatch: c={s} zig={s}\n", .{ i, @tagName(c_tag), @tagName(z_tag) }); - return error.TestExpectedEqual; - } - if (c_tree.nodes.items(.main_token)[i] != zig_tree.nodes.items(.main_token)[i]) { - print("node[{d}] main_token mismatch: c={d} zig={d}\n", .{ i, c_tree.nodes.items(.main_token)[i], zig_tree.nodes.items(.main_token)[i] }); - return error.TestExpectedEqual; - } - const field_count = dataFieldCount(c_tag); - if (field_count >= 1) { - const c_data: *const [2]u32 = @ptrCast(&c_tree.nodes.items(.data)[i]); - const z_data: *const [2]u32 = @ptrCast(&zig_tree.nodes.items(.data)[i]); - if (c_data[0] != z_data[0]) { - print("node[{d}] data[0] mismatch: c={d} zig={d}\n", .{ i, c_data[0], z_data[0] }); - return error.TestExpectedEqual; - } - if (field_count >= 2 and c_data[1] != z_data[1]) { - print("node[{d}] data[1] mismatch: c={d} zig={d}\n", .{ i, c_data[1], z_data[1] }); - return error.TestExpectedEqual; - } - } - } - - if (c_tree.extra_data.len != zig_tree.extra_data.len) { - print("extra_data length mismatch: c={d} zig={d}\n", .{ c_tree.extra_data.len, zig_tree.extra_data.len }); - return error.TestExpectedEqual; - } - for (0..c_tree.extra_data.len) |i| { - if (c_tree.extra_data[i] != zig_tree.extra_data[i]) { - print("extra_data[{d}] mismatch: c={d} zig={d}\n", .{ i, c_tree.extra_data[i], zig_tree.extra_data[i] }); - return error.TestExpectedEqual; - } - } -}