Files
zig0/ast.h

606 lines
23 KiB
C

#ifndef _ZIG0_AST_H__
#define _ZIG0_AST_H__
#include <stdbool.h>
#include <stdint.h>
#include "common.h"
#include "tokenizer.h"
typedef enum {
/// sub_list[lhs...rhs]
AST_NODE_TAG_ROOT,
/// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
AST_NODE_TAG_USINGNAMESPACE,
/// lhs is test name token (must be string literal or identifier), if any.
/// rhs is the body node.
AST_NODE_TAG_TEST_DECL,
/// lhs is the index into extra_data.
/// rhs is the initialization expression, if any.
/// main_token is `var` or `const`.
AST_NODE_TAG_GLOBAL_VAR_DECL,
/// `var a: x align(y) = rhs`
/// lhs is the index into extra_data.
/// main_token is `var` or `const`.
AST_NODE_TAG_LOCAL_VAR_DECL,
/// `var a: lhs = rhs`. lhs and rhs may be unused.
/// Can be local or global.
/// main_token is `var` or `const`.
AST_NODE_TAG_SIMPLE_VAR_DECL,
/// `var a align(lhs) = rhs`. lhs and rhs may be unused.
/// Can be local or global.
/// main_token is `var` or `const`.
AST_NODE_TAG_ALIGNED_VAR_DECL,
/// lhs is the identifier token payload if any,
/// rhs is the deferred expression.
AST_NODE_TAG_AST_NODE_TAG_ERRDEFER,
/// lhs is unused.
/// rhs is the deferred expression.
AST_NODE_TAG_AST_NODE_TAG_DEFER,
/// lhs catch rhs
/// lhs catch |err| rhs
/// main_token is the `catch` keyword.
/// payload is determined by looking at the next token after the `catch` keyword.
AST_NODE_TAG_AST_NODE_TAG_CATCH,
/// `lhs.a`. main_token is the dot. rhs is the identifier token index.
AST_NODE_TAG_FIELD_ACCESS,
/// `lhs.?`. main_token is the dot. rhs is the `?` token index.
AST_NODE_TAG_UNWRAP_OPTIONAL,
/// `lhs == rhs`. main_token is op.
AST_NODE_TAG_EQUAL_EQUAL,
/// `lhs != rhs`. main_token is op.
AST_NODE_TAG_BANG_EQUAL,
/// `lhs < rhs`. main_token is op.
AST_NODE_TAG_LESS_THAN,
/// `lhs > rhs`. main_token is op.
AST_NODE_TAG_GREATER_THAN,
/// `lhs <= rhs`. main_token is op.
AST_NODE_TAG_LESS_OR_EQUAL,
/// `lhs >= rhs`. main_token is op.
AST_NODE_TAG_GREATER_OR_EQUAL,
/// `lhs *= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_MUL,
/// `lhs /= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_DIV,
/// `lhs %= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_MOD,
/// `lhs += rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_ADD,
/// `lhs -= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_SUB,
/// `lhs <<= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_SHL,
/// `lhs <<|= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_SHL_SAT,
/// `lhs >>= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_SHR,
/// `lhs &= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_BIT_AND,
/// `lhs ^= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_BIT_XOR,
/// `lhs |= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_BIT_OR,
/// `lhs *%= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_MUL_WRAP,
/// `lhs +%= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_ADD_WRAP,
/// `lhs -%= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_SUB_WRAP,
/// `lhs *|= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_MUL_SAT,
/// `lhs +|= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_ADD_SAT,
/// `lhs -|= rhs`. main_token is op.
AST_NODE_TAG_ASSIGN_SUB_SAT,
/// `lhs = rhs`. main_token is op.
AST_NODE_TAG_ASSIGN,
/// `a, b, ... = rhs`. main_token is op. lhs is index into `extra_data`
/// of an lhs elem count followed by an array of that many `Node.Index`,
/// with each node having one of the following types:
/// * `global_var_decl`
/// * `local_var_decl`
/// * `simple_var_decl`
/// * `aligned_var_decl`
/// * Any expression node
/// The first 3 types correspond to a `var` or `const` lhs node (note
/// that their `rhs` is always 0). 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.
AST_NODE_TAG_ASSIGN_DESTRUCTURE,
/// `lhs || rhs`. main_token is the `||`.
AST_NODE_TAG_MERGE_ERROR_SETS,
/// `lhs * rhs`. main_token is the `*`.
AST_NODE_TAG_MUL,
/// `lhs / rhs`. main_token is the `/`.
AST_NODE_TAG_DIV,
/// `lhs % rhs`. main_token is the `%`.
AST_NODE_TAG_MOD,
/// `lhs ** rhs`. main_token is the `**`.
AST_NODE_TAG_ARRAY_MULT,
/// `lhs *% rhs`. main_token is the `*%`.
AST_NODE_TAG_MUL_WRAP,
/// `lhs *| rhs`. main_token is the `*|`.
AST_NODE_TAG_MUL_SAT,
/// `lhs + rhs`. main_token is the `+`.
AST_NODE_TAG_ADD,
/// `lhs - rhs`. main_token is the `-`.
AST_NODE_TAG_SUB,
/// `lhs ++ rhs`. main_token is the `++`.
AST_NODE_TAG_ARRAY_CAT,
/// `lhs +% rhs`. main_token is the `+%`.
AST_NODE_TAG_ADD_WRAP,
/// `lhs -% rhs`. main_token is the `-%`.
AST_NODE_TAG_SUB_WRAP,
/// `lhs +| rhs`. main_token is the `+|`.
AST_NODE_TAG_ADD_SAT,
/// `lhs -| rhs`. main_token is the `-|`.
AST_NODE_TAG_SUB_SAT,
/// `lhs << rhs`. main_token is the `<<`.
AST_NODE_TAG_SHL,
/// `lhs <<| rhs`. main_token is the `<<|`.
AST_NODE_TAG_SHL_SAT,
/// `lhs >> rhs`. main_token is the `>>`.
AST_NODE_TAG_SHR,
/// `lhs & rhs`. main_token is the `&`.
AST_NODE_TAG_BIT_AND,
/// `lhs ^ rhs`. main_token is the `^`.
AST_NODE_TAG_BIT_XOR,
/// `lhs | rhs`. main_token is the `|`.
AST_NODE_TAG_BIT_OR,
/// `lhs orelse rhs`. main_token is the `orelse`.
AST_NODE_TAG_AST_NODE_TAG_ORELSE,
/// `lhs and rhs`. main_token is the `and`.
AST_NODE_TAG_BOOL_AND,
/// `lhs or rhs`. main_token is the `or`.
AST_NODE_TAG_BOOL_OR,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_BOOL_NOT,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_NEGATION,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_BIT_NOT,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_NEGATION_WRAP,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_ADDRESS_OF,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_AST_NODE_TAG_TRY,
/// `op lhs`. rhs unused. main_token is op.
AST_NODE_TAG_AST_NODE_TAG_AWAIT,
/// `?lhs`. rhs unused. main_token is the `?`.
AST_NODE_TAG_OPTIONAL_TYPE,
/// `[lhs]rhs`.
AST_NODE_TAG_ARRAY_TYPE,
/// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`.
AST_NODE_TAG_ARRAY_TYPE_SENTINEL,
/// `[*]align(lhs) rhs`. lhs can be omitted.
/// `*align(lhs) rhs`. lhs can be omitted.
/// `[]rhs`.
/// main_token is the asterisk if a single item pointer or the lbracket
/// if a slice, many-item pointer, or C-pointer
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
AST_NODE_TAG_PTR_TYPE_ALIGNED,
/// `[*:lhs]rhs`. lhs can be omitted.
/// `*rhs`.
/// `[:lhs]rhs`.
/// main_token is the asterisk if a single item pointer or the lbracket
/// if a slice, many-item pointer, or C-pointer
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
AST_NODE_TAG_PTR_TYPE_SENTINEL,
/// lhs is index into ptr_type. rhs is the element type expression.
/// main_token is the asterisk if a single item pointer or the lbracket
/// if a slice, many-item pointer, or C-pointer
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
AST_NODE_TAG_PTR_TYPE,
/// lhs is index into ptr_type_bit_range. rhs is the element type expression.
/// main_token is the asterisk if a single item pointer or the lbracket
/// if a slice, many-item pointer, or C-pointer
/// main_token might be a ** token, which is shared with a parent/child
/// pointer type and may require special handling.
AST_NODE_TAG_PTR_TYPE_BIT_RANGE,
/// `lhs[rhs..]`
/// main_token is the lbracket.
AST_NODE_TAG_SLICE_OPEN,
/// `lhs[b..c]`. rhs is index into Slice
/// main_token is the lbracket.
AST_NODE_TAG_SLICE,
/// `lhs[b..c :d]`. rhs is index into SliceSentinel. Slice end c can be omitted.
/// main_token is the lbracket.
AST_NODE_TAG_SLICE_SENTINEL,
/// `lhs.*`. rhs is unused.
AST_NODE_TAG_DEREF,
/// `lhs[rhs]`.
AST_NODE_TAG_ARRAY_ACCESS,
/// `lhs{rhs}`. rhs can be omitted.
AST_NODE_TAG_ARRAY_INIT_ONE,
/// `lhs{rhs,}`. rhs can *not* be omitted
AST_NODE_TAG_ARRAY_INIT_ONE_COMMA,
/// `.{lhs, rhs}`. lhs and rhs can be omitted.
AST_NODE_TAG_ARRAY_INIT_DOT_TWO,
/// Same as `array_init_dot_two` except there is known to be a trailing comma
/// before the final rbrace.
AST_NODE_TAG_ARRAY_INIT_DOT_TWO_COMMA,
/// `.{a, b}`. `sub_list[lhs..rhs]`.
AST_NODE_TAG_ARRAY_INIT_DOT,
/// Same as `array_init_dot` except there is known to be a trailing comma
/// before the final rbrace.
AST_NODE_TAG_ARRAY_INIT_DOT_COMMA,
/// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.
AST_NODE_TAG_ARRAY_INIT,
/// Same as `array_init` except there is known to be a trailing comma
/// before the final rbrace.
AST_NODE_TAG_ARRAY_INIT_COMMA,
/// `lhs{.a = rhs}`. rhs can be omitted making it empty.
/// main_token is the lbrace.
AST_NODE_TAG_STRUCT_INIT_ONE,
/// `lhs{.a = rhs,}`. rhs can *not* be omitted.
/// main_token is the lbrace.
AST_NODE_TAG_STRUCT_INIT_ONE_COMMA,
/// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted.
/// main_token is the lbrace.
/// No trailing comma before the rbrace.
AST_NODE_TAG_STRUCT_INIT_DOT_TWO,
/// Same as `struct_init_dot_two` except there is known to be a trailing comma
/// before the final rbrace.
AST_NODE_TAG_STRUCT_INIT_DOT_TWO_COMMA,
/// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`.
/// main_token is the lbrace.
AST_NODE_TAG_STRUCT_INIT_DOT,
/// Same as `struct_init_dot` except there is known to be a trailing comma
/// before the final rbrace.
AST_NODE_TAG_STRUCT_INIT_DOT_COMMA,
/// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`.
/// lhs can be omitted which means `.{.a = b, .c = d}`.
/// main_token is the lbrace.
AST_NODE_TAG_STRUCT_INIT,
/// Same as `struct_init` except there is known to be a trailing comma
/// before the final rbrace.
AST_NODE_TAG_STRUCT_INIT_COMMA,
/// `lhs(rhs)`. rhs can be omitted.
/// main_token is the lparen.
AST_NODE_TAG_CALL_ONE,
/// `lhs(rhs,)`. rhs can be omitted.
/// main_token is the lparen.
AST_NODE_TAG_CALL_ONE_COMMA,
/// `async lhs(rhs)`. rhs can be omitted.
AST_NODE_TAG_ASYNC_CALL_ONE,
/// `async lhs(rhs,)`.
AST_NODE_TAG_ASYNC_CALL_ONE_COMMA,
/// `lhs(a, b, c)`. `SubRange[rhs]`.
/// main_token is the `(`.
AST_NODE_TAG_CALL,
/// `lhs(a, b, c,)`. `SubRange[rhs]`.
/// main_token is the `(`.
AST_NODE_TAG_CALL_COMMA,
/// `async lhs(a, b, c)`. `SubRange[rhs]`.
/// main_token is the `(`.
AST_NODE_TAG_ASYNC_CALL,
/// `async lhs(a, b, c,)`. `SubRange[rhs]`.
/// main_token is the `(`.
AST_NODE_TAG_ASYNC_CALL_COMMA,
/// `switch(lhs) {}`. `SubRange[rhs]`.
/// `main_token` is the identifier of a preceding label, if any; otherwise `switch`.
AST_NODE_TAG_AST_NODE_TAG_SWITCH,
/// Same as switch except there is known to be a trailing comma
/// before the final rbrace
AST_NODE_TAG_SWITCH_COMMA,
/// `lhs => rhs`. If lhs is omitted it means `else`.
/// main_token is the `=>`
AST_NODE_TAG_SWITCH_CASE_ONE,
/// Same ast `switch_case_one` but the case is inline
AST_NODE_TAG_SWITCH_CASE_INLINE_ONE,
/// `a, b, c => rhs`. `SubRange[lhs]`.
/// main_token is the `=>`
AST_NODE_TAG_SWITCH_CASE,
/// Same ast `switch_case` but the case is inline
AST_NODE_TAG_SWITCH_CASE_INLINE,
/// `lhs...rhs`.
AST_NODE_TAG_SWITCH_RANGE,
/// `while (lhs) rhs`.
/// `while (lhs) |x| rhs`.
AST_NODE_TAG_WHILE_SIMPLE,
/// `while (lhs) : (a) b`. `WhileCont[rhs]`.
/// `while (lhs) : (a) b`. `WhileCont[rhs]`.
AST_NODE_TAG_WHILE_CONT,
/// `while (lhs) : (a) b else c`. `While[rhs]`.
/// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
/// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
/// The cont expression part `: (a)` may be omitted.
AST_NODE_TAG_AST_NODE_TAG_WHILE,
/// `for (lhs) rhs`.
AST_NODE_TAG_FOR_SIMPLE,
/// `for (lhs[0..inputs]) lhs[inputs + 1] else lhs[inputs + 2]`. `For[rhs]`.
AST_NODE_TAG_AST_NODE_TAG_AST_NODE_TAG_FOR,
/// `lhs..rhs`. rhs can be omitted.
AST_NODE_TAG_AST_NODE_TAG_FOR_RANGE,
/// `if (lhs) rhs`.
/// `if (lhs) |a| rhs`.
AST_NODE_TAG_IF_SIMPLE,
/// `if (lhs) a else b`. `If[rhs]`.
/// `if (lhs) |x| a else b`. `If[rhs]`.
/// `if (lhs) |x| a else |y| b`. `If[rhs]`.
AST_NODE_TAG_AST_NODE_TAG_AST_NODE_TAG_IF,
/// `suspend lhs`. lhs can be omitted. rhs is unused.
AST_NODE_TAG_AST_NODE_TAG_AST_NODE_TAG_SUSPEND,
/// `resume lhs`. rhs is unused.
AST_NODE_TAG_AST_NODE_TAG_AST_NODE_TAG_RESUME,
/// `continue :lhs rhs`
/// both lhs and rhs may be omitted.
AST_NODE_TAG_AST_NODE_TAG_AST_NODE_TAG_CONTINUE,
/// `break :lhs rhs`
/// both lhs and rhs may be omitted.
AST_NODE_TAG_AST_NODE_TAG_AST_NODE_TAG_BREAK,
/// `return lhs`. lhs can be omitted. rhs is unused.
AST_NODE_TAG_AST_NODE_TAG_RETURN,
/// `fn (a: lhs) rhs`. lhs can be omitted.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
AST_NODE_TAG_FN_PROTO_SIMPLE,
/// `fn (a: b, c: d) rhs`. `sub_range_list[lhs]`.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
AST_NODE_TAG_FN_PROTO_MULTI,
/// `fn (a: b) addrspace(e) linksection(f) callconv(g) rhs`. `FnProtoOne[lhs]`.
/// zero or one parameters.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
AST_NODE_TAG_FN_PROTO_ONE,
/// `fn (a: b, c: d) addrspace(e) linksection(f) callconv(g) rhs`. `FnProto[lhs]`.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
AST_NODE_TAG_FN_PROTO,
/// lhs is the fn_proto.
/// rhs is the function body block.
/// Note that extern function declarations use the fn_proto tags rather
/// than this one.
AST_NODE_TAG_FN_DECL,
/// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
AST_NODE_TAG_ANYFRAME_TYPE,
/// Both lhs and rhs unused.
AST_NODE_TAG_ANYFRAME_LITERAL,
/// Both lhs and rhs unused.
AST_NODE_TAG_CHAR_LITERAL,
/// Both lhs and rhs unused.
AST_NODE_TAG_NUMBER_LITERAL,
/// Both lhs and rhs unused.
AST_NODE_TAG_UNREACHABLE_LITERAL,
/// Both lhs and rhs 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.
AST_NODE_TAG_IDENTIFIER,
/// lhs is the dot token index, rhs unused, main_token is the identifier.
AST_NODE_TAG_ENUM_LITERAL,
/// main_token is the string literal token
/// Both lhs and rhs unused.
AST_NODE_TAG_STRING_LITERAL,
/// main_token is the first token index (redundant with lhs)
/// lhs is the first token index; rhs is the last token index.
/// Could be a series of multiline_string_literal_line tokens, or a single
/// string_literal token.
AST_NODE_TAG_MULTILINE_STRING_LITERAL,
/// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
AST_NODE_TAG_GROUPED_EXPRESSION,
/// `@a(lhs, rhs)`. lhs and rhs may be omitted.
/// main_token is the builtin token.
AST_NODE_TAG_BUILTIN_CALL_TWO,
/// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
AST_NODE_TAG_BUILTIN_CALL_TWO_COMMA,
/// `@a(b, c)`. `sub_list[lhs..rhs]`.
/// main_token is the builtin token.
AST_NODE_TAG_BUILTIN_CALL,
/// Same as builtin_call but there is known to be a trailing comma before the rparen.
AST_NODE_TAG_BUILTIN_CALL_COMMA,
/// `error{a, b}`.
/// rhs is the rbrace, lhs is unused.
AST_NODE_TAG_ERROR_SET_DECL,
/// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`.
/// main_token is `struct`, `union`, `opaque`, `enum` keyword.
AST_NODE_TAG_CONTAINER_DECL,
/// Same as ContainerDecl but there is known to be a trailing comma
/// or semicolon before the rbrace.
AST_NODE_TAG_CONTAINER_DECL_TRAILING,
/// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`.
/// lhs or rhs can be omitted.
/// main_token is `struct`, `union`, `opaque`, `enum` keyword.
AST_NODE_TAG_CONTAINER_DECL_TWO,
/// Same as ContainerDeclTwo except there is known to be a trailing comma
/// or semicolon before the rbrace.
AST_NODE_TAG_CONTAINER_DECL_TWO_TRAILING,
/// `struct(lhs)` / `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
AST_NODE_TAG_CONTAINER_DECL_ARG,
/// Same as container_decl_arg but there is known to be a trailing
/// comma or semicolon before the rbrace.
AST_NODE_TAG_CONTAINER_DECL_ARG_TRAILING,
/// `union(enum) {}`. `sub_list[lhs..rhs]`.
/// Note that tagged unions with explicitly provided enums are represented
/// by `container_decl_arg`.
AST_NODE_TAG_TAGGED_UNION,
/// Same as tagged_union but there is known to be a trailing comma
/// or semicolon before the rbrace.
AST_NODE_TAG_TAGGED_UNION_TRAILING,
/// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted.
/// Note that tagged unions with explicitly provided enums are represented
/// by `container_decl_arg`.
AST_NODE_TAG_TAGGED_UNION_TWO,
/// Same as tagged_union_two but there is known to be a trailing comma
/// or semicolon before the rbrace.
AST_NODE_TAG_TAGGED_UNION_TWO_TRAILING,
/// `union(enum(lhs)) {}`. `SubRange[rhs]`.
AST_NODE_TAG_TAGGED_UNION_ENUM_TAG,
/// Same as tagged_union_enum_tag but there is known to be a trailing comma
/// or semicolon before the rbrace.
AST_NODE_TAG_TAGGED_UNION_ENUM_TAG_TRAILING,
/// `a: lhs = rhs,`. lhs and rhs can be omitted.
/// main_token is the field name identifier.
/// lastToken() does not include the possible trailing comma.
AST_NODE_TAG_CONTAINER_FIELD_INIT,
/// `a: lhs align(rhs),`. rhs can be omitted.
/// main_token is the field name identifier.
/// lastToken() does not include the possible trailing comma.
AST_NODE_TAG_CONTAINER_FIELD_ALIGN,
/// `a: lhs align(c) = d,`. `container_field_list[rhs]`.
/// main_token is the field name identifier.
/// lastToken() does not include the possible trailing comma.
AST_NODE_TAG_CONTAINER_FIELD,
/// `comptime lhs`. rhs unused.
AST_NODE_TAG_COMPTIME,
/// `nosuspend lhs`. rhs unused.
AST_NODE_TAG_NOSUSPEND,
/// `{lhs rhs}`. rhs or lhs can be omitted.
/// main_token points at the lbrace.
AST_NODE_TAG_BLOCK_TWO,
/// Same as block_two but there is known to be a semicolon before the rbrace.
AST_NODE_TAG_BLOCK_TWO_SEMICOLON,
/// `{}`. `sub_list[lhs..rhs]`.
/// main_token points at the lbrace.
AST_NODE_TAG_BLOCK,
/// Same as block but there is known to be a semicolon before the rbrace.
AST_NODE_TAG_BLOCK_SEMICOLON,
/// `asm(lhs)`. rhs is the token index of the rparen.
AST_NODE_TAG_ASM_SIMPLE,
/// `asm(lhs, a)`. `Asm[rhs]`.
AST_NODE_TAG_ASM,
/// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen.
/// `[a] "b" (-> lhs)`. rhs is token index of the rparen.
/// main_token is `a`.
AST_NODE_TAG_ASM_OUTPUT,
/// `[a] "b" (lhs)`. rhs is token index of the rparen.
/// main_token is `a`.
AST_NODE_TAG_ASM_INPUT,
/// `error.a`. lhs is token index of `.`. rhs is token index of `a`.
AST_NODE_TAG_ERROR_VALUE,
/// `lhs!rhs`. main_token is the `!`.
AST_NODE_TAG_ERROR_UNION,
} AstNodeTag;
typedef uint32_t AstTokenIndex;
typedef uint32_t AstNodeIndex;
typedef uint32_t AstIndex;
typedef struct {
AstIndex lhs;
AstIndex rhs;
} AstData;
typedef struct {
uint32_t len;
uint32_t cap;
AstNodeTag* tags;
AstTokenIndex* main_tokens;
AstData* datas;
} AstNodeList;
typedef struct {
AstNodeTag tag;
AstTokenIndex main_token;
AstData data;
} AstNodeItem;
typedef struct {
uint32_t len;
uint32_t cap;
TokenizerTag* tags;
AstIndex* starts;
} AstTokenList;
typedef SLICE(AstNodeIndex) AstNodeIndexSlice;
typedef struct {
const char* source;
uint32_t source_len;
AstTokenList tokens;
AstNodeList nodes;
AstNodeIndexSlice extra_data;
} Ast;
typedef struct AstPtrType {
AstNodeIndex sentinel;
AstNodeIndex align_node;
AstNodeIndex addrspace_node;
} AstPtrType;
typedef struct AstPtrTypeBitRange {
AstNodeIndex sentinel;
AstNodeIndex align_node;
AstNodeIndex addrspace_node;
AstNodeIndex bit_range_start;
AstNodeIndex bit_range_end;
} AstPtrTypeBitRange;
typedef struct AstFnProtoOne {
AstNodeIndex param;
AstNodeIndex align_expr;
AstNodeIndex addrspace_expr;
AstNodeIndex section_expr;
AstNodeIndex callconv_expr;
} AstFnProtoOne;
typedef struct AstFnProto {
AstNodeIndex params_start;
AstNodeIndex params_end;
AstNodeIndex align_expr;
AstNodeIndex addrspace_expr;
AstNodeIndex section_expr;
AstNodeIndex callconv_expr;
} AstFnProto;
typedef struct AstSubRange {
AstNodeIndex start;
AstNodeIndex end;
} AstSubRange;
typedef struct AstSliceSentinel {
AstNodeIndex start;
AstNodeIndex end;
AstNodeIndex sentinel;
} AstSliceSentinel;
typedef struct AstWhileCont {
AstNodeIndex cont_expr;
AstNodeIndex then_expr;
} AstWhileCont;
typedef struct AstWhile {
AstNodeIndex cont_expr;
AstNodeIndex then_expr;
AstNodeIndex else_expr;
} AstWhile;
typedef struct AstFor {
unsigned int inputs : 31;
unsigned int has_else : 1;
} AstFor;
typedef struct AstIf {
AstNodeIndex then_expr;
AstNodeIndex else_expr;
} AstIf;
typedef struct AstError {
bool is_note;
AstTokenIndex token;
union {
struct {
TokenizerTag expected_tag;
} expected;
struct {
} none;
} extra;
} AstError;
Ast astParse(const char* source, uint32_t len);
AstNodeIndex astNodeListAppend(AstNodeList*, AstNodeItem);
void astTokenListAppend(AstTokenList* list, TokenizerTag tag, AstIndex start);
#endif