#ifndef __AST_H__ #define __AST_H__ #include "../../frontend.h" #include "../../lexer/lexer.h" #include "../../../../libcore/vector.h" #include "../type.h" typedef enum { NT_INIT, NT_ROOT, // global scope in root node NT_ADD, // (expr) + (expr) NT_SUB, // (expr) - (expr) NT_MUL, // (expr) * (expr) NT_DIV, // (expr) / (expr) NT_MOD, // (expr) % (expr) NT_AND, // (expr) & (expr) NT_OR, // (expr) | (expr) NT_XOR, // (expr) ^ (expr) NT_L_SH, // (expr) << (expr) NT_R_SH, // (expr) >> (expr) NT_EQ, // (expr) == (expr) NT_NEQ, // (expr) != (expr) NT_LE, // (expr) <= (expr) NT_GE, // (expr) >= (expr) NT_LT, // (expr) < (expr) NT_GT, // (expr) > (expr) NT_AND_AND, // (expr) && (expr) NT_OR_OR, // (expr) || (expr) NT_NOT, // ! (expr) NT_BIT_NOT, // ~ (expr) NT_COND, // (expr) ? (expr) : (expr) NT_COMMA, // expr, expr 逗号运算符 NT_ASSIGN, // (expr) = (expr) NT_ADDRESS, // &expr (取地址) NT_DEREF, // *expr (解引用) NT_INDEX, // arr[index] (数组访问) NT_MEMBER, // struct.member NT_PTR_MEMBER,// ptr->member NT_CAST, // (type)expr 强制类型转换 NT_SIZEOF, // sizeof(type|expr) // NT_ALIGNOF, // _Alignof(type) (C11) NT_STMT_EMPTY, // ; NT_STMT_IF, // if (cond) { ... } [else {...}] NT_STMT_WHILE, // while (cond) { ... } NT_STMT_DOWHILE, // do {...} while (cond) NT_STMT_FOR, // for (init; cond; iter) {...} NT_STMT_SWITCH, // switch (expr) { case ... } NT_STMT_BREAK, // break; NT_STMT_CONTINUE, // continue; NT_STMT_GOTO, // goto label; NT_STMT_CASE, // case const_expr: NT_STMT_DEFAULT, // default: NT_STMT_LABEL, // label: NT_STMT_BLOCK, // { ... } NT_STMT_RETURN, // return expr; NT_STMT_EXPR, // expr; NT_BLOCK, // NT_TYPE_BASE, // 基础类型节点 // NT_TYPE_PTR, // 指针类型 // NT_TYPE_ARRAY, // 数组类型 // NT_TYPE_FUNC, // 函数类型 // NT_TYPE_QUAL, // 限定符节点 NT_DECL_VAR, // type name; or type name = expr; NT_DECL_FUNC, // type func_name(param_list); NT_FUNC, // type func_name(param_list) {...} NT_PARAM, // 函数形参 NT_ARG_LIST, // 实参列表(需要与NT_CALL配合) NT_TERM_CALL, // func (expr) NT_TERM_VAL, NT_TERM_IDENT, NT_TERM_TYPE, } ast_type_t; typedef struct ASTNode { ast_type_t type; union { void *children[6]; struct { vector_header(children, struct ASTNode*); } root; struct { vector_header(children, struct ASTNode*); } block; struct { struct ASTNode* decl_node; tok_t tok; } syms; struct { vector_header(params, struct ASTNode*); } params; struct { struct ASTNode* name; struct ASTNode* params; struct ASTNode* func_decl; } call; struct { struct ASTNode *type; struct ASTNode *name; struct ASTNode *expr_stmt; // optional void* data; } decl_val; struct { struct ASTNode *ret; struct ASTNode *name; struct ASTNode *params; // array of params struct ASTNode *def; } decl_func; struct { struct ASTNode *decl; struct ASTNode *body; // optional void* data; } func; struct { struct ASTNode *left; struct ASTNode *right; struct ASTNode *optional; // optional } expr; struct { struct ASTNode *cond; struct ASTNode *if_stmt; struct ASTNode *else_stmt; // optional } if_stmt; struct { struct ASTNode *cond; struct ASTNode *body; } switch_stmt; struct { struct ASTNode *cond; struct ASTNode *body; } while_stmt; struct { struct ASTNode *body; struct ASTNode *cond; } do_while_stmt; struct { struct ASTNode *init; struct ASTNode *cond; // optional struct ASTNode *iter; // optional struct ASTNode *body; } for_stmt; struct { struct ASTNode *expr_stmt; // optional } return_stmt; struct { struct ASTNode *label; } goto_stmt; struct { struct ASTNode *label; } label_stmt; struct { struct ASTNode *block; } block_stmt; struct { struct ASTNode *expr_stmt; } expr_stmt; }; } ast_node_t; struct ASTNode* new_ast_node(void); void init_ast_node(struct ASTNode* node); void pnt_ast(struct ASTNode* node, int depth); typedef struct parser parser_t; typedef struct ASTNode* (*parse_func_t) (parser_t*); void parse_prog(parser_t* parser); ast_node_t* parse_decl(parser_t* parser); ast_node_t* parse_block(parser_t* parser); ast_node_t* parse_stmt(parser_t* parser); ast_node_t* parse_expr(parser_t* parser); ast_node_t* parse_type(parser_t* parser); ast_node_t* new_ast_ident_node(tok_t* tok); ast_node_t* expect_pop_ident(tok_buf_t* tokbuf); int peek_decl(tok_buf_t* tokbuf); #endif