#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) { tok_type_t ttype; ast_node_t *params = new_ast_node(); node->decl_func.params = params; vector_init(params->params.params); int depth = 1; while (depth) { ttype = peek_tok_type(cache); switch (ttype) { case TOKEN_COMMA: break; case TOKEN_ELLIPSIS: ttype = peek_tok_type(cache); if (ttype != TOKEN_R_PAREN) { error("... must be a last parameter list (expect ')')"); } // TODO error("not implement"); break; case TOKEN_IDENT: // TODO 静态数组 flush_peek_tok(cache); ast_node_t* id_node = new_ast_ident_node(peek_tok(cache)); ast_node_t* node = new_ast_node(); node->type = NT_DECL_VAR; node->decl_val.name = id_node; // TODO typing sys node->decl_val.type = NULL; node->decl_val.expr_stmt = NULL; node->decl_val.data = NULL; vector_push(params->params.params, node); symtab_add_symbol(parser->symtab, id_node->syms.tok.val.str, node, 0); break; case TOKEN_L_PAREN: { depth++; break; } case TOKEN_R_PAREN: { depth--; break; } default: break; // TODO 使用cache的类型解析 // parse_type(parser); // TODO type parse // ttype = peekcachetype(cache); // ttype = peekcachetype(cache); // if (ttype != TOKEN_IDENT) { // node->node_type = NT_DECL_FUNC; // flush_peek_tok(tokbuf); // continue; // } // error("function expected ')' or ','\n"); } pop_tok(cache); } } ast_type_t check_is_func_decl(tok_buf_t* tokbuf, tok_buf_t* cache) { expect_pop_tok(tokbuf, TOKEN_L_PAREN); int depth = 1; while (depth) { tok_t* tok = peek_tok(tokbuf); pop_tok(tokbuf); if (cache->size >= cache->cap - 1) { error("function parameter list too long"); } cache->buf[cache->size++] = *tok; switch (tok->type) { case TOKEN_L_PAREN: depth++; break; case TOKEN_R_PAREN: depth--; break; default: break; } } cache->end = cache->size; switch (peek_tok_type(tokbuf)) { case TOKEN_SEMICOLON: pop_tok(tokbuf); return NT_DECL_FUNC; case TOKEN_L_BRACE: return NT_FUNC; break; default: error("function define or decl need '{' or ';' but you don't got"); } } static ast_node_t* new_ast_node_funcdecl(ast_node_t* ret, ast_node_t* name) { ast_node_t* node = new_ast_node(); node->type = NT_DECL_FUNC; node->decl_func.ret = ret; node->decl_func.name = name; node->decl_func.def = NULL; return node; } void parse_func(parser_t* parser) { tok_buf_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; init_tokbuf(&cache, NULL, NULL); cache.cap = FUNC_PARAM_CACHE_SIZE; tok_t buf[FUNC_PARAM_CACHE_SIZE]; cache.buf = buf; ast_type_t type = check_is_func_decl(&(parser->tokbuf), &cache); 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); } // TODO check redeclare func is match if (type == NT_FUNC) { // TODO Free decl; free(decl); decl = prev; goto FUNC; } return; } vector_push(parser->root->root.children, decl); if (type == NT_DECL_FUNC) { return; } FUNC: // 该data临时用于判断是否重复定义 if (decl->decl_func.def != NULL) { error("redefinition of function %s", func_name); } ast_node_t* node = new_ast_node(); node->type = NT_FUNC; node->func.decl = decl; node->func.data = NULL; decl->decl_func.def = node; symtab_enter_scope(parser->symtab); parse_params(parser, &cache, decl); node->func.body = parse_block(parser); symtab_leave_scope(parser->symtab); vector_push(parser->root->root.children, node); }