feat(ast): 修改函数调用表达式的结构定义

在AST定义中将函数调用表达式的name字段替换为callee字段,
以支持更复杂的函数调用场景。同时更新了相关的初始化函数、
转储函数和解析逻辑,使函数调用表达式能够正确处理callee节点。

BREAKING CHANGE: 函数调用表达式的结构发生了改变,从使用name字符串
改为使用callee表达式节点。
This commit is contained in:
zzy
2026-03-10 14:33:32 +08:00
parent 2e331ee016
commit 742bede02f
7 changed files with 102 additions and 23 deletions

View File

@@ -269,6 +269,7 @@ struct scc_ast_expr {
// 函数调用
struct {
const char *name;
scc_ast_expr_t *callee;
scc_ast_expr_t *_target;
scc_ast_expr_vec_t args;
} call;

View File

@@ -293,12 +293,12 @@ static inline void scc_ast_expr_cond_init(scc_ast_expr_t *expr,
// args can be null
static inline void scc_ast_expr_call_init(scc_ast_expr_t *expr,
const char *name,
scc_ast_expr_t *callee,
scc_ast_expr_vec_t *args) {
Assert(expr != null && name != null);
Assert(expr != null && callee != null);
expr->base.loc = scc_pos_create();
expr->base.type = SCC_AST_EXPR_CALL;
expr->call.name = name;
expr->call.callee = callee;
expr->call._target = null;
if (args == null) {
scc_vec_init(expr->call.args);

View File

@@ -440,8 +440,7 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) {
break;
case SCC_AST_EXPR_CALL:
// dump_child_node((scc_ast_node_t *)expr->call._target, ctx, false);
PRINT_NODE(ctx, "%s", expr->call.name);
dump_child_node((scc_ast_node_t *)expr->call.callee, ctx, false);
// 转储参数
for (size_t i = 0; i < expr->call.args.size; i++) {
dump_child_node((scc_ast_node_t *)expr->call.args.data[i], ctx,

View File

@@ -145,7 +145,7 @@ A.2.4 External definitions
function-definition
declaration
(6.9.1) function-definition:
declaration-specifiers declarator declaration-listopt compound-statement
declaration-specifiers declarator declaration-list(opt) compound-statement
(6.9.1) declaration-list:
declaration
declaration-list declaration
@@ -210,6 +210,9 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
scc_ast_expr_t *init = scc_parse_expression(parser);
scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme),
init);
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
LOG_ERROR("expect semicolon");
}
goto RETURN;
}
// TODO
@@ -250,7 +253,9 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
RETURN:
if (decl) {
parser->sema_callbacks.on_decl(parser->sema_callbacks.context,
decl->base.type, decl);
}
return decl;
}

View File

@@ -760,7 +760,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
scc_lexer_tok_drop(&lp);
scc_ast_expr_t *call = expr_create(parser, SCC_AST_EXPR_CALL);
call->call._target = left;
call->call.callee = left;
scc_vec_init(call->call.args);
// 解析参数列表

View File

@@ -249,17 +249,13 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) {
scc_ast_stmt_t *body = null;
// TODO use decl or expr
init = (scc_ast_type_t *)scc_parse_expression(parser);
if (init == null) {
init = (scc_ast_type_t *)scc_parse_declaration(parser);
}
if (init == null) {
LOG_ERROR("Expected expression or declaration in for statement.");
}
init = (scc_ast_type_t *)scc_parse_expression(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
LOG_ERROR("Expected semicolon in for statement.");
}
}
cond = scc_parse_expression(parser);
@@ -309,7 +305,9 @@ static scc_ast_stmt_t *parse_jump_statement(scc_parser_t *parser) {
static scc_ast_stmt_t *parse_expression_statement(scc_parser_t *parser) {
if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
return null;
scc_ast_stmt_t *stmt = ast_stmt_alloc();
scc_ast_stmt_expr_init(stmt, null);
return stmt;
}
scc_ast_expr_t *expr = scc_parse_expression(parser);
@@ -430,7 +428,9 @@ scc_ast_stmt_t *scc_parse_statement(scc_parser_t *parser) {
stmt = parse_expression_statement(parser);
RETURN:
scc_parser_reset(parser);
if (stmt) {
parser->sema_callbacks.on_stmt(parser->sema_callbacks.context,
stmt->base.type, stmt);
}
return stmt;
}

View File

@@ -248,6 +248,76 @@ static void test_parser_unit(void) {
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
// 整数字面量 10
scc_ast_expr_t lit10;
scc_ast_expr_literal_int_init(&lit10, "10", false);
// 变量声明 int x = 10;
scc_ast_decl_t x_decl;
scc_ast_decl_val_init(
&x_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", &lit10);
// 表达式 x + 1
scc_ast_expr_t x_ref1, lit1, add;
scc_ast_expr_identifier_init(&x_ref1, "x");
scc_ast_expr_literal_int_init(&lit1, "1", false);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &x_ref1, &lit1);
// 赋值 x = x + 1
scc_ast_expr_t x_ref2, assign;
scc_ast_expr_identifier_init(&x_ref2, "x");
scc_ast_expr_binary_init(&assign, SCC_AST_OP_ASSIGN, &x_ref2, &add);
// 表达式语句
scc_ast_stmt_t assign_stmt;
scc_ast_stmt_expr_init(&assign_stmt, &assign);
// return x
scc_ast_expr_t x_ref3;
scc_ast_expr_identifier_init(&x_ref3, "x");
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &x_ref3);
// 复合语句块
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&x_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items);
// 函数类型(返回 int无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null); // null 表示无参数
// 函数声明 int main() { ... }
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
// 翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
// 输入源代码
const char *input = "int main() {\n"
" int x = 10;\n"
" x = x + 1;\n"
" return x;\n"
"}\n";
// 比较解析结果与期望 AST
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
}
static void test_parser_expression(void) {
@@ -286,7 +356,9 @@ static void test_parser_expression(void) {
scc_ast_expr_vec_t args;
scc_vec_init(args);
scc_ast_expr_t call;
scc_ast_expr_call_init(&call, "f",
scc_ast_expr_t callee1;
scc_ast_expr_identifier_init(&callee1, "f");
scc_ast_expr_call_init(&call, &callee1,
&args); // 使用函数名target 在语义分析时填充
SCC_CHECK_AST(&call.base, "f()", scc_parse_expression);
@@ -298,8 +370,10 @@ static void test_parser_expression(void) {
scc_vec_init(args2);
scc_vec_push(args2, &arg1);
scc_vec_push(args2, &arg2);
scc_ast_expr_t callee2;
scc_ast_expr_identifier_init(&callee2, "f");
scc_ast_expr_t call2;
scc_ast_expr_call_init(&call2, "f", &args2);
scc_ast_expr_call_init(&call2, &callee2, &args2);
SCC_CHECK_AST(&call2.base, "f(1, x)", scc_parse_expression);
// 成员访问 .