diff --git a/libs/argparse/src/argparse.c b/libs/argparse/src/argparse.c index c85d309..05ef3dc 100644 --- a/libs/argparse/src/argparse.c +++ b/libs/argparse/src/argparse.c @@ -116,6 +116,7 @@ static void init_context(scc_argparse_context_t *ctx, scc_argparse_t *parser, static int handle_parse_error(scc_argparse_t *parser, scc_argparse_context_t *ctx) { + (void)parser; // TODO scc_argparse_err_t error = SCC_ARGPARSE_ERR_NONE; switch (ctx->result.error) { case SCC_OPT_ERROR_NOT_FOUND_SHORT_ARG: @@ -138,6 +139,7 @@ static int handle_parse_error(scc_argparse_t *parser, static int validate_and_cleanup(scc_argparse_context_t *ctx, scc_argparse_t *parser, int errcode) { + (void)parser; // TODO if (errcode == SCC_ARGPARSE_ERR_NONE) { // 检查必需参数是否都已提供 scc_vec_foreach(ctx->current_cmd->args, i) { @@ -213,6 +215,7 @@ static int handle_option(scc_argparse_context_t *ctx, scc_argparse_t *parser) { static int handle_positional_arg(scc_argparse_context_t *ctx, scc_argparse_t *parser) { + (void)parser; // TODO scc_argparse_cmd_t *subcmd = is_subcommand(ctx->current_cmd, ctx->result.value); if (subcmd != NULL) { diff --git a/libs/ast/include/ast_def.h b/libs/ast/include/ast_def.h index fb83ece..7bd1748 100644 --- a/libs/ast/include/ast_def.h +++ b/libs/ast/include/ast_def.h @@ -11,6 +11,7 @@ typedef enum { SCC_AST_UNKNOWN, // 声明 scc_ast_decl_t_BEGIN, // 声明开始 + SCC_AST_DECL_LIST, // 声明列表 SCC_AST_DECL_VAR, // 变量声明 SCC_AST_DECL_FUNC, // 函数声明 SCC_AST_DECL_PARAM, // 参数声明 @@ -417,6 +418,9 @@ struct scc_ast_decl { scc_ast_node_t base; const char *name; union { + struct { + scc_ast_decl_vec_t vars; + } list; // 变量声明 struct { scc_ast_type_t *type; diff --git a/libs/ast/include/scc_ast.h b/libs/ast/include/scc_ast.h index 2e771b7..9a1a03e 100644 --- a/libs/ast/include/scc_ast.h +++ b/libs/ast/include/scc_ast.h @@ -20,6 +20,16 @@ scc_ast_translation_unit_init(scc_ast_translation_unit_t *translation_unit, } } +static inline void scc_ast_decl_list_init(scc_ast_decl_t *decl, + scc_ast_decl_vec_t *list_move) { + Assert(decl != null && list_move != null); + decl->base.loc = scc_pos_create(); + decl->base.type = SCC_AST_DECL_LIST; + decl->name = null; + decl->list.vars = *list_move; + scc_vec_init(*list_move); +} + // name and var_init can be null static inline void scc_ast_decl_unsafe_val_init(scc_ast_decl_t *decl, scc_ast_type_t *type, diff --git a/libs/ast/src/ast_dump.c b/libs/ast/src/ast_dump.c index 79f4731..2b9b23c 100644 --- a/libs/ast/src/ast_dump.c +++ b/libs/ast/src/ast_dump.c @@ -17,6 +17,7 @@ static const char *node_type_names[] = { [SCC_AST_UNKNOWN] = "Unknown", [scc_ast_decl_t_BEGIN] = "ERROR", + [SCC_AST_DECL_LIST] = "DeclList", [SCC_AST_DECL_VAR] = "VarDecl", [SCC_AST_DECL_FUNC] = "FuncDecl", [SCC_AST_DECL_PARAM] = "ParamDecl", @@ -224,7 +225,7 @@ static inline void dump_child_node(scc_ast_node_t *child, scc_vec_push(ctx->stack, is_last); scc_ast_dump_node(ctx, child); - scc_vec_pop(ctx->stack); + (void)scc_vec_pop(ctx->stack); } // 用于构建复合类型名称的宏 @@ -343,7 +344,7 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) { SCC_TREE_DUMP_PRINT_PURE(ctx, ctx->node_color, "%s\n", "ReturnType"); dump_child_node((scc_ast_node_t *)type->function.return_type, ctx, true); - scc_vec_pop(ctx->stack); + (void)scc_vec_pop(ctx->stack); scc_vec_push(ctx->stack, true); if (scc_vec_size(type->function.param_types) != 0) { @@ -360,7 +361,7 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) { PRINT_QUOTED_VALUE(ctx, "()"); scc_tree_dump_printf(ctx, "\n"); } - scc_vec_pop(ctx->stack); + (void)scc_vec_pop(ctx->stack); break; default: break; @@ -445,7 +446,7 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) { ctx, ctx->node_color, "%s %s\n", expr->base.type == SCC_AST_EXPR_MEMBER ? "Member" : "PtrMember", expr->member.name); - scc_vec_pop(ctx->stack); + (void)scc_vec_pop(ctx->stack); break; case SCC_AST_EXPR_CAST: @@ -563,11 +564,10 @@ static void dump_stmt_impl(scc_ast_stmt_t *stmt, scc_tree_dump_ctx_t *ctx) { break; case SCC_AST_STMT_COMPOUND: end_node_dump(ctx); - for (size_t i = 0; i < stmt->compound.block_items.size; i++) { - scc_ast_node_t *item = - (scc_ast_node_t *)stmt->compound.block_items.data[i]; - dump_child_node(item, ctx, - i == stmt->compound.block_items.size - 1); + scc_vec_foreach(stmt->compound.block_items, i) { + dump_child_node( + (scc_ast_node_t *)scc_vec_at(stmt->compound.block_items, i), + ctx, i + 1 == stmt->compound.block_items.size); } break; @@ -613,6 +613,12 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { // 递归转储子节点 switch (decl->base.type) { + case SCC_AST_DECL_LIST: + scc_vec_foreach(decl->list.vars, i) { + dump_child_node((scc_ast_node_t *)scc_vec_at(decl->list.vars, i), + ctx, i + 1 != scc_vec_size(decl->list.vars)); + } + break; case SCC_AST_DECL_VAR: if (decl->var.type) { dump_child_node((scc_ast_node_t *)decl->var.type, ctx, @@ -641,17 +647,18 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { case SCC_AST_DECL_STRUCT: case SCC_AST_DECL_UNION: - for (size_t i = 0; i < decl->record.fields.size; i++) { - dump_child_node((scc_ast_node_t *)decl->record.fields.data[i], ctx, - i == decl->record.fields.size - 1); + scc_vec_foreach(decl->record.fields, i) { + dump_child_node( + (scc_ast_node_t *)scc_vec_at(decl->record.fields, i), ctx, + i + 1 != scc_vec_size(decl->record.fields)); } break; case SCC_AST_DECL_ENUM: - for (size_t i = 0; i < decl->enumeration.enumerators.size; i++) { + scc_vec_foreach(decl->enumeration.enumerators, i) { dump_child_node( - (scc_ast_node_t *)decl->enumeration.enumerators.data[i], ctx, - i == decl->enumeration.enumerators.size - 1); + (scc_ast_node_t *)scc_vec_at(decl->enumeration.enumerators, i), + ctx, i + 1 != scc_vec_size(decl->enumeration.enumerators)); } break; @@ -675,9 +682,9 @@ static void dump_unit_impl(scc_ast_translation_unit_t *unit, start_node_dump(&unit->base, ctx); end_node_dump(ctx); - for (size_t i = 0; i < unit->declarations.size; i++) { - dump_child_node((scc_ast_node_t *)unit->declarations.data[i], ctx, - i == unit->declarations.size - 1); + scc_vec_foreach(unit->declarations, i) { + dump_child_node((scc_ast_node_t *)scc_vec_at(unit->declarations, i), + ctx, i + 1 != scc_vec_size(unit->declarations)); } } diff --git a/libs/parser/include/scc_parser.h b/libs/parser/include/scc_parser.h index 4cd1877..5c5d7f4 100644 --- a/libs/parser/include/scc_parser.h +++ b/libs/parser/include/scc_parser.h @@ -75,7 +75,9 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser); * @param parser 解析器实例 * @return 类型 AST 节点 */ -scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser); +scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser, + scc_ast_type_t *type); +scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser); scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser); static inline void scc_parse_decl_sema(scc_parser_t *parser, diff --git a/libs/parser/src/parse_decl.c b/libs/parser/src/parse_decl.c index 2cfcb1f..e567927 100644 --- a/libs/parser/src/parse_decl.c +++ b/libs/parser/src/parse_decl.c @@ -258,25 +258,33 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser, } scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { - scc_ast_decl_t *decl = scc_parse_declarator(parser); + const scc_lexer_tok_t *tok_ptr = null; + + scc_ast_decl_t *decl_list = null; + scc_ast_decl_vec_t decl_list_vec; + scc_vec_init(decl_list_vec); + + scc_ast_type_t *type = scc_parse_declaration_specifiers(parser); + if (type == null) { + return null; + } + scc_ast_decl_specifier_t spec = type->quals; + // FIXME drop typedef inline and ... + type->quals.is_typedef = false; + + scc_ast_decl_t *decl = null; +CONTINUE: + decl = scc_parse_declarator(parser, type); if (decl == null) { return null; } - - const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); - if (tok_ptr->type == SCC_TOK_SEMICOLON) { - scc_parser_next_consume(parser, null); - goto RETURN; - } else if (tok_ptr->type == SCC_TOK_ASSIGN) { + tok_ptr = scc_parser_peek(parser); + if (tok_ptr->type == SCC_TOK_ASSIGN) { scc_parser_next_consume(parser, null); // TODO maybe memory leak scc_ast_expr_t *lvalue = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_lvalue_init(lvalue, decl->var.type); decl->var.init = scc_parse_initializer(parser, lvalue); - if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { - SCC_ERROR(scc_parser_got_current_pos(parser), "expect semicolon"); - } - goto RETURN; } else if (tok_ptr->type == SCC_TOK_L_BRACE) { scc_ast_stmt_t *body = scc_parse_statement(parser); Assert(decl->base.type == SCC_AST_DECL_FUNC); @@ -285,13 +293,56 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION); Assert(decl->func.body != null); Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND); + goto RETURN; + } + + tok_ptr = scc_parser_peek(parser); + if (tok_ptr->type == SCC_TOK_SEMICOLON) { + scc_parser_next_consume(parser, null); + if (spec.is_typedef) { + if (decl_list) { + scc_vec_foreach(decl_list_vec, i) { + decl = scc_vec_at(decl_list_vec, i); + scc_ast_decl_typedef_init(decl, decl->name, type); + } + } else { + scc_ast_decl_typedef_init(decl, decl->name, decl->var.type); + } + } + if (decl_list != null) { + scc_vec_push(decl_list_vec, decl); + + scc_vec_foreach(decl_list_vec, i) { + decl = scc_vec_at(decl_list_vec, i); + scc_parse_decl_sema(parser, decl); + } + scc_ast_decl_list_init(decl_list, &decl_list_vec); + decl = decl_list; + } else { + scc_parse_decl_sema(parser, decl); + } + goto RETURN; + } else if (tok_ptr->type == SCC_TOK_COMMA) { + scc_parser_next_consume(parser, null); + if (decl_list == null) { + decl_list = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(decl_list != null); + scc_vec_push(decl_list_vec, decl); + } else { + Assert(scc_vec_size(decl_list_vec) != 0); + decl->var.type = scc_vec_at(decl_list_vec, 0)->var.type; + scc_vec_push(decl_list_vec, decl); + } + goto CONTINUE; } else { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ';' or '=' or '{'"); - UNREACHABLE(); + // FIXME memory leak + goto ERROR; } RETURN: - scc_parse_decl_sema(parser, decl); return decl; +ERROR: + return null; } diff --git a/libs/parser/src/parse_expr.c b/libs/parser/src/parse_expr.c index f852031..e4080b1 100644 --- a/libs/parser/src/parse_expr.c +++ b/libs/parser/src/parse_expr.c @@ -149,8 +149,6 @@ parse_primary_expression(scc_parser_t *parser); // 基本表达式 // 特殊结构的内部辅助函数 static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser); -static scc_ast_expr_t * -parse_paren_expression(scc_parser_t *parser); // 处理括号的三种情况 /* ---------------------------- 工具函数 ---------------------------- */ // 获取 token 的优先级(用于二元运算符) @@ -537,11 +535,10 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) { case SCC_TOK_BIT_NOT: // ~x case SCC_TOK_NOT: // !x { - scc_lexer_tok_t op_tok; - if (!scc_parser_next_consume(parser, &op_tok)) + if (!scc_parser_next_consume(parser, &tok)) return null; - scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, true); - scc_lexer_tok_drop(&op_tok); + scc_ast_expr_op_t op = map_token_to_unary_op(tok.type, true); + scc_lexer_tok_drop(&tok); // 一元运算符右结合,递归调用 parse_unary_expression diff --git a/libs/parser/src/parse_type.c b/libs/parser/src/parse_type.c index 7235ed0..e7532d4 100644 --- a/libs/parser/src/parse_type.c +++ b/libs/parser/src/parse_type.c @@ -588,10 +588,13 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser, break; } - decl = scc_parse_declarator(parser); - if (decl != null) { - scc_vec_push(member, decl); - continue; + scc_ast_type_t *type = scc_parse_declaration_specifiers(parser); + if (type != null) { + decl = scc_parse_declarator(parser, type); + if (decl != null) { + scc_vec_push(member, decl); + continue; + } } if (tok_ptr->type == SCC_TOK_SEMICOLON) { @@ -893,11 +896,16 @@ static void parse_parameter_type_list(scc_parser_t *parser, declaration-specifiers abstract-declarator(opt) */ scc_ast_decl_t *param = null; + scc_ast_decl_t *decl = null; while (1) { // FIXME - scc_ast_decl_t *decl = scc_parse_declarator(parser); + scc_ast_type_t *type = scc_parse_declaration_specifiers(parser); + if (type == null) { + break; + } + decl = scc_parse_declarator(parser, type); if (decl == null) { - return; + break; } // TODO Check validation @@ -1142,87 +1150,142 @@ parse_direct_abstract_declarator(scc_parser_t *parser, scc_ast_type_t *base, } } -scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser) { - if (!scc_parse_is_decl_specifier_start(parser)) { - return null; - } - - cbool is_typedef_decl = false; - if (scc_parser_consume_if(parser, SCC_TOK_TYPEDEF)) { - is_typedef_decl = true; - } - - scc_ast_type_t *ret = null; - scc_ast_decl_specifier_t spec = {0}; - spec = parse_declaration_specifiers_list(parser, spec); - ret = parse_type_specifier(parser); - if (ret != null) { - ret->quals = spec; - ret->quals.is_inline = false; - } - - scc_lexer_tok_t tok_ident = {0}; - scc_ast_type_t *type = parse_declarator(parser, ret, null, &tok_ident); - +scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser, + scc_ast_type_t *type) { + scc_lexer_tok_t decl_name_tok = {0}; + scc_ast_type_t *decl_type = + parse_declarator(parser, type, null, &decl_name_tok); scc_ast_decl_t *decl = null; - if (tok_ident.type == SCC_TOK_IDENT) { - decl = scc_malloc(sizeof(scc_ast_decl_t)); - Assert(decl != null); - } - const char *name = decl ? scc_cstring_as_cstr(&tok_ident.lexeme) : null; - if (is_typedef_decl) { - if (decl == null) { - SCC_ERROR(scc_parser_got_current_pos(parser), - "typedef don't have a ident"); - parser->errcode = 1; + decl = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(decl != null); + Assert(decl_name_tok.type == SCC_TOK_IDENT || + decl_name_tok.type == SCC_TOK_UNKNOWN); + + // FIXME memory leak + const char *name = decl_name_tok.type == SCC_TOK_IDENT + ? scc_cstring_as_cstr(&decl_name_tok.lexeme) + : null; + + if (decl_type->base.type == SCC_AST_TYPE_FUNCTION) { + scc_ast_decl_func_init(decl, decl_type, name, null); + // TODO using sema to change it + if (type->quals.is_inline) { + decl_type->quals.is_inline = true; } else { - scc_ast_decl_typedef_init(decl, name, type); - } - } else if (decl) { - if (type->base.type == SCC_AST_TYPE_FUNCTION) { - scc_ast_decl_func_init(decl, type, name, null); - // TODO using sema to change it - if (spec.is_inline) { - type->quals.is_inline = true; - } - } else { - scc_ast_decl_val_init(decl, type, name, null); + type->quals.is_inline = false; } + } else { + scc_ast_decl_unsafe_val_init(decl, decl_type, name, null); } - scc_ast_node_t *type_or_decl = decl != null ? &decl->base : &type->base; - if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) { - scc_ast_type_t *type = SCC_AST_CAST_TO(scc_ast_type_t, type_or_decl); - if (type->base.type == SCC_AST_TYPE_STRUCT || - type->base.type == SCC_AST_TYPE_UNION) { - if (type->record.decl == null) { + if (decl_name_tok.type != SCC_TOK_IDENT) { + if (decl_type->base.type == SCC_AST_TYPE_STRUCT || + decl_type->base.type == SCC_AST_TYPE_UNION) { + if (decl_type->record.decl == null) { SCC_ERROR(scc_parser_got_current_pos(parser), "record don't have a decl"); Panic(); } - decl = type->record.decl; - scc_free(type_or_decl); // FIXME - } else if (type->base.type == SCC_AST_TYPE_ENUM) { - if (type->enumeration.decl == null) { + decl = decl_type->record.decl; + scc_free(decl_type); // FIXME + } else if (decl_type->base.type == SCC_AST_TYPE_ENUM) { + if (decl_type->enumeration.decl == null) { SCC_ERROR(scc_parser_got_current_pos(parser), "enum don't have a decl"); Panic(); } decl = type->enumeration.decl; - scc_free(type_or_decl); // FIXME + scc_free(decl_type); // FIXME } else { decl = scc_malloc(sizeof(scc_ast_decl_t)); scc_ast_decl_unsafe_val_init(decl, type, null, null); } - } else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) { - decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl); - } else { - SCC_ERROR(scc_parser_got_current_pos(parser), "invalid declaration"); - return null; } return decl; } +scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser) { + if (!scc_parse_is_decl_specifier_start(parser)) { + return null; + } + scc_ast_decl_specifier_t spec = {0}; + + if (scc_parser_consume_if(parser, SCC_TOK_TYPEDEF)) { + spec.is_typedef = true; + } + + spec = parse_declaration_specifiers_list(parser, spec); + scc_ast_type_t *specifier = parse_type_specifier(parser); + if (specifier == null) { + SCC_ERROR(scc_parser_got_current_pos(parser), + "declaration specifier can't have type specifier"); + return null; + } + specifier->quals = spec; + + return specifier; + // scc_lexer_tok_t tok_ident = {0}; + // scc_ast_type_t *type = parse_declarator(parser, ret, null, &tok_ident); + + // scc_ast_decl_t *decl = null; + // if (tok_ident.type == SCC_TOK_IDENT) { + // decl = scc_malloc(sizeof(scc_ast_decl_t)); + // Assert(decl != null); + // } + // const char *name = decl ? scc_cstring_as_cstr(&tok_ident.lexeme) : null; + // if (is_typedef_decl) { + // if (decl == null) { + // SCC_ERROR(scc_parser_got_current_pos(parser), + // "typedef don't have a ident"); + // parser->errcode = 1; + // } else { + // scc_ast_decl_typedef_init(decl, name, type); + // } + // } else if (decl) { + // if (type->base.type == SCC_AST_TYPE_FUNCTION) { + // scc_ast_decl_func_init(decl, type, name, null); + // // TODO using sema to change it + // if (spec.is_inline) { + // type->quals.is_inline = true; + // } + // } else { + // scc_ast_decl_val_init(decl, type, name, null); + // } + // } + + // scc_ast_node_t *type_or_decl = decl != null ? &decl->base : &type->base; + // if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) { + // scc_ast_type_t *type = SCC_AST_CAST_TO(scc_ast_type_t, type_or_decl); + // if (type->base.type == SCC_AST_TYPE_STRUCT || + // type->base.type == SCC_AST_TYPE_UNION) { + // if (type->record.decl == null) { + // SCC_ERROR(scc_parser_got_current_pos(parser), + // "record don't have a decl"); + // Panic(); + // } + // decl = type->record.decl; + // scc_free(type_or_decl); // FIXME + // } else if (type->base.type == SCC_AST_TYPE_ENUM) { + // if (type->enumeration.decl == null) { + // SCC_ERROR(scc_parser_got_current_pos(parser), + // "enum don't have a decl"); + // Panic(); + // } + // decl = type->enumeration.decl; + // scc_free(type_or_decl); // FIXME + // } else { + // decl = scc_malloc(sizeof(scc_ast_decl_t)); + // scc_ast_decl_unsafe_val_init(decl, type, null, null); + // } + // } else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) { + // decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl); + // } else { + // SCC_ERROR(scc_parser_got_current_pos(parser), "invalid declaration"); + // return null; + // } + // return decl; +} + scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) { if (!(scc_parse_is_type_specifier_start(parser) || scc_parse_is_type_qualifier_start(parser))) { diff --git a/libs/parser/src/scc_parser.c b/libs/parser/src/scc_parser.c index fa2be33..5f743b2 100644 --- a/libs/parser/src/scc_parser.c +++ b/libs/parser/src/scc_parser.c @@ -64,7 +64,6 @@ scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) { * same as * Program := Declaration* Definition* */ - cbool matched = false; while (1) { scc_ast_decl_t *decl = scc_parse_declaration(parser); if (decl != null) { diff --git a/libs/parser/src/scc_sema.c b/libs/parser/src/scc_sema.c index 40ef9a6..12524a0 100644 --- a/libs/parser/src/scc_sema.c +++ b/libs/parser/src/scc_sema.c @@ -25,13 +25,22 @@ static void decl_callback(void *context, scc_ast_node_type_t node_type, } if (decl->base.type == SCC_AST_DECL_STRUCT) { scc_ast_type_struct_init(type, decl->name, decl); - scc_sema_symtab_add_symbol(sema_symtab, decl->name, &type->base); + scc_cstring_t name = scc_cstring_from_cstr("$S_"); + scc_cstring_append_cstr(&name, decl->name, scc_strlen(decl->name)); + scc_sema_symtab_add_symbol(sema_symtab, scc_cstring_as_cstr(&name), + &type->base); } else if (decl->base.type == SCC_AST_DECL_UNION) { scc_ast_type_union_init(type, decl->name, decl); - scc_sema_symtab_add_symbol(sema_symtab, decl->name, &type->base); + scc_cstring_t name = scc_cstring_from_cstr("$U_"); + scc_cstring_append_cstr(&name, decl->name, scc_strlen(decl->name)); + scc_sema_symtab_add_symbol(sema_symtab, scc_cstring_as_cstr(&name), + &type->base); } else if (decl->base.type == SCC_AST_DECL_ENUM) { scc_ast_type_enum_init(type, decl->name, decl); - scc_sema_symtab_add_symbol(sema_symtab, decl->name, &type->base); + scc_cstring_t name = scc_cstring_from_cstr("$E_"); + scc_cstring_append_cstr(&name, decl->name, scc_strlen(decl->name)); + scc_sema_symtab_add_symbol(sema_symtab, scc_cstring_as_cstr(&name), + &type->base); } else if (decl->base.type == SCC_AST_DECL_TYPEDEF) { scc_ast_type_typedef_init(type, decl->name, decl); scc_sema_symtab_add_symbol(sema_symtab, decl->name, &type->base); diff --git a/libs/parser/src/sema_symtab.c b/libs/parser/src/sema_symtab.c index a81e7ea..9bf3916 100644 --- a/libs/parser/src/sema_symtab.c +++ b/libs/parser/src/sema_symtab.c @@ -23,8 +23,9 @@ void scc_sema_symtab_enter_scope(scc_sema_symtab_t *symtab) { return; } scope->parent = symtab->current_scope; - scc_hashtable_init(&scope->symbols, (scc_hashtable_hash_func_t)scc_strcmp, - (scc_hashtable_equal_func_t)scc_strhash32); + scc_hashtable_init(&scope->symbols, + (scc_hashtable_hash_func_t)scc_strhash32, + (scc_hashtable_equal_func_t)scc_strcmp); symtab->current_scope = scope; } diff --git a/libs/parser/tests/test_parser_unit.c b/libs/parser/tests/test_parser_unit.c index 376cb98..0237e27 100644 --- a/libs/parser/tests/test_parser_unit.c +++ b/libs/parser/tests/test_parser_unit.c @@ -689,55 +689,57 @@ static void test_parser_unit(void) { scc_parse_declaration); } - // // 测试 int a, b; - // { - // scc_ast_decl_t decl_a, decl_b; - // scc_ast_decl_val_init(&decl_a, - // (scc_ast_type_t - // *)&scc_ast_builtin_type_int, "a", null); - // scc_ast_decl_val_init(&decl_b, - // (scc_ast_type_t - // *)&scc_ast_builtin_type_int, "b", null); + // 测试 int a, b; + { + scc_ast_decl_t decl_a, decl_b; + scc_ast_decl_val_init(&decl_a, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + "a", null); + scc_ast_decl_val_init(&decl_b, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + "b", null); - // scc_ast_decl_vec_t decl_vec; - // scc_vec_init(decl_vec); - // scc_vec_push(decl_vec, &decl_a); - // scc_vec_push(decl_vec, &decl_b); + scc_ast_decl_vec_t decl_vec; + scc_vec_init(decl_vec); + scc_vec_push(decl_vec, &decl_a); + scc_vec_push(decl_vec, &decl_b); - // scc_ast_decl_t decl_list; - // scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数 + scc_ast_decl_t decl_list; + scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数 - // SCC_CHECK_AST(&decl_list.base, "int a, b;", - // scc_parse_declaration); - // } + SCC_CHECK_AST(&decl_list.base, "int a, b;", scc_parse_declaration); + } - // // 测试 int a = 1, b = 2; - // { - // scc_ast_expr_t lit1, lit2; - // scc_ast_expr_literal_int_init(&lit1, "1", false); - // scc_ast_expr_literal_int_init(&lit2, "2", false); + // 测试 int a = 1, b = 2; + { + scc_ast_expr_t lit1, lit2; + scc_ast_expr_literal_int_init(&lit1, "1", false); + scc_ast_expr_literal_int_init(&lit2, "2", false); - // scc_ast_decl_t decl_a, decl_b; - // scc_ast_decl_val_init(&decl_a, - // (scc_ast_type_t - // *)&scc_ast_builtin_type_int, "a", &lit1); - // scc_ast_decl_val_init(&decl_b, - // (scc_ast_type_t - // *)&scc_ast_builtin_type_int, "b", &lit2); + scc_ast_decl_t decl_a, decl_b; + scc_ast_decl_val_init(&decl_a, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + "a", &lit1); + scc_ast_decl_val_init(&decl_b, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + "b", &lit2); - // scc_ast_decl_vec_t decl_vec; - // scc_vec_init(decl_vec); - // scc_vec_push(decl_vec, &decl_a); - // scc_vec_push(decl_vec, &decl_b); + scc_ast_decl_vec_t decl_vec; + scc_vec_init(decl_vec); + scc_vec_push(decl_vec, &decl_a); + scc_vec_push(decl_vec, &decl_b); - // scc_ast_decl_t decl_list; - // scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数 + scc_ast_decl_t decl_list; + scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数 - // SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;", - // scc_parse_declaration); - // } + SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;", + scc_parse_declaration); + } + "struct list_head *next, *prev;"; + "typedef struct { int a; } struct_t, *struct_ptr_t;"; "__scc_builtin_va_arg(ag, int)"; "__scc_builtin_va_arg(ag, long long)"; + "typedef struct a;int a;struct a b;"; } { diff --git a/libs/pproc/src/pproc_if.c b/libs/pproc/src/pproc_if.c index a7563a1..ae7a05e 100644 --- a/libs/pproc/src/pproc_if.c +++ b/libs/pproc/src/pproc_if.c @@ -68,7 +68,7 @@ static void in_endif(scc_pproc_t *pp) { if (scc_vec_size(pp->if_stack) == 0) { LOG_ERROR("#endif without #if"); } else { - scc_vec_pop(pp->if_stack); + (void)scc_vec_pop(pp->if_stack); } if (scc_vec_size(pp->if_stack) == 0) { pp->enable = true; @@ -136,6 +136,7 @@ cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, static int parse_constant_condition(scc_pproc_t *pp, scc_lexer_tok_ring_t *tok_ring) { + (void)pp; // TODO int ok; scc_lexer_tok_t tok = {0}; ok = scc_lexer_next_non_blank(tok_ring, &tok); diff --git a/libs/sstream/src/scc_pos_log.c b/libs/sstream/src/scc_pos_log.c index 0524a7f..3d07736 100644 --- a/libs/sstream/src/scc_pos_log.c +++ b/libs/sstream/src/scc_pos_log.c @@ -44,8 +44,9 @@ static int user_log_handler(logger_t *module, log_level_t level, log_puts(buf); log_puts("\n"); - if (level == LOG_LEVEL_FATAL) - log_exit(1); + if (level == LOG_LEVEL_FATAL) { + log_abort(); + } return 0; } diff --git a/libs/sstream/src/scc_sstream.c b/libs/sstream/src/scc_sstream.c index b48e5f8..500132a 100644 --- a/libs/sstream/src/scc_sstream.c +++ b/libs/sstream/src/scc_sstream.c @@ -67,6 +67,7 @@ static int sstream_scan_at(scc_sstream_t *stream, scc_pos_t scan_pos, // 环形缓冲区填充回调(通过 userdata 获取流对象) static cbool fill_func(scc_sstream_char_t *out, void *userdata) { + Assert(out != null && userdata != null); scc_sstream_t *stream = (scc_sstream_t *)userdata; if (stream->fill_pos.offset >= stream->len) return false; // 已到文件尾 diff --git a/libs/tree_dump/include/tree_dump.h b/libs/tree_dump/include/tree_dump.h index d3fc624..e0bd2e9 100644 --- a/libs/tree_dump/include/tree_dump.h +++ b/libs/tree_dump/include/tree_dump.h @@ -66,7 +66,7 @@ static inline void scc_tree_dump_ctx_drop(scc_tree_dump_ctx_t *ctx) { } // 打印缩进 -static void scc_tree_print_indent(scc_tree_dump_ctx_t *ctx) { +static inline void scc_tree_print_indent(scc_tree_dump_ctx_t *ctx) { scc_vec_foreach(ctx->stack, i) { cbool last_child = scc_vec_at(ctx->stack, i); const char *data = null; diff --git a/runtime/log/include/log.c b/runtime/log/include/log.c index a472f1a..2fa02be 100644 --- a/runtime/log/include/log.c +++ b/runtime/log/include/log.c @@ -60,7 +60,7 @@ int log_default_handler(logger_t *module, log_level_t level, const char *file, (void)color_code; (void)level_str; if (level & LOG_LEVEL_FATAL) { - log_exit(-LOG_LEVEL_FATAL); + log_abort(); } return 0; } diff --git a/runtime/log/include/log.h b/runtime/log/include/log.h index 0efad5b..f6f64ad 100644 --- a/runtime/log/include/log.h +++ b/runtime/log/include/log.h @@ -14,7 +14,7 @@ #include #define log_vsnprintf vsnprintf #define log_puts puts -#define log_exit scc_exit +#define log_abort abort #endif #ifdef __GNUC__ // GCC, Clang @@ -37,9 +37,9 @@ #warning "log_puts not defined" #endif -#ifndef log_exit -#define log_exit(...) -#warning "log_exit not defined" +#ifndef log_abort +#define log_abort(...) +#warning "log_abort not defined" #endif /** @@ -155,7 +155,7 @@ void log_set_handler(logger_t *logger, log_handler handler); ((void)((cond) || \ (__default_logger_root.handler(SCC_LOG_HANDLE_ARGS( \ &__default_logger_root, LOG_LEVEL_FATAL, __VA_ARGS__)), \ - log_exit(1), __scc_log_unreachable(), 0))) + log_abort(), __scc_log_unreachable(), 0))) /// @name 断言工具宏 /// @{ diff --git a/runtime/scc_core/include/scc_core_impl.h b/runtime/scc_core/include/scc_core_impl.h index 59fc87f..b668ffe 100644 --- a/runtime/scc_core/include/scc_core_impl.h +++ b/runtime/scc_core/include/scc_core_impl.h @@ -9,6 +9,7 @@ #define scc_realloc scc_pal_realloc #define scc_free scc_pal_free #define scc_exit scc_pal_exit +#define scc_abort scc_pal_abort typedef void *scc_file_t; typedef enum { diff --git a/runtime/scc_core/include/scc_core_log.h b/runtime/scc_core/include/scc_core_log.h index fd8f4bf..e1711d1 100644 --- a/runtime/scc_core/include/scc_core_log.h +++ b/runtime/scc_core/include/scc_core_log.h @@ -9,8 +9,8 @@ #define log_puts(str) scc_printf("%s", str) #endif -#ifndef log_exit -#define log_exit scc_exit +#ifndef log_abort +#define log_abort scc_abort #endif #include diff --git a/runtime/scc_core/include/scc_core_pal.h b/runtime/scc_core/include/scc_core_pal.h index f14e123..c818e7a 100644 --- a/runtime/scc_core/include/scc_core_pal.h +++ b/runtime/scc_core/include/scc_core_pal.h @@ -17,6 +17,9 @@ void scc_pal_free(void *ptr); // Required void scc_pal_exit(int code); +// Option +void scc_pal_abort(); + /* IO */ // Required diff --git a/runtime/scc_core/include/scc_core_ring.h b/runtime/scc_core/include/scc_core_ring.h index 3edb4ab..4d975b9 100644 --- a/runtime/scc_core/include/scc_core_ring.h +++ b/runtime/scc_core/include/scc_core_ring.h @@ -58,7 +58,7 @@ } \ usize phys_tail = _scc_ring_phys(ring, (ring).tail); \ if ((ring).fill == null || \ - !(ring).fill(&(ring).data[phys_tail], (ring).userdata)) { \ + !(ring).fill(&((ring).data[phys_tail]), (ring).userdata)) { \ ok = 0; \ break; \ } \ @@ -104,7 +104,7 @@ #define scc_ring_init(ring, _cap, fill_func, _userdata) \ do { \ (ring).data = \ - (_cap) ? scc_malloc((_cap) * sizeof(*(ring).data)) : null; \ + (_cap) != 0 ? scc_malloc((_cap) * sizeof(*(ring).data)) : null; \ (ring).cap = (_cap); \ (ring).head = 0; \ (ring).probe = 0; \ diff --git a/runtime/scc_core/include/scc_printf/printf.h b/runtime/scc_core/include/scc_printf/printf.h index 87715ed..f590cad 100644 --- a/runtime/scc_core/include/scc_printf/printf.h +++ b/runtime/scc_core/include/scc_printf/printf.h @@ -35,10 +35,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - +/* clang-format off */ #ifndef PRINTF_H_ #define PRINTF_H_ +#define PRINTF_INCLUDE_CONFIG_H #ifdef PRINTF_INCLUDE_CONFIG_H #include "printf_config.h" #endif diff --git a/runtime/scc_core/include/scc_printf/printf_config.h b/runtime/scc_core/include/scc_printf/printf_config.h new file mode 100644 index 0000000..7dcc7f2 --- /dev/null +++ b/runtime/scc_core/include/scc_printf/printf_config.h @@ -0,0 +1,10 @@ +/* clang-format off */ +/* Support for the decimal notation floating point conversion specifiers (%f, %F) */ +#ifndef PRINTF_SUPPORT_DECIMAL_SPECIFIERS +#define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 0 +#endif + +/* Support for the exponential notation floating point conversion specifiers (%e, %g, %E, %G) */ +#ifndef PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +#define PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS 0 +#endif \ No newline at end of file diff --git a/runtime/scc_core/src/cfg.std_impl.c b/runtime/scc_core/src/cfg.std_impl.c index e8f2f4e..f5b7562 100644 --- a/runtime/scc_core/src/cfg.std_impl.c +++ b/runtime/scc_core/src/cfg.std_impl.c @@ -74,12 +74,15 @@ size_t scc_pal_fseek(scc_pal_file_t f, size_t offset, void scc_pal_exit(int code) { exit(code); } +void scc_pal_abort() { abort(); } + void scc_pal_putchar(char c) { putchar(c); } void scc_pal_eputchar(char c) { fputc(c, stderr); } void scc_pal_write(const char *data, size_t len) { int res = fputs(data, stdout); + (void)len; // FIXME maybe using len to check return value if (res != 0) { fprintf(stderr, "\nError writing to stdout [%d]\n", res); scc_pal_exit(1); @@ -88,6 +91,7 @@ void scc_pal_write(const char *data, size_t len) { void scc_pal_ewrite(const char *data, size_t len) { int res = fputs(data, stderr); + (void)len; // FIXME maybe using len to check return value if (res != 0) { fprintf(stderr, "\nError writing to stderr [%d]\n", res); scc_pal_exit(1); diff --git a/runtime/scc_core/src/core_impl.c b/runtime/scc_core/src/core_impl.c index 2b67061..1bcc450 100644 --- a/runtime/scc_core/src/core_impl.c +++ b/runtime/scc_core/src/core_impl.c @@ -5,13 +5,22 @@ #define __SCC_LOG_IMPL_IMPORT_SRC__ #include -void putchar_(char ch) { LOG_FATAL("you can't use printf.c directly"); } +void putchar_(char ch) { + (void)ch; + LOG_FATAL("you can't use printf.c directly"); +} scc_file_t scc_fopen(const char *path, scc_fmode_t mode) { return scc_pal_fopen(path, (scc_pal_fmode_t)mode); // FIXME } -void scc_fclose(scc_file_t file) { scc_pal_fclose(file); } +void scc_fclose(scc_file_t file) { + if (file == scc_stdout || file == scc_stderr) { + return; + } else { + scc_pal_fclose(file); + } +} usize scc_fsize(scc_file_t file) { if (scc_pal_fseek(file, 0, SCC_SEEK_PAL_END) != 0) {