refactor: 重构前端代码并添加日志功能
- 重命名和重构了多个文件,包括 lexer、parser 和 AST 相关代码 - 添加了日志功能,使用 LOG_* 宏替代原有的 error 和 warn 函数 - 优化了错误处理和内存分配方式 - 调整了代码结构,提高了模块化和可读性
This commit is contained in:
		| @ -1,173 +0,0 @@ | ||||
| #include "ast.h" | ||||
| #include "../parser.h" | ||||
| struct ASTNode* new_ast_node(void) { | ||||
|     struct ASTNode* node = xmalloc(sizeof(struct ASTNode)); | ||||
|     init_ast_node(node); | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| void init_ast_node(struct ASTNode* node) { | ||||
|     node->type = NT_INIT; | ||||
|      | ||||
|     for (int i = 0; i < sizeof(node->children) / sizeof(node->children[0]); i++) { | ||||
|         node->children[i] = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // struct ASTNode* find_ast_node(struct ASTNode* node, ast_type_t type) { | ||||
|      | ||||
| // } | ||||
|  | ||||
| #include <stdio.h> | ||||
| static void pnt_depth(int depth) { | ||||
|     for (int i = 0; i < depth; i++) { | ||||
|         printf("  "); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // void pnt_ast(struct ASTNode* node, int depth) { | ||||
| //     if (!node) return; | ||||
| //     pnt_depth(depth); | ||||
| //     switch (node->type) { | ||||
| //         case NT_ROOT: | ||||
| //             for (int i = 0; i < node->root.child_size; i++) { | ||||
| //                 pnt_ast(node->root.children[i], depth); | ||||
| //             } | ||||
| //             return; | ||||
|  | ||||
| //         case NT_ADD     : printf("+ \n"); break; // (expr) + (expr) | ||||
| //         case NT_SUB     : printf("- \n"); break; // (expr) - (expr) | ||||
| //         case NT_MUL     : printf("* \n"); break; // (expr) * (expr) | ||||
| //         case NT_DIV     : printf("/ \n"); break; // (expr) / (expr) | ||||
| //         case NT_MOD     : printf("%%\n"); break; // (expr) % (expr) | ||||
| //         case NT_AND     : printf("& \n"); break; // (expr) & (expr) | ||||
| //         case NT_OR      : printf("| \n"); break; // (expr) | (expr) | ||||
| //         case NT_XOR     : printf("^ \n"); break; // (expr) ^ (expr) | ||||
| //         case NT_L_SH    : printf("<<\n"); break; // (expr) << (expr) | ||||
| //         case NT_R_SH    : printf(">>\n"); break; // (expr) >> (expr) | ||||
| //         case NT_EQ      : printf("==\n"); break; // (expr) == (expr) | ||||
| //         case NT_NEQ     : printf("!=\n"); break; // (expr) != (expr) | ||||
| //         case NT_LE      : printf("<=\n"); break; // (expr) <= (expr) | ||||
| //         case NT_GE      : printf(">=\n"); break; // (expr) >= (expr) | ||||
| //         case NT_LT      : printf("< \n"); break; // (expr) < (expr) | ||||
| //         case NT_GT      : printf("> \n"); break; // (expr) > (expr) | ||||
| //         case NT_AND_AND : printf("&&\n"); break; // (expr) && (expr) | ||||
| //         case NT_OR_OR   : printf("||\n"); break; // (expr) || (expr) | ||||
| //         case NT_NOT     : printf("! \n"); break; // ! (expr) | ||||
| //         case NT_BIT_NOT : printf("~ \n"); break; // ~ (expr) | ||||
| //         case NT_COMMA   : printf(", \n"); break; // expr, expr 逗号运算符 | ||||
| //         case NT_ASSIGN  : printf("= \n"); break; // (expr) = (expr) | ||||
| //         // case NT_COND    : // (expr) ? (expr) : (expr) | ||||
|          | ||||
| //         case NT_STMT_EMPTY    : // ; | ||||
| //             printf(";\n"); | ||||
| //             break; | ||||
| //         case NT_STMT_IF       : // if (cond) { ... } [else {...}] | ||||
| //             printf("if"); | ||||
| //             pnt_ast(node->if_stmt.cond, depth+1); | ||||
| //             pnt_ast(node->if_stmt.if_stmt, depth+1); | ||||
| //             if (node->if_stmt.else_stmt) { | ||||
| //                 pnt_depth(depth); | ||||
| //                 printf("else"); | ||||
| //                 pnt_ast(node->if_stmt.else_stmt, depth+1);             | ||||
| //             } | ||||
| //             break; | ||||
| //         case NT_STMT_WHILE    : // while (cond) { ... } | ||||
| //             printf("while\n"); | ||||
| //             pnt_ast(node->while_stmt.cond, depth+1); | ||||
| //             pnt_ast(node->while_stmt.body, depth+1); | ||||
| //             break; | ||||
| //         case NT_STMT_DOWHILE  : // do {...} while (cond) | ||||
| //             printf("do-while\n"); | ||||
| //             pnt_ast(node->do_while_stmt.body, depth+1); | ||||
| //             pnt_ast(node->do_while_stmt.cond, depth+1); | ||||
| //             break; | ||||
| //         case NT_STMT_FOR      : // for (init; cond; iter) {...} | ||||
| //             printf("for\n"); | ||||
| //             if (node->for_stmt.init) | ||||
| //                 pnt_ast(node->for_stmt.init, depth+1); | ||||
| //             if (node->for_stmt.cond) | ||||
| //                 pnt_ast(node->for_stmt.cond, depth+1); | ||||
| //             if (node->for_stmt.iter) | ||||
| //                 pnt_ast(node->for_stmt.iter, depth+1); | ||||
| //             pnt_ast(node->for_stmt.body, depth+1); | ||||
| //             break; | ||||
| //         case NT_STMT_SWITCH   : // switch (expr) { case ... } | ||||
| //         case NT_STMT_BREAK    : // break; | ||||
| //         case NT_STMT_CONTINUE : // continue; | ||||
| //         case NT_STMT_GOTO     : // goto label; | ||||
| //         case NT_STMT_CASE     : // case const_expr: | ||||
| //         case NT_STMT_DEFAULT  : // default: | ||||
| //         case NT_STMT_LABEL    : // label: | ||||
| //             break; | ||||
| //         case NT_STMT_BLOCK    : // { ... } | ||||
| //             printf("{\n"); | ||||
| //             for (int i = 0; i < node->block.child_size; i++) { | ||||
| //                 pnt_ast(node->block.children[i], depth+1); | ||||
| //             } | ||||
| //             pnt_depth(depth); | ||||
| //             printf("}\n"); | ||||
| //             break; | ||||
| //         case NT_STMT_RETURN   : // return expr; | ||||
| //             printf("return"); | ||||
| //             if (node->return_stmt.expr_stmt) { | ||||
| //                 printf(" "); | ||||
| //                 pnt_ast(node->return_stmt.expr_stmt, depth+1); | ||||
| //             } else { | ||||
| //                 printf("\n"); | ||||
| //             } | ||||
| //             break; | ||||
| //         case NT_STMT_EXPR     : // expr; | ||||
| //             printf("stmt\n"); | ||||
| //             pnt_ast(node->expr_stmt.expr_stmt, depth); | ||||
| //             pnt_depth(depth); | ||||
| //             printf(";\n"); | ||||
| //             break; | ||||
| //         case NT_DECL_VAR : // type name; or type name = expr; | ||||
| //             printf("decl_val\n"); | ||||
| //             break; | ||||
| //         case NT_DECL_FUNC: // type func_name(param_list); | ||||
| //             printf("decl func %s\n", node->func.name->syms.tok.val.str); | ||||
| //             break; | ||||
| //         case NT_FUNC      : // type func_name(param_list) {...} | ||||
| //             printf("def func %s\n", node->func.name->syms.tok.val.str); | ||||
| //             // pnt_ast(node->child.func.params, depth); | ||||
| //             pnt_ast(node->func.body, depth); | ||||
| //             // pnt_ast(node->child.func.ret, depth); | ||||
| //             break; | ||||
| //         case NT_PARAM     : // 函数形参 | ||||
| //             printf("param\n"); | ||||
| //         case NT_ARG_LIST  : // 实参列表(需要与NT_CALL配合) | ||||
| //             printf("arg_list\n"); | ||||
| //         case NT_TERM_CALL      : // func (expr) | ||||
| //             printf("call\n"); | ||||
| //             break; | ||||
| //         case NT_TERM_IDENT: | ||||
| //             printf("%s\n", node->syms.tok.val.str); | ||||
| //             break; | ||||
| //         case NT_TERM_VAL : // Terminal Symbols like constant, identifier, keyword | ||||
| //             tok_t * tok = &node->syms.tok; | ||||
| //             switch (tok->type) { | ||||
| //                 case TOKEN_CHAR_LITERAL: | ||||
| //                     printf("%c\n", tok->val.ch); | ||||
| //                     break; | ||||
| //                 case TOKEN_INT_LITERAL: | ||||
| //                     printf("%d\n", tok->val.i); | ||||
| //                     break; | ||||
| //                 case TOKEN_STRING_LITERAL: | ||||
| //                     printf("%s\n", tok->val.str); | ||||
| //                     break; | ||||
| //                 default: | ||||
| //                     printf("unknown term val\n"); | ||||
| //                     break; | ||||
| //             } | ||||
| //         default: | ||||
| //             break; | ||||
| //     } | ||||
|      | ||||
| //     // 通用子节点递归处理 | ||||
| //     if (node->type <= NT_ASSIGN) { // 表达式类统一处理子节点 | ||||
| //         if (node->expr.left) pnt_ast(node->expr.left, depth+1); | ||||
| //         if (node->expr.right) pnt_ast(node->expr.right, depth + 1); | ||||
| //     } | ||||
| // } | ||||
| @ -1,189 +0,0 @@ | ||||
| #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_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_buf_t* tokbuf); | ||||
|  | ||||
| int peek_decl(tok_buf_t* tokbuf); | ||||
|  | ||||
| #endif | ||||
| @ -1,5 +1,5 @@ | ||||
|  | ||||
| #include "ast.h" | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "../symtab/symtab.h" | ||||
|  | ||||
| @ -17,7 +17,7 @@ ast_node_t* new_ast_node_block() { | ||||
|  | ||||
| ast_node_t* parse_block(parser_t* parser) { | ||||
|     symtab_enter_scope(parser->symtab); | ||||
|     tok_buf_t *tokbuf = &parser->tokbuf; | ||||
|     tok_stream_t *tokbuf = &parser->tokbuf; | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype; | ||||
|     ast_node_t* node = new_ast_node_block(); | ||||
|  | ||||
| @ -1,19 +1,19 @@ | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "ast.h" | ||||
| #include "../symtab/symtab.h" | ||||
|  | ||||
| /** | ||||
|  * 0 false | ||||
|  * 1 true | ||||
|  */ | ||||
| int peek_decl(tok_buf_t* tokbuf) { | ||||
| int peek_decl(tok_stream_t* tokbuf) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|     switch (peek_tok_type(tokbuf)) { | ||||
|         case TOKEN_STATIC: | ||||
|         case TOKEN_EXTERN: | ||||
|         case TOKEN_REGISTER: | ||||
|         case TOKEN_TYPEDEF: | ||||
|             error("not impliment"); | ||||
|             LOG_ERROR("not impliment"); | ||||
|             break; | ||||
|         default: | ||||
|             flush_peek_tok(tokbuf); | ||||
| @ -36,7 +36,7 @@ int peek_decl(tok_buf_t* tokbuf) { | ||||
| } | ||||
|  | ||||
| ast_node_t* parse_decl_val(parser_t* parser) { | ||||
|     tok_buf_t* tokbuf = &parser->tokbuf; | ||||
|     tok_stream_t* tokbuf = &parser->tokbuf; | ||||
|     tok_type_t ttype; | ||||
|     flush_peek_tok(tokbuf); | ||||
|  | ||||
| @ -55,28 +55,28 @@ ast_node_t* parse_decl_val(parser_t* parser) { | ||||
|     if (ttype == TOKEN_ASSIGN) { | ||||
|         node->decl_val.expr_stmt = parse_stmt(parser); | ||||
|         if (node->decl_val.expr_stmt->type != NT_STMT_EXPR) { | ||||
|             error("parser_decl_val want stmt_expr"); | ||||
|             LOG_ERROR("parser_decl_val want stmt_expr"); | ||||
|         } | ||||
|     } else if (ttype == TOKEN_SEMICOLON) { | ||||
|         pop_tok(tokbuf); | ||||
|         expect_pop_tok(tokbuf, TOKEN_SEMICOLON); | ||||
|     } else { | ||||
|         error("parser_decl_val syntax error"); | ||||
|         LOG_ERROR("parser_decl_val syntax error"); | ||||
|     } | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| ast_node_t* parse_decl(parser_t* parser) { | ||||
|     tok_buf_t* tokbuf = &parser->tokbuf; | ||||
|     tok_stream_t* tokbuf = &parser->tokbuf; | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype; | ||||
|     ast_node_t* node; | ||||
|      | ||||
|     if (peek_decl(tokbuf) == 0) { | ||||
|         error("syntax error expect decl_val TYPE"); | ||||
|         LOG_ERROR("syntax error expect decl_val TYPE"); | ||||
|     } | ||||
|     if (peek_tok_type(tokbuf) != TOKEN_IDENT) { | ||||
|         error("syntax error expect decl_val IDENT"); | ||||
|         LOG_ERROR("syntax error expect decl_val IDENT"); | ||||
|     } | ||||
|  | ||||
|     ttype = peek_tok_type(tokbuf); | ||||
| @ -89,7 +89,7 @@ ast_node_t* parse_decl(parser_t* parser) { | ||||
|             node = parse_decl_val(parser); | ||||
|             break; | ||||
|         default: | ||||
|             error("syntax error expect decl_val ASSIGN or SEMICOLON"); | ||||
|             LOG_ERROR("syntax error expect decl_val ASSIGN or SEMICOLON"); | ||||
|             return NULL; | ||||
|     } | ||||
|     return node; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "ast.h" | ||||
| #include "../symtab/symtab.h" | ||||
|  | ||||
| // Copy from `CParse` | ||||
| @ -33,7 +33,7 @@ enum ParseType { | ||||
|     PREFIX_PARSER, | ||||
| }; | ||||
|  | ||||
| static ast_node_t *parse_subexpression(tok_buf_t* tokbuf, symtab_t *symtab, enum Precedence prec); | ||||
| static ast_node_t *parse_subexpression(tok_stream_t* tokbuf, symtab_t *symtab, enum Precedence prec); | ||||
| #define NEXT(prec) parse_subexpression(tokbuf, symtab, prec) | ||||
|  | ||||
| static ast_node_t* gen_node2(ast_node_t* left, ast_node_t* right, | ||||
| @ -72,7 +72,7 @@ static ast_node_t* gen_node2(ast_node_t* left, ast_node_t* right, | ||||
|     // } | ||||
| } | ||||
|  | ||||
| static ast_node_t* parse_comma(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
| static ast_node_t* parse_comma(tok_stream_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
|     ast_node_t* node = new_ast_node(); | ||||
|     node->type = NT_COMMA; | ||||
|     node->expr.left = left; | ||||
| @ -80,7 +80,7 @@ static ast_node_t* parse_comma(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| static ast_node_t* parse_assign(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
| static ast_node_t* parse_assign(tok_stream_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype = peek_tok_type(tokbuf); | ||||
|     pop_tok(tokbuf); | ||||
| @ -124,14 +124,14 @@ static ast_node_t* parse_assign(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* | ||||
|             left = gen_node2(left, NEXT(next), NT_XOR); | ||||
|             break; | ||||
|         default: | ||||
|             error("unsupported operator"); | ||||
|             LOG_ERROR("unsupported operator"); | ||||
|             break; | ||||
|     } | ||||
|     node->expr.right = left; | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| static ast_node_t* parse_cmp(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
| static ast_node_t* parse_cmp(tok_stream_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype = peek_tok_type(tokbuf); | ||||
|     pop_tok(tokbuf); | ||||
| @ -164,12 +164,12 @@ static ast_node_t* parse_cmp(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* le | ||||
|             node->expr.right = NEXT(PREC_RELATIONAL); | ||||
|             break; | ||||
|         default: | ||||
|             error("invalid operator"); | ||||
|             LOG_ERROR("invalid operator"); | ||||
|     } | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| static ast_node_t* parse_cal(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
| static ast_node_t* parse_cal(tok_stream_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype = peek_tok_type(tokbuf); | ||||
|     pop_tok(tokbuf); | ||||
| @ -230,7 +230,7 @@ static ast_node_t* parse_cal(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* le | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| static ast_node_t* parse_call(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* ident) { | ||||
| static ast_node_t* parse_call(tok_stream_t* tokbuf, symtab_t *symtab, ast_node_t* ident) { | ||||
|     ast_node_t* node = new_ast_node(); | ||||
|     node->type = NT_TERM_CALL; | ||||
|     node->call.name = ident; | ||||
| @ -257,14 +257,14 @@ static ast_node_t* parse_call(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* i | ||||
|     ast_node_t* sym = symtab_lookup_symbol(symtab, name); | ||||
|     // TODO check func is match | ||||
|     if (sym == NULL || sym->type != NT_DECL_FUNC) { | ||||
|         error("function not decl %s", name); | ||||
|         LOG_ERROR("function not decl %s", name); | ||||
|     } | ||||
|     node->call.name = ident; | ||||
|     node->call.func_decl = sym; | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| static ast_node_t* parse_paren(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
| static ast_node_t* parse_paren(tok_stream_t* tokbuf, symtab_t *symtab, ast_node_t* left) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|     expect_pop_tok(tokbuf, TOKEN_L_PAREN); | ||||
|     left = NEXT(PREC_EXPRESSION); | ||||
| @ -273,7 +273,7 @@ static ast_node_t* parse_paren(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* | ||||
|     return left; | ||||
| } | ||||
|  | ||||
| typedef ast_node_t* (*parse_expr_fun_t)(tok_buf_t*, symtab_t* , ast_node_t*); | ||||
| typedef ast_node_t* (*parse_expr_fun_t)(tok_stream_t*, symtab_t* , ast_node_t*); | ||||
| static struct expr_prec_table_t { | ||||
|     parse_expr_fun_t parser; | ||||
|     enum Precedence prec; | ||||
| @ -322,7 +322,7 @@ static struct expr_prec_table_t { | ||||
|     [TOKEN_L_PAREN] = {parse_paren, PREC_POSTFIX, INFIX_PARSER}, | ||||
| }; | ||||
|  | ||||
| static ast_node_t *parse_primary_expression(tok_buf_t* tokbuf, symtab_t *symtab) { | ||||
| static ast_node_t *parse_primary_expression(tok_stream_t* tokbuf, symtab_t *symtab) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|  | ||||
|     tok_t* tok = peek_tok(tokbuf); | ||||
| @ -335,7 +335,7 @@ static ast_node_t *parse_primary_expression(tok_buf_t* tokbuf, symtab_t *symtab) | ||||
|         // node->data.data_type = TYPE_INT; | ||||
|         break; | ||||
|     case TOKEN_FLOAT_LITERAL: | ||||
|         warn("float not supported"); | ||||
|         LOG_WARN("float not supported"); | ||||
|         break; | ||||
|     case TOKEN_CHAR_LITERAL: | ||||
|         // node->data.data_type = TYPE_CHAR; | ||||
| @ -350,7 +350,7 @@ static ast_node_t *parse_primary_expression(tok_buf_t* tokbuf, symtab_t *symtab) | ||||
|         } else { | ||||
|             void *sym = symtab_lookup_symbol(symtab, tok->val.str); | ||||
|             if (sym == NULL) { | ||||
|                 error("undefined symbol but use %s", tok->val.str); | ||||
|                 LOG_ERROR("undefined symbol but use %s", tok->val.str); | ||||
|             } | ||||
|             node->type = NT_TERM_IDENT; | ||||
|             node->syms.decl_node = sym; | ||||
| @ -364,7 +364,7 @@ END: | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| static ast_node_t *parse_subexpression(tok_buf_t* tokbuf, symtab_t *symtab, enum Precedence prec) { | ||||
| static ast_node_t *parse_subexpression(tok_stream_t* tokbuf, symtab_t *symtab, enum Precedence prec) { | ||||
|     tok_type_t                  ttype; | ||||
|     struct expr_prec_table_t*   work; | ||||
|     ast_node_t*                 left; | ||||
| @ -397,7 +397,7 @@ static ast_node_t *parse_subexpression(tok_buf_t* tokbuf, symtab_t *symtab, enum | ||||
| } | ||||
|  | ||||
| ast_node_t* parse_expr(parser_t* parser) { | ||||
|     tok_buf_t* tokbuf = &(parser->tokbuf); | ||||
|     tok_stream_t* tokbuf = &(parser->tokbuf); | ||||
|     symtab_t *symtab = parser->symtab; | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype = peek_tok_type(tokbuf); | ||||
| @ -419,7 +419,7 @@ ast_node_t* parse_expr(parser_t* parser) { | ||||
|     case TOKEN_IDENT: | ||||
|         return NEXT(PREC_EXPRESSION); | ||||
|     default: | ||||
|         error("Want expr but not got %s", get_tok_name(ttype)); | ||||
|         LOG_ERROR("Want expr but not got %s", get_tok_name(ttype)); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "../symtab/symtab.h" | ||||
| #include "ast.h" | ||||
|  | ||||
| #ifndef FUNC_PARAM_CACHE_SIZE | ||||
| #define FUNC_PARAM_CACHE_SIZE 32  // 合理初始值,可覆盖99%常见情况 | ||||
| #endif | ||||
|  | ||||
| // TODO 语义分析压入符号表 | ||||
| static void parse_params(parser_t* parser, tok_buf_t* cache, ast_node_t* node) { | ||||
| static void parse_params(parser_t* parser, tok_stream_t* cache, ast_node_t* node) { | ||||
|     flush_peek_tok(cache); | ||||
|     tok_type_t ttype; | ||||
|     ast_node_t *params = new_ast_node(); | ||||
| @ -23,10 +23,10 @@ static void parse_params(parser_t* parser, tok_buf_t* cache, ast_node_t* node) { | ||||
|         case TOKEN_ELLIPSIS: | ||||
|             ttype = peek_tok_type(cache); | ||||
|             if (ttype != TOKEN_R_PAREN) { | ||||
|                 error("... must be a last parameter list (expect ')')"); | ||||
|                 LOG_ERROR("... must be a last parameter list (expect ')')"); | ||||
|             } | ||||
|             // TODO | ||||
|             error("not implement"); | ||||
|             LOG_ERROR("not implement"); | ||||
|             break; | ||||
|         case TOKEN_IDENT: | ||||
|             // TODO 静态数组 | ||||
| @ -62,13 +62,13 @@ static void parse_params(parser_t* parser, tok_buf_t* cache, ast_node_t* node) { | ||||
|             //     flush_peek_tok(tokbuf); | ||||
|             //     continue; | ||||
|             // } | ||||
|             // error("function expected ')' or ','\n"); | ||||
|             // LOG_ERROR("function expected ')' or ','\n"); | ||||
|         } | ||||
|         pop_tok(cache); | ||||
|     } | ||||
| } | ||||
|  | ||||
| ast_type_t check_is_func_decl(tok_buf_t* tokbuf, tok_buf_t* cache) { | ||||
| ast_type_t check_is_func_decl(tok_stream_t* tokbuf, tok_stream_t* cache) { | ||||
|     expect_pop_tok(tokbuf, TOKEN_L_PAREN); | ||||
|     int depth = 1; | ||||
|      | ||||
| @ -76,7 +76,7 @@ ast_type_t check_is_func_decl(tok_buf_t* tokbuf, tok_buf_t* cache) { | ||||
|         tok_t* tok = peek_tok(tokbuf); | ||||
|         pop_tok(tokbuf); | ||||
|         if (cache->size >= cache->cap - 1) { | ||||
|             error("function parameter list too long"); | ||||
|             LOG_ERROR("function parameter list too long"); | ||||
|         } | ||||
|         cache->buf[cache->size++] = *tok; | ||||
|         switch (tok->type) { | ||||
| @ -100,7 +100,7 @@ ast_type_t check_is_func_decl(tok_buf_t* tokbuf, tok_buf_t* cache) { | ||||
|             return NT_FUNC; | ||||
|             break; | ||||
|         default: | ||||
|             error("function define or decl need '{' or ';' but you don't got"); | ||||
|             LOG_ERROR("function define or decl need '{' or ';' but you don't got"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -114,14 +114,14 @@ static ast_node_t* new_ast_node_funcdecl(ast_node_t* ret, ast_node_t* name) { | ||||
| } | ||||
|  | ||||
| void parse_func(parser_t* parser) { | ||||
|     tok_buf_t* tokbuf = &(parser->tokbuf); | ||||
|     tok_stream_t* tokbuf = &(parser->tokbuf); | ||||
|     flush_peek_tok(tokbuf); | ||||
|     ast_node_t* ret_node = parse_type(parser); | ||||
|     ast_node_t* name_node = expect_pop_ident(tokbuf); | ||||
|     const char* func_name = name_node->syms.tok.val.str; | ||||
|     ast_node_t* decl = new_ast_node_funcdecl(ret_node, name_node); | ||||
|  | ||||
|     tok_buf_t cache; | ||||
|     tok_stream_t cache; | ||||
|     init_tokbuf(&cache, NULL, NULL); | ||||
|     cache.cap = FUNC_PARAM_CACHE_SIZE; | ||||
|     tok_t buf[FUNC_PARAM_CACHE_SIZE]; | ||||
| @ -132,12 +132,12 @@ void parse_func(parser_t* parser) { | ||||
|     ast_node_t* prev = symtab_add_symbol(parser->symtab, func_name, decl, 1); | ||||
|     if (prev != NULL) { | ||||
|         if (prev->type != NT_DECL_FUNC) { | ||||
|             error("the symbol duplicate old is %d, new is func", prev->type); | ||||
|             LOG_ERROR("the symbol duplicate old is %d, new is func", prev->type); | ||||
|         } | ||||
|         // TODO check redeclare func is match | ||||
|         if (type == NT_FUNC) { | ||||
|             // TODO Free decl; | ||||
|             free(decl); | ||||
|             rt._free(decl); | ||||
|             decl = prev; | ||||
|             goto FUNC; | ||||
|         } | ||||
| @ -151,7 +151,7 @@ void parse_func(parser_t* parser) { | ||||
| FUNC: | ||||
|     // 该data临时用于判断是否重复定义 | ||||
|     if (decl->decl_func.def != NULL) { | ||||
|         error("redefinition of function %s", func_name); | ||||
|         LOG_ERROR("redefinition of function %s", func_name); | ||||
|     } | ||||
|  | ||||
|     ast_node_t* node = new_ast_node(); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "ast.h" | ||||
|  | ||||
| #ifndef PROG_MAX_NODE_SIZE | ||||
| #define PROG_MAX_NODE_SIZE (1024 * 4) | ||||
| @ -13,7 +13,7 @@ void parse_prog(parser_t* parser) { | ||||
|      * same as | ||||
|      * Program := Declaration* Definition* | ||||
|      */ | ||||
|     tok_buf_t *tokbuf = &(parser->tokbuf); | ||||
|     tok_stream_t *tokbuf = &(parser->tokbuf); | ||||
|     parser->root = new_ast_node(); | ||||
|     ast_node_t* node; | ||||
|     parser->root->type = NT_ROOT; | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "ast.h" | ||||
|  | ||||
| ast_node_t* parse_stmt(parser_t* parser) { | ||||
|     tok_buf_t* tokbuf = &parser->tokbuf; | ||||
|     tok_stream_t* tokbuf = &parser->tokbuf; | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype = peek_tok_type(tokbuf); | ||||
|     ast_node_t* node = new_ast_node(); | ||||
| @ -66,7 +66,7 @@ ast_node_t* parse_stmt(parser_t* parser) { | ||||
|         node->do_while_stmt.body = parse_stmt(parser); | ||||
|         ttype = peek_tok_type(tokbuf); | ||||
|         if (ttype != TOKEN_WHILE) { | ||||
|             error("expected while after do"); | ||||
|             LOG_ERROR("expected while after do"); | ||||
|         } | ||||
|         pop_tok(tokbuf); | ||||
|         expect_pop_tok(tokbuf, TOKEN_L_PAREN); | ||||
| @ -83,7 +83,7 @@ ast_node_t* parse_stmt(parser_t* parser) { | ||||
|         pop_tok(tokbuf); | ||||
|         ttype = peek_tok_type(tokbuf); | ||||
|         if (ttype != TOKEN_L_PAREN) { | ||||
|             error("expected ( after for"); | ||||
|             LOG_ERROR("expected ( after for"); | ||||
|         } | ||||
|         pop_tok(tokbuf); | ||||
|  | ||||
| @ -170,7 +170,7 @@ ast_node_t* parse_stmt(parser_t* parser) { | ||||
|         // find symbol table | ||||
|         ttype = peek_tok_type(tokbuf); | ||||
|         if (ttype != TOKEN_IDENT) { | ||||
|             error("expect identifier after goto"); | ||||
|             LOG_ERROR("expect identifier after goto"); | ||||
|         } | ||||
|         expect_pop_tok(tokbuf, TOKEN_SEMICOLON); | ||||
|         // TODO filling label | ||||
| @ -211,7 +211,7 @@ ast_node_t* parse_stmt(parser_t* parser) { | ||||
|     case TOKEN_CASE: { | ||||
|         // TODO label switch | ||||
|         pop_tok(tokbuf); | ||||
|         error("unimplemented switch label"); | ||||
|         LOG_ERROR("unimplemented switch label"); | ||||
|         node->label_stmt.label = parse_expr(parser); | ||||
|         // TODO 该表达式为const int | ||||
|         expect_pop_tok(tokbuf, TOKEN_COLON); | ||||
| @ -234,7 +234,7 @@ ast_node_t* parse_stmt(parser_t* parser) { | ||||
|         flush_peek_tok(tokbuf); | ||||
|         ttype = peek_tok_type(tokbuf); | ||||
|         if (ttype != TOKEN_SEMICOLON) { | ||||
|             error("exp must end with \";\""); | ||||
|             LOG_ERROR("exp must end with \";\""); | ||||
|         } | ||||
|         pop_tok(tokbuf); | ||||
|         node->type = NT_STMT_EXPR; | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| #include "../ast.h" | ||||
| #include "../parser.h" | ||||
| #include "../type.h" | ||||
| #include "ast.h" | ||||
|  | ||||
| ast_node_t* new_ast_ident_node(tok_t* tok) { | ||||
|     if (tok->type != TOKEN_IDENT) { | ||||
|         error("syntax error: want identifier but got %d", tok->type); | ||||
|         LOG_ERROR("syntax error: want identifier but got %d", tok->type); | ||||
|     } | ||||
|     ast_node_t* node = new_ast_node(); | ||||
|     node->type = NT_TERM_IDENT; | ||||
| @ -13,7 +13,7 @@ ast_node_t* new_ast_ident_node(tok_t* tok) { | ||||
|     return node; | ||||
| } | ||||
|  | ||||
| ast_node_t* expect_pop_ident(tok_buf_t* tokbuf) { | ||||
| ast_node_t* expect_pop_ident(tok_stream_t* tokbuf) { | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_t* tok = peek_tok(tokbuf); | ||||
|     ast_node_t* node = new_ast_ident_node(tok); | ||||
| @ -22,7 +22,7 @@ ast_node_t* expect_pop_ident(tok_buf_t* tokbuf) { | ||||
| } | ||||
|  | ||||
| ast_node_t* parse_type(parser_t* parser) { | ||||
|     tok_buf_t* tokbuf = &parser->tokbuf; | ||||
|     tok_stream_t* tokbuf = &parser->tokbuf; | ||||
|     flush_peek_tok(tokbuf); | ||||
|     tok_type_t ttype = peek_tok_type(tokbuf); | ||||
|     data_type_t dtype; | ||||
| @ -35,7 +35,7 @@ ast_node_t* parse_type(parser_t* parser) { | ||||
|         case TOKEN_FLOAT:   dtype = TYPE_FLOAT; break; | ||||
|         case TOKEN_DOUBLE:  dtype = TYPE_DOUBLE; break; | ||||
|         default: | ||||
|             error("无效的类型说明符"); | ||||
|             LOG_ERROR("无效的类型说明符"); | ||||
|     } | ||||
|  | ||||
|     ast_node_t* node = new_ast_node(); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user