#ifndef __AST_H__ #define __AST_H__ #include #include "../lexer/lexer.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 ast_node { ast_type_t type; union { void *children[6]; struct { vector_header(children, struct ast_node *); } root; struct { vector_header(children, struct ast_node *); } block; struct { struct ast_node * decl_node; tok_t tok; } syms; struct { vector_header(params, struct ast_node *); } params; struct { struct ast_node * name; struct ast_node * params; struct ast_node * func_decl; } call; struct { struct ast_node *type; struct ast_node *name; struct ast_node *expr_stmt; // optional void* data; } decl_val; struct { struct ast_node *ret; struct ast_node *name; struct ast_node *params; // array of params struct ast_node *def; } decl_func; struct { struct ast_node *decl; struct ast_node *body; // optional void* data; } func; struct { struct ast_node *left; struct ast_node *right; struct ast_node *optional; // optional } expr; struct { struct ast_node *cond; struct ast_node *if_stmt; struct ast_node *else_stmt; // optional } if_stmt; struct { struct ast_node *cond; struct ast_node *body; } switch_stmt; struct { struct ast_node *cond; struct ast_node *body; } while_stmt; struct { struct ast_node *body; struct ast_node *cond; } do_while_stmt; struct { struct ast_node *init; struct ast_node *cond; // optional struct ast_node *iter; // optional struct ast_node *body; } for_stmt; struct { struct ast_node *expr_stmt; // optional } return_stmt; struct { struct ast_node *label; } goto_stmt; struct { struct ast_node *label; } label_stmt; struct { struct ast_node *block; } block_stmt; struct { struct ast_node *expr_stmt; } expr_stmt; }; } ast_node_t; ast_node_t* new_ast_node(void); void init_ast_node(ast_node_t* node); void pnt_ast(ast_node_t* node, int depth); typedef struct parser parser_t; typedef ast_node_t* (*parse_func_t) (parser_t*); void parse_prog(parser_t* parser); ast_node_t* parse_decl(parser_t* parser); ast_node_t* parse_decl_val(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_stream_t* tokbuf); int peek_decl(tok_stream_t* tokbuf); #endif