struct Node [src]

Fields

tag: Tag
main_token: TokenIndex
data: Data

Members

Source

pub const Node = struct { tag: Tag, main_token: TokenIndex, data: Data, /// Index into `nodes`. pub const Index = enum(u32) { root = 0, _, pub fn toOptional(i: Index) OptionalIndex { const result: OptionalIndex = @enumFromInt(@intFromEnum(i)); assert(result != .none); return result; } pub fn toOffset(base: Index, destination: Index) Offset { const base_i64: i64 = @intFromEnum(base); const destination_i64: i64 = @intFromEnum(destination); return @enumFromInt(destination_i64 - base_i64); } }; /// Index into `nodes`, or null. pub const OptionalIndex = enum(u32) { root = 0, none = std.math.maxInt(u32), _, pub fn unwrap(oi: OptionalIndex) ?Index { return if (oi == .none) null else @enumFromInt(@intFromEnum(oi)); } pub fn fromOptional(oi: ?Index) OptionalIndex { return if (oi) |i| i.toOptional() else .none; } }; /// A relative node index. pub const Offset = enum(i32) { zero = 0, _, pub fn toOptional(o: Offset) OptionalOffset { const result: OptionalOffset = @enumFromInt(@intFromEnum(o)); assert(result != .none); return result; } pub fn toAbsolute(offset: Offset, base: Index) Index { return @enumFromInt(@as(i64, @intFromEnum(base)) + @intFromEnum(offset)); } }; /// A relative node index, or null. pub const OptionalOffset = enum(i32) { none = std.math.maxInt(i32), _, pub fn unwrap(oo: OptionalOffset) ?Offset { return if (oo == .none) null else @enumFromInt(@intFromEnum(oo)); } }; comptime { // Goal is to keep this under one byte for efficiency. assert(@sizeOf(Tag) == 1); if (!std.debug.runtime_safety) { assert(@sizeOf(Data) == 8); } } /// The FooComma/FooSemicolon variants exist to ease the implementation of /// `Ast.lastToken()` pub const Tag = enum { /// The root node which is guaranteed to be at `Node.Index.root`. /// The meaning of the `data` field depends on whether it is a `.zig` or /// `.zon` file. /// /// The `main_token` field is the first token for the source file. root, /// `usingnamespace expr;`. /// /// The `data` field is a `.node` to expr. /// /// The `main_token` field is the `usingnamespace` token. @"usingnamespace", /// `test {}`, /// `test "name" {}`, /// `test identifier {}`. /// /// The `data` field is a `.opt_token_and_node`: /// 1. a `OptionalTokenIndex` to the test name token (must be string literal or identifier), if any. /// 2. a `Node.Index` to the block. /// /// The `main_token` field is the `test` token. test_decl, /// The `data` field is a `.extra_and_opt_node`: /// 1. a `ExtraIndex` to `GlobalVarDecl`. /// 2. a `Node.OptionalIndex` to the initialization expression. /// /// The `main_token` field is the `var` or `const` token. /// /// The initialization expression can't be `.none` unless it is part of /// a `assign_destructure` node or a parsing error occured. global_var_decl, /// `var a: b align(c) = d`. /// `const main_token: type_node align(align_node) = init_expr`. /// /// The `data` field is a `.extra_and_opt_node`: /// 1. a `ExtraIndex` to `LocalVarDecl`. /// 2. a `Node.OptionalIndex` to the initialization expression- /// /// The `main_token` field is the `var` or `const` token. /// /// The initialization expression can't be `.none` unless it is part of /// a `assign_destructure` node or a parsing error occured. local_var_decl, /// `var a: b = c`. /// `const name_token: type_expr = init_expr`. /// Can be local or global. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the type expression, if any. /// 2. a `Node.OptionalIndex` to the initialization expression. /// /// The `main_token` field is the `var` or `const` token. /// /// The initialization expression can't be `.none` unless it is part of /// a `assign_destructure` node or a parsing error occured. simple_var_decl, /// `var a align(b) = c`. /// `const name_token align(align_expr) = init_expr`. /// Can be local or global. /// /// The `data` field is a `.node_and_opt_node`: /// 1. a `Node.Index` to the alignment expression. /// 2. a `Node.OptionalIndex` to the initialization expression. /// /// The `main_token` field is the `var` or `const` token. /// /// The initialization expression can't be `.none` unless it is part of /// a `assign_destructure` node or a parsing error occured. aligned_var_decl, /// `errdefer expr`, /// `errdefer |payload| expr`. /// /// The `data` field is a `.opt_token_and_node`: /// 1. a `OptionalTokenIndex` to the payload identifier, if any. /// 2. a `Node.Index` to the deferred expression. /// /// The `main_token` field is the `errdefer` token. @"errdefer", /// `defer expr`. /// /// The `data` field is a `.node` to the deferred expression. /// /// The `main_token` field is the `defer`. @"defer", /// `lhs catch rhs`, /// `lhs catch |err| rhs`. /// /// The `main_token` field is the `catch` token. /// /// The error payload is determined by looking at the next token after /// the `catch` token. @"catch", /// `lhs.a`. /// /// The `data` field is a `.node_and_token`: /// 1. a `Node.Index` to the left side of the field access. /// 2. a `TokenIndex` to the field name identifier. /// /// The `main_token` field is the `.` token. field_access, /// `lhs.?`. /// /// The `data` field is a `.node_and_token`: /// 1. a `Node.Index` to the left side of the optional unwrap. /// 2. a `TokenIndex` to the `?` token. /// /// The `main_token` field is the `.` token. unwrap_optional, /// `lhs == rhs`. The `main_token` field is the `==` token. equal_equal, /// `lhs != rhs`. The `main_token` field is the `!=` token. bang_equal, /// `lhs < rhs`. The `main_token` field is the `<` token. less_than, /// `lhs > rhs`. The `main_token` field is the `>` token. greater_than, /// `lhs <= rhs`. The `main_token` field is the `<=` token. less_or_equal, /// `lhs >= rhs`. The `main_token` field is the `>=` token. greater_or_equal, /// `lhs *= rhs`. The `main_token` field is the `*=` token. assign_mul, /// `lhs /= rhs`. The `main_token` field is the `/=` token. assign_div, /// `lhs %= rhs`. The `main_token` field is the `%=` token. assign_mod, /// `lhs += rhs`. The `main_token` field is the `+=` token. assign_add, /// `lhs -= rhs`. The `main_token` field is the `-=` token. assign_sub, /// `lhs <<= rhs`. The `main_token` field is the `<<=` token. assign_shl, /// `lhs <<|= rhs`. The `main_token` field is the `<<|=` token. assign_shl_sat, /// `lhs >>= rhs`. The `main_token` field is the `>>=` token. assign_shr, /// `lhs &= rhs`. The `main_token` field is the `&=` token. assign_bit_and, /// `lhs ^= rhs`. The `main_token` field is the `^=` token. assign_bit_xor, /// `lhs |= rhs`. The `main_token` field is the `|=` token. assign_bit_or, /// `lhs *%= rhs`. The `main_token` field is the `*%=` token. assign_mul_wrap, /// `lhs +%= rhs`. The `main_token` field is the `+%=` token. assign_add_wrap, /// `lhs -%= rhs`. The `main_token` field is the `-%=` token. assign_sub_wrap, /// `lhs *|= rhs`. The `main_token` field is the `*%=` token. assign_mul_sat, /// `lhs +|= rhs`. The `main_token` field is the `+|=` token. assign_add_sat, /// `lhs -|= rhs`. The `main_token` field is the `-|=` token. assign_sub_sat, /// `lhs = rhs`. The `main_token` field is the `=` token. assign, /// `a, b, ... = rhs`. /// /// The `data` field is a `.extra_and_node`: /// 1. a `ExtraIndex`. Further explained below. /// 2. a `Node.Index` to the initialization expression. /// /// The `main_token` field is the `=` token. /// /// The `ExtraIndex` stores the following data: /// ``` /// elem_count: u32, /// variables: [elem_count]Node.Index, /// ``` /// /// Each node in `variables` has one of the following tags: /// - `global_var_decl` /// - `local_var_decl` /// - `simple_var_decl` /// - `aligned_var_decl` /// - Any expression node /// /// The first 4 tags correspond to a `var` or `const` lhs node (note /// that their initialization expression is always `.none`). /// An expression node corresponds to a standard assignment LHS (which /// must be evaluated as an lvalue). There may be a preceding /// `comptime` token, which does not create a corresponding `comptime` /// node so must be manually detected. assign_destructure, /// `lhs || rhs`. The `main_token` field is the `||` token. merge_error_sets, /// `lhs * rhs`. The `main_token` field is the `*` token. mul, /// `lhs / rhs`. The `main_token` field is the `/` token. div, /// `lhs % rhs`. The `main_token` field is the `%` token. mod, /// `lhs ** rhs`. The `main_token` field is the `**` token. array_mult, /// `lhs *% rhs`. The `main_token` field is the `*%` token. mul_wrap, /// `lhs *| rhs`. The `main_token` field is the `*|` token. mul_sat, /// `lhs + rhs`. The `main_token` field is the `+` token. add, /// `lhs - rhs`. The `main_token` field is the `-` token. sub, /// `lhs ++ rhs`. The `main_token` field is the `++` token. array_cat, /// `lhs +% rhs`. The `main_token` field is the `+%` token. add_wrap, /// `lhs -% rhs`. The `main_token` field is the `-%` token. sub_wrap, /// `lhs +| rhs`. The `main_token` field is the `+|` token. add_sat, /// `lhs -| rhs`. The `main_token` field is the `-|` token. sub_sat, /// `lhs << rhs`. The `main_token` field is the `<<` token. shl, /// `lhs <<| rhs`. The `main_token` field is the `<<|` token. shl_sat, /// `lhs >> rhs`. The `main_token` field is the `>>` token. shr, /// `lhs & rhs`. The `main_token` field is the `&` token. bit_and, /// `lhs ^ rhs`. The `main_token` field is the `^` token. bit_xor, /// `lhs | rhs`. The `main_token` field is the `|` token. bit_or, /// `lhs orelse rhs`. The `main_token` field is the `orelse` token. @"orelse", /// `lhs and rhs`. The `main_token` field is the `and` token. bool_and, /// `lhs or rhs`. The `main_token` field is the `or` token. bool_or, /// `!expr`. The `main_token` field is the `!` token. bool_not, /// `-expr`. The `main_token` field is the `-` token. negation, /// `~expr`. The `main_token` field is the `~` token. bit_not, /// `-%expr`. The `main_token` field is the `-%` token. negation_wrap, /// `&expr`. The `main_token` field is the `&` token. address_of, /// `try expr`. The `main_token` field is the `try` token. @"try", /// `await expr`. The `main_token` field is the `await` token. @"await", /// `?expr`. The `main_token` field is the `?` token. optional_type, /// `[lhs]rhs`. The `main_token` field is the `[` token. array_type, /// `[lhs:a]b`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the length expression. /// 2. a `ExtraIndex` to `ArrayTypeSentinel`. /// /// The `main_token` field is the `[` token. array_type_sentinel, /// `[*]align(lhs) rhs`, /// `*align(lhs) rhs`, /// `[]rhs`. /// /// The `data` field is a `.opt_node_and_node`: /// 1. a `Node.OptionalIndex` to the alignment expression, if any. /// 2. a `Node.Index` to the element type expression. /// /// The `main_token` is the asterisk if a single item pointer or the /// lbracket if a slice, many-item pointer, or C-pointer. /// The `main_token` might be a ** token, which is shared with a /// parent/child pointer type and may require special handling. ptr_type_aligned, /// `[*:lhs]rhs`, /// `*rhs`, /// `[:lhs]rhs`. /// /// The `data` field is a `.opt_node_and_node`: /// 1. a `Node.OptionalIndex` to the sentinel expression, if any. /// 2. a `Node.Index` to the element type expression. /// /// The `main_token` is the asterisk if a single item pointer or the /// lbracket if a slice, many-item pointer, or C-pointer. /// The `main_token` might be a ** token, which is shared with a /// parent/child pointer type and may require special handling. ptr_type_sentinel, /// The `data` field is a `.opt_node_and_node`: /// 1. a `ExtraIndex` to `PtrType`. /// 2. a `Node.Index` to the element type expression. /// /// The `main_token` is the asterisk if a single item pointer or the /// lbracket if a slice, many-item pointer, or C-pointer. /// The `main_token` might be a ** token, which is shared with a /// parent/child pointer type and may require special handling. ptr_type, /// The `data` field is a `.opt_node_and_node`: /// 1. a `ExtraIndex` to `PtrTypeBitRange`. /// 2. a `Node.Index` to the element type expression. /// /// The `main_token` is the asterisk if a single item pointer or the /// lbracket if a slice, many-item pointer, or C-pointer. /// The `main_token` might be a ** token, which is shared with a /// parent/child pointer type and may require special handling. ptr_type_bit_range, /// `lhs[rhs..]` /// /// The `main_token` field is the `[` token. slice_open, /// `sliced[start..end]`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the sliced expression. /// 2. a `ExtraIndex` to `Slice`. /// /// The `main_token` field is the `[` token. slice, /// `sliced[start..end :sentinel]`, /// `sliced[start.. :sentinel]`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the sliced expression. /// 2. a `ExtraIndex` to `SliceSentinel`. /// /// The `main_token` field is the `[` token. slice_sentinel, /// `expr.*`. /// /// The `data` field is a `.node` to expr. /// /// The `main_token` field is the `*` token. deref, /// `lhs[rhs]`. /// /// The `main_token` field is the `[` token. array_access, /// `lhs{rhs}`. /// /// The `main_token` field is the `{` token. array_init_one, /// Same as `array_init_one` except there is known to be a trailing /// comma before the final rbrace. array_init_one_comma, /// `.{a}`, /// `.{a, b}`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first element. Never `.none` /// 2. a `Node.OptionalIndex` to the second element, if any. /// /// The `main_token` field is the `{` token. array_init_dot_two, /// Same as `array_init_dot_two` except there is known to be a trailing /// comma before the final rbrace. array_init_dot_two_comma, /// `.{a, b, c}`. /// /// The `data` field is a `.extra_range` that stores a `Node.Index` for /// each element. /// /// The `main_token` field is the `{` token. array_init_dot, /// Same as `array_init_dot` except there is known to be a trailing /// comma before the final rbrace. array_init_dot_comma, /// `a{b, c}`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the type expression. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each element. /// /// The `main_token` field is the `{` token. array_init, /// Same as `array_init` except there is known to be a trailing comma /// before the final rbrace. array_init_comma, /// `a{.x = b}`, `a{}`. /// /// The `data` field is a `.node_and_opt_node`: /// 1. a `Node.Index` to the type expression. /// 2. a `Node.OptionalIndex` to the first field initialization, if any. /// /// The `main_token` field is the `{` token. /// /// The field name is determined by looking at the tokens preceding the /// field initialization. struct_init_one, /// Same as `struct_init_one` except there is known to be a trailing comma /// before the final rbrace. struct_init_one_comma, /// `.{.x = a, .y = b}`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first field initialization. Never `.none` /// 2. a `Node.OptionalIndex` to the second field initialization, if any. /// /// The `main_token` field is the '{' token. /// /// The field name is determined by looking at the tokens preceding the /// field initialization. struct_init_dot_two, /// Same as `struct_init_dot_two` except there is known to be a trailing /// comma before the final rbrace. struct_init_dot_two_comma, /// `.{.x = a, .y = b, .z = c}`. /// /// The `data` field is a `.extra_range` that stores a `Node.Index` for /// each field initialization. /// /// The `main_token` field is the `{` token. /// /// The field name is determined by looking at the tokens preceding the /// field initialization. struct_init_dot, /// Same as `struct_init_dot` except there is known to be a trailing /// comma before the final rbrace. struct_init_dot_comma, /// `a{.x = b, .y = c}`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the type expression. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each field initialization. /// /// The `main_token` field is the `{` token. /// /// The field name is determined by looking at the tokens preceding the /// field initialization. struct_init, /// Same as `struct_init` except there is known to be a trailing comma /// before the final rbrace. struct_init_comma, /// `a(b)`, `a()`. /// /// The `data` field is a `.node_and_opt_node`: /// 1. a `Node.Index` to the function expression. /// 2. a `Node.OptionalIndex` to the first argument, if any. /// /// The `main_token` field is the `(` token. call_one, /// Same as `call_one` except there is known to be a trailing comma /// before the final rparen. call_one_comma, /// `async a(b)`, `async a()`. /// /// The `data` field is a `.node_and_opt_node`: /// 1. a `Node.Index` to the function expression. /// 2. a `Node.OptionalIndex` to the first argument, if any. /// /// The `main_token` field is the `(` token. async_call_one, /// Same as `async_call_one` except there is known to be a trailing /// comma before the final rparen. async_call_one_comma, /// `a(b, c, d)`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the function expression. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each argument. /// /// The `main_token` field is the `(` token. call, /// Same as `call` except there is known to be a trailing comma before /// the final rparen. call_comma, /// `async a(b, c, d)`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the function expression. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each argument. /// /// The `main_token` field is the `(` token. async_call, /// Same as `async_call` except there is known to be a trailing comma /// before the final rparen. async_call_comma, /// `switch(a) {}`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the switch operand. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each switch case. /// /// `The `main_token` field` is the identifier of a preceding label, if any; otherwise `switch`. @"switch", /// Same as `switch` except there is known to be a trailing comma before /// the final rbrace. switch_comma, /// `a => b`, /// `else => b`. /// /// The `data` field is a `.opt_node_and_node`: /// 1. a `Node.OptionalIndex` where `.none` means `else`. /// 2. a `Node.Index` to the target expression. /// /// The `main_token` field is the `=>` token. switch_case_one, /// Same as `switch_case_one` but the case is inline. switch_case_inline_one, /// `a, b, c => d`. /// /// The `data` field is a `.extra_and_node`: /// 1. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each switch item. /// 2. a `Node.Index` to the target expression. /// /// The `main_token` field is the `=>` token. switch_case, /// Same as `switch_case` but the case is inline. switch_case_inline, /// `lhs...rhs`. /// /// The `main_token` field is the `...` token. switch_range, /// `while (a) b`, /// `while (a) |x| b`. while_simple, /// `while (a) : (b) c`, /// `while (a) |x| : (b) c`. while_cont, /// `while (a) : (b) c else d`, /// `while (a) |x| : (b) c else d`, /// `while (a) |x| : (b) c else |y| d`. /// The continue expression part `: (b)` may be omitted. @"while", /// `for (a) b`. for_simple, /// `for (lhs[0..inputs]) lhs[inputs + 1] else lhs[inputs + 2]`. `For[rhs]`. @"for", /// `lhs..rhs`, `lhs..`. for_range, /// `if (a) b`. /// `if (b) |x| b`. if_simple, /// `if (a) b else c`. /// `if (a) |x| b else c`. /// `if (a) |x| b else |y| d`. @"if", /// `suspend expr`. /// /// The `data` field is a `.node` to expr. /// /// The `main_token` field is the `suspend` token. @"suspend", /// `resume expr`. /// /// The `data` field is a `.node` to expr. /// /// The `main_token` field is the `resume` token. @"resume", /// `continue :label expr`, /// `continue expr`, /// `continue :label`, /// `continue`. /// /// The `data` field is a `.opt_token_and_opt_node`: /// 1. a `OptionalTokenIndex` to the label identifier, if any. /// 2. a `Node.OptionalIndex` to the target expression, if any. /// /// The `main_token` field is the `continue` token. @"continue", /// `break :label expr`, /// `break expr`, /// `break :label`, /// `break`. /// /// The `data` field is a `.opt_token_and_opt_node`: /// 1. a `OptionalTokenIndex` to the label identifier, if any. /// 2. a `Node.OptionalIndex` to the target expression, if any. /// /// The `main_token` field is the `break` token. @"break", /// `return expr`, `return`. /// /// The `data` field is a `.opt_node` to the return value, if any. /// /// The `main_token` field is the `return` token. @"return", /// `fn (a: type_expr) return_type`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first parameter type expression, if any. /// 2. a `Node.OptionalIndex` to the return type expression. Can't be /// `.none` unless a parsing error occured. /// /// The `main_token` field is the `fn` token. /// /// `anytype` and `...` parameters are omitted from the AST tree. /// Extern function declarations use this tag. fn_proto_simple, /// `fn (a: b, c: d) return_type`. /// /// The `data` field is a `.extra_and_opt_node`: /// 1. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each parameter type expression. /// 2. a `Node.OptionalIndex` to the return type expression. Can't be /// `.none` unless a parsing error occured. /// /// The `main_token` field is the `fn` token. /// /// `anytype` and `...` parameters are omitted from the AST tree. /// Extern function declarations use this tag. fn_proto_multi, /// `fn (a: b) addrspace(e) linksection(f) callconv(g) return_type`. /// zero or one parameters. /// /// The `data` field is a `.extra_and_opt_node`: /// 1. a `Node.ExtraIndex` to `FnProtoOne`. /// 2. a `Node.OptionalIndex` to the return type expression. Can't be /// `.none` unless a parsing error occured. /// /// The `main_token` field is the `fn` token. /// /// `anytype` and `...` parameters are omitted from the AST tree. /// Extern function declarations use this tag. fn_proto_one, /// `fn (a: b, c: d) addrspace(e) linksection(f) callconv(g) return_type`. /// /// The `data` field is a `.extra_and_opt_node`: /// 1. a `Node.ExtraIndex` to `FnProto`. /// 2. a `Node.OptionalIndex` to the return type expression. Can't be /// `.none` unless a parsing error occured. /// /// The `main_token` field is the `fn` token. /// /// `anytype` and `...` parameters are omitted from the AST tree. /// Extern function declarations use this tag. fn_proto, /// Extern function declarations use the fn_proto tags rather than this one. /// /// The `data` field is a `.node_and_node`: /// 1. a `Node.Index` to `fn_proto_*`. /// 2. a `Node.Index` to function body block. /// /// The `main_token` field is the `fn` token. fn_decl, /// `anyframe->return_type`. /// /// The `data` field is a `.token_and_node`: /// 1. a `TokenIndex` to the `->` token. /// 2. a `Node.Index` to the function frame return type expression. /// /// The `main_token` field is the `anyframe` token. anyframe_type, /// The `data` field is unused. anyframe_literal, /// The `data` field is unused. char_literal, /// The `data` field is unused. number_literal, /// The `data` field is unused. unreachable_literal, /// The `data` field is unused. /// /// Most identifiers will not have explicit AST nodes, however for /// expressions which could be one of many different kinds of AST nodes, /// there will be an identifier AST node for it. identifier, /// `.foo`. /// /// The `data` field is unused. /// /// The `main_token` field is the identifier. enum_literal, /// The `data` field is unused. /// /// The `main_token` field is the string literal token. string_literal, /// The `data` field is a `.token_and_token`: /// 1. a `TokenIndex` to the first `.multiline_string_literal_line` token. /// 2. a `TokenIndex` to the last `.multiline_string_literal_line` token. /// /// The `main_token` field is the first token index (redundant with `data`). multiline_string_literal, /// `(expr)`. /// /// The `data` field is a `.node_and_token`: /// 1. a `Node.Index` to the sub-expression /// 2. a `TokenIndex` to the `)` token. /// /// The `main_token` field is the `(` token. grouped_expression, /// `@a(b, c)`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first argument, if any. /// 2. a `Node.OptionalIndex` to the second argument, if any. /// /// The `main_token` field is the builtin token. builtin_call_two, /// Same as `builtin_call_two` except there is known to be a trailing comma /// before the final rparen. builtin_call_two_comma, /// `@a(b, c, d)`. /// /// The `data` field is a `.extra_range` that stores a `Node.Index` for /// each argument. /// /// The `main_token` field is the builtin token. builtin_call, /// Same as `builtin_call` except there is known to be a trailing comma /// before the final rparen. builtin_call_comma, /// `error{a, b}`. /// /// The `data` field is a `.token_and_token`: /// 1. a `TokenIndex` to the `{` token. /// 2. a `TokenIndex` to the `}` token. /// /// The `main_token` field is the `error`. error_set_decl, /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. /// /// The `data` field is a `.extra_range` that stores a `Node.Index` for /// each container member. /// /// The `main_token` field is the `struct`, `union`, `opaque` or `enum` token. container_decl, /// Same as `container_decl` except there is known to be a trailing /// comma before the final rbrace. container_decl_trailing, /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first container member, if any. /// 2. a `Node.OptionalIndex` to the second container member, if any. /// /// The `main_token` field is the `struct`, `union`, `opaque` or `enum` token. container_decl_two, /// Same as `container_decl_two` except there is known to be a trailing /// comma before the final rbrace. container_decl_two_trailing, /// `struct(arg)`, `union(arg)`, `enum(arg)`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to arg. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each container member. /// /// The `main_token` field is the `struct`, `union` or `enum` token. container_decl_arg, /// Same as `container_decl_arg` except there is known to be a trailing /// comma before the final rbrace. container_decl_arg_trailing, /// `union(enum) {}`. /// /// The `data` field is a `.extra_range` that stores a `Node.Index` for /// each container member. /// /// The `main_token` field is the `union` token. /// /// A tagged union with explicitly provided enums will instead be /// represented by `container_decl_arg`. tagged_union, /// Same as `tagged_union` except there is known to be a trailing comma /// before the final rbrace. tagged_union_trailing, /// `union(enum) {lhs, rhs}`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first container member, if any. /// 2. a `Node.OptionalIndex` to the second container member, if any. /// /// The `main_token` field is the `union` token. /// /// A tagged union with explicitly provided enums will instead be /// represented by `container_decl_arg`. tagged_union_two, /// Same as `tagged_union_two` except there is known to be a trailing /// comma before the final rbrace. tagged_union_two_trailing, /// `union(enum(arg)) {}`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to arg. /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for /// each container member. /// /// The `main_token` field is the `union` token. tagged_union_enum_tag, /// Same as `tagged_union_enum_tag` except there is known to be a /// trailing comma before the final rbrace. tagged_union_enum_tag_trailing, /// `a: lhs = rhs,`, /// `a: lhs,`. /// /// The `data` field is a `.node_and_opt_node`: /// 1. a `Node.Index` to the field type expression. /// 2. a `Node.OptionalIndex` to the default value expression, if any. /// /// The `main_token` field is the field name identifier. /// /// `lastToken()` does not include the possible trailing comma. container_field_init, /// `a: lhs align(rhs),`. /// /// The `data` field is a `.node_and_node`: /// 1. a `Node.Index` to the field type expression. /// 2. a `Node.Index` to the alignment expression. /// /// The `main_token` field is the field name identifier. /// /// `lastToken()` does not include the possible trailing comma. container_field_align, /// `a: lhs align(c) = d,`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to the field type expression. /// 2. a `ExtraIndex` to `ContainerField`. /// /// The `main_token` field is the field name identifier. /// /// `lastToken()` does not include the possible trailing comma. container_field, /// `comptime expr`. /// /// The `data` field is a `.node` to expr. /// /// The `main_token` field is the `comptime` token. @"comptime", /// `nosuspend expr`. /// /// The `data` field is a `.node` to expr. /// /// The `main_token` field is the `nosuspend` token. @"nosuspend", /// `{lhs rhs}`. /// /// The `data` field is a `.opt_node_and_opt_node`: /// 1. a `Node.OptionalIndex` to the first statement, if any. /// 2. a `Node.OptionalIndex` to the second statement, if any. /// /// The `main_token` field is the `{` token. block_two, /// Same as `block_two` except there is known to be a trailing /// comma before the final rbrace. block_two_semicolon, /// `{a b}`. /// /// The `data` field is a `.extra_range` that stores a `Node.Index` for /// each statement. /// /// The `main_token` field is the `{` token. block, /// Same as `block` except there is known to be a trailing comma before /// the final rbrace. block_semicolon, /// `asm(lhs)`. /// /// rhs is a `Token.Index` to the `)` token. /// The `main_token` field is the `asm` token. asm_simple, /// `asm(lhs, a)`. /// /// The `data` field is a `.node_and_extra`: /// 1. a `Node.Index` to lhs. /// 2. a `ExtraIndex` to `Asm`. /// /// The `main_token` field is the `asm` token. @"asm", /// `[a] "b" (c)`. /// `[a] "b" (-> lhs)`. /// /// The `data` field is a `.opt_node_and_token`: /// 1. a `Node.OptionalIndex` to lhs, if any. /// 2. a `TokenIndex` to the `)` token. /// /// The `main_token` field is `a`. asm_output, /// `[a] "b" (lhs)`. /// /// The `data` field is a `.node_and_token`: /// 1. a `Node.Index` to lhs. /// 2. a `TokenIndex` to the `)` token. /// /// The `main_token` field is `a`. asm_input, /// `error.a`. /// /// The `data` field is unused. /// /// The `main_token` field is `error` token. error_value, /// `lhs!rhs`. /// /// The `main_token` field is the `!` token. error_union, pub fn isContainerField(tag: Tag) bool { return switch (tag) { .container_field_init, .container_field_align, .container_field, => true, else => false, }; } }; pub const Data = union { node: Index, opt_node: OptionalIndex, token: TokenIndex, node_and_node: struct { Index, Index }, opt_node_and_opt_node: struct { OptionalIndex, OptionalIndex }, node_and_opt_node: struct { Index, OptionalIndex }, opt_node_and_node: struct { OptionalIndex, Index }, node_and_extra: struct { Index, ExtraIndex }, extra_and_node: struct { ExtraIndex, Index }, extra_and_opt_node: struct { ExtraIndex, OptionalIndex }, node_and_token: struct { Index, TokenIndex }, token_and_node: struct { TokenIndex, Index }, token_and_token: struct { TokenIndex, TokenIndex }, opt_node_and_token: struct { OptionalIndex, TokenIndex }, opt_token_and_node: struct { OptionalTokenIndex, Index }, opt_token_and_opt_node: struct { OptionalTokenIndex, OptionalIndex }, opt_token_and_opt_token: struct { OptionalTokenIndex, OptionalTokenIndex }, @"for": struct { ExtraIndex, For }, extra_range: SubRange, }; pub const LocalVarDecl = struct { type_node: Index, align_node: Index, }; pub const ArrayTypeSentinel = struct { sentinel: Index, elem_type: Index, }; pub const PtrType = struct { sentinel: OptionalIndex, align_node: OptionalIndex, addrspace_node: OptionalIndex, }; pub const PtrTypeBitRange = struct { sentinel: OptionalIndex, align_node: Index, addrspace_node: OptionalIndex, bit_range_start: Index, bit_range_end: Index, }; pub const SubRange = struct { /// Index into extra_data. start: ExtraIndex, /// Index into extra_data. end: ExtraIndex, }; pub const If = struct { then_expr: Index, else_expr: Index, }; pub const ContainerField = struct { align_expr: Index, value_expr: Index, }; pub const GlobalVarDecl = struct { /// Populated if there is an explicit type ascription. type_node: OptionalIndex, /// Populated if align(A) is present. align_node: OptionalIndex, /// Populated if addrspace(A) is present. addrspace_node: OptionalIndex, /// Populated if linksection(A) is present. section_node: OptionalIndex, }; pub const Slice = struct { start: Index, end: Index, }; pub const SliceSentinel = struct { start: Index, /// May be .none if the slice is "open" end: OptionalIndex, sentinel: Index, }; pub const While = struct { cont_expr: OptionalIndex, then_expr: Index, else_expr: Index, }; pub const WhileCont = struct { cont_expr: Index, then_expr: Index, }; pub const For = packed struct(u32) { inputs: u31, has_else: bool, }; pub const FnProtoOne = struct { /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters. param: OptionalIndex, /// Populated if align(A) is present. align_expr: OptionalIndex, /// Populated if addrspace(A) is present. addrspace_expr: OptionalIndex, /// Populated if linksection(A) is present. section_expr: OptionalIndex, /// Populated if callconv(A) is present. callconv_expr: OptionalIndex, }; pub const FnProto = struct { params_start: ExtraIndex, params_end: ExtraIndex, /// Populated if align(A) is present. align_expr: OptionalIndex, /// Populated if addrspace(A) is present. addrspace_expr: OptionalIndex, /// Populated if linksection(A) is present. section_expr: OptionalIndex, /// Populated if callconv(A) is present. callconv_expr: OptionalIndex, }; pub const Asm = struct { items_start: ExtraIndex, items_end: ExtraIndex, /// Needed to make lastToken() work. rparen: TokenIndex, }; }