#ifndef __SPL_AST_H__ #define __SPL_AST_H__ #include "../stage0/include/utils.h" #include "spl_dbg.h" #include "spl_lexer.h" #include "spl_tok.h" /* clang-format off */ #define SPL_AST_KIND_TABLE \ X(SPL_AST_NONE, V0, none) \ X(SPL_AST_ROOT, V0, root) \ X(SPL_AST_CONTAINER_MEMBERS, V0, container_members) \ X(SPL_AST_EXTERNAL_TAG_ITEM, V0, external_tag_item) \ X(SPL_AST_TAG_ITEM, V0, tag_item) \ X(SPL_AST_COMPTIME_DECL, V0, comptime_decl) \ X(SPL_AST_TOP_LEVEL_BLOCK, V0, top_level_block) \ X(SPL_AST_FN_DECL, V0, fn_decl) \ X(SPL_AST_VAR_DECL, V0, var_decl) \ X(SPL_AST_CONST_DECL, V0, const_decl) \ X(SPL_AST_TYPE_DECL, V0, type_decl) \ X(SPL_AST_MEMBER_DECL, V0, member_decl) \ X(SPL_AST_PARAM_DECL, V0, param_decl) \ X(SPL_AST_STATEMENT_RET, V0, statement_ret) \ X(SPL_AST_STATEMENT_BREAK, V0, statement_break) \ X(SPL_AST_STATEMENT_CONTINUE, V0, statement_continue) \ X(SPL_AST_STATEMENT_DEFER, V0, statement_defer) \ X(SPL_AST_STATEMENT_COMPTIME, V0, statement_comptime) \ X(SPL_AST_STATEMENT_DECL, V0, statement_decl) \ X(SPL_AST_STATEMENT_EXPR, V0, statement_expr) \ X(SPL_AST_AGGREGATE_MEMBER, V0, aggregate_member) \ X(SPL_AST_STRUCT_INIT_ITEM, V0, struct_init_item) \ X(SPL_AST_MATCH_ARM, V0, match_arm) \ X(SPL_AST_LABEL, V0, label) \ X(SPL_AST_EXPR_INT_LIT, V0, int_lit) \ X(SPL_AST_EXPR_FLOAT_LIT, V0, float_lit) \ X(SPL_AST_EXPR_CHAR_LIT, V0, char_lit) \ X(SPL_AST_EXPR_STRING_LIT, V0, string_lit) \ X(SPL_AST_EXPR_BOOL_LIT, V0, bool_lit) \ X(SPL_AST_EXPR_NULL_LIT, V0, null_lit) \ X(SPL_AST_EXPR_UNDEFINED_LIT, V0, undefined_lit) \ X(SPL_AST_EXPR_IDENT, V0, ident) \ X(SPL_AST_EXPR_UNARY, V0, unary) \ X(SPL_AST_EXPR_BINARY, V0, binary) \ X(SPL_AST_EXPR_CALL, V0, call) \ X(SPL_AST_EXPR_FIELD, V0, field) \ X(SPL_AST_EXPR_INDEX, V0, index) \ X(SPL_AST_EXPR_SLICE, V0, slice) \ X(SPL_AST_EXPR_CAST, V0, cast) \ X(SPL_AST_EXPR_TUPLE, V0, tuple) \ X(SPL_AST_EXPR_ARRAY_LIT, V0, array_literal) \ X(SPL_AST_EXPR_ANON_ARRAY_LIT, V0, anon_array_literal) \ X(SPL_AST_EXPR_AGGREGATE_LIT, V0, aggregate_literal) \ X(SPL_AST_EXPR_COMPTIME_CALL, V0, comptime_call) \ X(SPL_AST_EXPR_BLOCK, V0, block) \ X(SPL_AST_EXPR_IF, V0, if_expr) \ X(SPL_AST_EXPR_IFVAR, V0, ifvar_expr) \ X(SPL_AST_EXPR_WHILE, V0, while_expr) \ X(SPL_AST_EXPR_LOOP, V0, loop_expr) \ X(SPL_AST_EXPR_FOR, V0, for_expr) \ X(SPL_AST_EXPR_MATCH, V0, match_expr) \ X(SPL_AST_EXPR_FN_TYPE, V0, fn_type) \ X(SPL_AST_TYPE_PATH, V0, type_path) \ X(SPL_AST_TYPE_POINTER, V0, type_pointer) \ X(SPL_AST_TYPE_ARRAY, V0, type_array) \ X(SPL_AST_TYPE_SLICE, V0, type_slice) \ X(SPL_AST_TYPE_FN, V0, type_fn) \ X(SPL_AST_TYPE_PAREN, V0, type_paren) \ X(SPL_AST_TYPE_AGGREGATE, V0, type_aggregate) \ X(SPL_AST_TYPE_COMPTIME_CALL, V0, type_comptime_call) \ X(SPL_AST_PATTERN_IDENT, V0, pattern_ident) \ X(SPL_AST_PATTERN_UNDERSCORE, V0, pattern_underscore) \ X(SPL_AST_PATTERN_DOT, V0, pattern_dot) \ X(SPL_AST_PATTERN_TUPLE, V0, pattern_tuple) \ X(SPL_AST_PATTERN_LIST, V0, pattern_list) /* clang-format on */ typedef enum { #ifdef X #undef X #endif #define X(name, ...) name, SPL_AST_KIND_TABLE #undef X SPL_AST_COUNT, } spl_ast_node_kind_t; /* clang-format off */ #define SPL_BINARY_OP_TABLE \ X(SPL_OP_ASSIGN, 1, 'R', =) \ X(SPL_OP_ASSIGN_ADD, 1, 'R', +=) \ X(SPL_OP_ASSIGN_SUB, 1, 'R', -=) \ X(SPL_OP_ASSIGN_MUL, 1, 'R', *=) \ X(SPL_OP_ASSIGN_DIV, 1, 'R', /=) \ X(SPL_OP_ASSIGN_MOD, 1, 'R', %=) \ X(SPL_OP_ASSIGN_AND, 1, 'R', &=) \ X(SPL_OP_ASSIGN_OR, 1, 'R', |=) \ X(SPL_OP_ASSIGN_XOR, 1, 'R', ^=) \ X(SPL_OP_ASSIGN_LSHIFT, 1, 'R', <<=) \ X(SPL_OP_ASSIGN_RSHIFT, 1, 'R', >>=) \ X(SPL_OP_BOOL_OR, 2, 'L', ||) \ X(SPL_OP_BOOL_AND, 3, 'L', &&) \ X(SPL_OP_BIT_OR, 4, 'L', |) \ X(SPL_OP_BIT_XOR, 5, 'L', ^) \ X(SPL_OP_BIT_AND, 6, 'L', &) \ X(SPL_OP_CMP_EQ, 7, 'L', ==) \ X(SPL_OP_CMP_NE, 7, 'L', !=) \ X(SPL_OP_CMP_LE, 8, 'L', <=) \ X(SPL_OP_CMP_GE, 8, 'L', >=) \ X(SPL_OP_CMP_LT, 8, 'L', <) \ X(SPL_OP_CMP_GT, 8, 'L', >) \ X(SPL_OP_ARROW_LEFT, 9, 'L', <-) \ X(SPL_OP_ARROW_RIGHT, 9, 'L', ->) \ X(SPL_OP_ARROW_FAT_BOTH, 9, 'L', <=>) \ X(SPL_OP_ARROW_THIN_BOTH, 9, 'L', <->) \ X(SPL_OP_ARROW_FAT_RIGHT, 9, 'L', =>) \ X(SPL_OP_RANGE, 10, 'L', ..) \ X(SPL_OP_LSHIFT, 11, 'L', <<) \ X(SPL_OP_RSHIFT, 11, 'L', >>) \ X(SPL_OP_ADD, 12, 'L', +) \ X(SPL_OP_SUB, 12, 'L', -) \ X(SPL_OP_MUL, 13, 'L', *) \ X(SPL_OP_DIV, 13, 'L', /) \ X(SPL_OP_MOD, 13, 'L', %) /* clang-format on */ typedef enum { #ifdef X #undef X #endif #define X(name, ...) name, SPL_BINARY_OP_TABLE #undef X } spl_binary_op_t; typedef enum { SPL_UNARY_OP_MINUS, SPL_UNARY_OP_NOT, SPL_UNARY_OP_BIT_NOT, SPL_UNARY_OP_ADDRESS, } spl_unary_op_t; const char *spl_binary_op_name(spl_binary_op_t op); const char *spl_unary_op_name(spl_unary_op_t op); struct spl_ast_node; typedef struct spl_ast_node spl_ast_node_t; typedef usize spl_ast_node_ref_t; typedef VEC(spl_ast_node_ref_t) spl_ast_node_ref_vec_t; struct spl_ast_node { spl_ast_node_kind_t kind; spl_dbg_node_t dbg; union { usize resolved_def_id; usize resolved_type_id; }; union { /* SPL_AST_ROOT */ struct { spl_ast_node_ref_t members; /* container_members 节点 */ } root; /* SPL_AST_CONTAINER_MEMBERS */ struct { spl_ast_node_ref_vec_t external_tags; /* external_tag_item 节点列表 */ spl_ast_node_ref_vec_t declarations; } container_members; /* SPL_AST_FN_DECL */ struct { spl_ast_node_ref_vec_t tag_list; /* tag_item 节点 */ bool is_comptime; const char *name; spl_ast_node_ref_vec_t params; /* param_decl 节点 */ spl_ast_node_ref_t ret_type; /* 类型节点,可空 */ spl_ast_node_ref_t body; /* 表达式节点,可空表示仅声明 */ } fn_decl; /* SPL_AST_VAR_DECL / SPL_AST_CONST_DECL */ struct { spl_ast_node_ref_vec_t attr_list; spl_ast_node_ref_t pattern; /* 模式节点 */ spl_ast_node_ref_t type; /* 类型节点,可空 */ spl_ast_node_ref_t init_expr; /* 表达式节点,可空 */ } var_const_decl; /* SPL_AST_TYPE_DECL */ struct { spl_ast_node_ref_vec_t attr_list; const char *name; spl_ast_node_ref_t type_expr; /* 类型节点 */ } type_decl; /* SPL_AST_MEMBER_DECL */ struct { spl_ast_node_ref_vec_t attr_list; const char *name; spl_ast_node_ref_t type_expr; /* 可空 */ spl_ast_node_ref_t init_expr; /* 可空 */ } member_decl; /* SPL_AST_PARAM_DECL */ struct { spl_ast_node_ref_vec_t attr_list; const char *name; spl_ast_node_ref_t type_expr; } param_decl; /* SPL_AST_TAG_ITEM / SPL_AST_EXTERNAL_TAG_ITEM */ struct { bool is_at; /* true: @, false: # */ bool is_external; /* true: @!或#! */ const char *name; spl_ast_node_ref_vec_t args; } tag_item; /* SPL_AST_COMPTIME_DECL */ struct { spl_ast_node_ref_t body; /* block 或 expr 节点 */ } comptime_decl; /* SPL_AST_TOP_LEVEL_BLOCK */ struct { spl_ast_node_ref_vec_t tag_list; /* tag_item 节点列表 */ spl_ast_node_ref_t block; /* 表达式节点block */ } top_level_block; /* SPL_AST_STATEMENT_RET */ struct { spl_ast_node_ref_t expr; /* 可空 */ } statement_ret; /* SPL_AST_STATEMENT_BREAK */ struct { spl_ast_node_ref_t label; /* 可空 */ spl_ast_node_ref_t expr; /* 可空 */ } statement_break; /* SPL_AST_STATEMENT_CONTINUE */ struct { spl_ast_node_ref_t label; /* 可空 */ } statement_continue; /* SPL_AST_STATEMENT_DEFER */ struct { spl_ast_node_ref_t body; /* block 或 statement 节点 */ } statement_defer; /* SPL_AST_STATEMENT_COMPTIME */ struct { spl_ast_node_ref_t body; /* block 或 expr 节点 */ } statement_comptime; /* SPL_AST_STATEMENT_DECL */ struct { spl_ast_node_ref_t decl; /* var/const/type 声明节点 */ } statement_decl; /* SPL_AST_STATEMENT_EXPR */ struct { spl_ast_node_ref_t expr; } statement_expr; /* SPL_AST_AGGREGATE_MEMBER */ struct { spl_ast_node_ref_vec_t attr_list; const char *name; spl_ast_node_ref_t type_expr; /* 可空 */ spl_ast_node_ref_t init_expr; /* 可空 */ } aggregate_member; /* SPL_AST_STRUCT_INIT_ITEM */ struct { const char *name; spl_ast_node_ref_t expr; /* 可空 */ } struct_init_item; /* SPL_AST_MATCH_ARM */ struct { spl_ast_node_ref_t pattern; /* 模式节点 */ spl_ast_node_ref_t body; /* block 或 expr 节点 */ } match_arm; /* SPL_AST_LABEL */ struct { const char *name; } label; /* ---- 表达式子类型 ---- */ struct { isize val; } int_lit; struct { double val; } float_lit; struct { char val; } char_lit; struct { const char *data; } string_lit; struct { bool val; } bool_lit; /* null_lit, undefined_lit 无数据 */ struct { const char *name; } ident; struct { spl_unary_op_t op; spl_ast_node_ref_t operand; } unary; struct { spl_binary_op_t op; spl_ast_node_ref_t left; spl_ast_node_ref_t right; } binary; struct { spl_ast_node_ref_t callee; spl_ast_node_ref_vec_t args; } call; struct { spl_ast_node_ref_t obj; const char *field; } field; struct { spl_ast_node_ref_t obj; spl_ast_node_ref_t index; } index; struct { spl_ast_node_ref_t obj; spl_ast_node_ref_t begin; spl_ast_node_ref_t end; } slice; struct { spl_ast_node_ref_t expr; spl_ast_node_ref_t type; } cast; struct { spl_ast_node_ref_vec_t elems; } tuple; struct { bool has_len; isize len; bool is_underscore_len; spl_ast_node_ref_t elem_type; spl_ast_node_ref_vec_t elems; } array_literal; struct { spl_ast_node_ref_vec_t elems; } anon_array_literal; struct { const char *name; /* 可空,匿名时为 NULL */ spl_ast_node_ref_vec_t fields; /* struct_init_item 节点列表 */ } aggregate_literal; struct { const char *name; spl_ast_node_ref_vec_t args; } comptime_call; struct { spl_ast_node_ref_vec_t stmts; spl_ast_node_ref_t tail_expr; } block; struct { spl_ast_node_ref_t cond; spl_ast_node_ref_t then_block; spl_ast_node_ref_t else_branch; } if_expr; struct { spl_ast_node_ref_t var_decl; spl_ast_node_ref_t then_block; spl_ast_node_ref_t else_branch; } ifvar_expr; struct { spl_ast_node_ref_t label; spl_ast_node_ref_t cond; spl_ast_node_ref_t body; spl_ast_node_ref_t else_branch; } while_expr; struct { spl_ast_node_ref_t label; spl_ast_node_ref_t body; } loop_expr; struct { spl_ast_node_ref_t label; spl_ast_node_ref_vec_t iter_exprs; spl_ast_node_ref_vec_t idents; spl_ast_node_ref_t body; spl_ast_node_ref_t else_branch; } for_expr; struct { spl_ast_node_ref_t matched_expr; spl_ast_node_ref_vec_t arms; /* match_arm 节点 */ } match_expr; struct { bool is_comptime; spl_ast_node_ref_vec_t params; spl_ast_node_ref_t ret_type; } fn_type; /* ---- 类型子类型 ---- */ struct { const char *name; spl_ast_node_ref_vec_t generic_args; } type_path; struct { spl_ast_node_ref_t pointee; } type_pointer; struct { bool has_len; isize len; bool is_underscore_len; spl_ast_node_ref_t elem_type; } type_array; struct { spl_ast_node_ref_t elem_type; } type_slice; struct { bool is_comptime; spl_ast_node_ref_vec_t params; spl_ast_node_ref_t ret_type; } type_fn; struct { spl_ast_node_ref_vec_t types; } type_paren; struct { const char *kind_name; spl_ast_node_ref_vec_t members; /* aggregate_member 节点 */ } type_aggregate; struct { const char *name; spl_ast_node_ref_vec_t args; } type_comptime_call; /* ---- 模式子类型 ---- */ struct { const char *name; } pattern_ident; /* pattern_underscore 无数据 */ struct { const char *name; spl_ast_node_ref_t sub_pattern; } pattern_dot; struct { spl_ast_node_ref_vec_t patterns; } pattern_tuple; struct { spl_ast_node_ref_vec_t patterns; } pattern_list; }; }; typedef VEC(spl_ast_node_t) spl_ast_node_vec_t; typedef VEC(char *) spl_ast_cstr_ref_vec_t; typedef struct { int parsed; spl_tok_vec_t input; spl_ast_node_vec_t node_buckets; spl_ast_cstr_ref_vec_t str_buckets; spl_ast_node_ref_t root; } spl_ast_t; void spl_ast_init(spl_ast_t *ast, const spl_tok_vec_t *tok_vec /*move*/); void spl_ast_drop(spl_ast_t *ast); spl_ast_node_t *spl_ast_node(spl_ast_t *ast, spl_ast_node_ref_t node); const char *spl_ast_node_name(spl_ast_node_t *node); void spl_ast_parse(spl_ast_t *ast); void spl_ast_valid(spl_ast_t *ast); void spl_ast_dump(spl_ast_t *ast, spl_ast_node_ref_t node); #endif /* __SPL_AST_H__ */