- 添加 SCC_AST_DECL_LIST 节点类型用于表示声明列表 - 实现 scc_ast_decl_list_init 函数来初始化声明列表节点 - 重构 scc_parse_declaration 函数以支持逗号分隔的多个变量声明 - 分离类型说明符解析到独立的 scc_parse_declaration_specifiers 函数 - 支持 typedef 和多变量声明如 'int a, b;' 和 'int a = 1, b = 2;' - 在 ast_dump 中添加对声明列表节点的打印支持 refactor(ast): 统一使用 scc_vec_foreach 宏替换手动循环 - 将 ast_dump.c 中的多个手动索引循环改为使用 scc_vec_foreach - 提高代码可读性和安全性 - 避免索引越界错误 fix(parser): 修复语义分析中结构体符号表冲突 - 为结构体、联合体和枚举符号名添加前缀避免命名冲突 - 使用 '$S_'、'$U_'、'$E_' 前缀分别标识结构体、联合体和枚举 refactor(log): 统一终止处理方式 - 将 log_exit 替换为 log_abort 以更准确反映行为 - 更新相关依赖模块的实现 style(parser): 移除未使用的参数和清理代码 - 在 argparse.c 中添加 (void) 参数注释处理未使用的参数 - 清理 parse_expr.c 中未使用的函数声明 - 优化 parse_type.c 中的错误处理流程
85 lines
3.3 KiB
C
85 lines
3.3 KiB
C
#include <scc_sema.h>
|
|
#include <sema_symtab.h>
|
|
|
|
static void type_callback(void *context, scc_ast_node_type_t node_type,
|
|
void *node) {
|
|
scc_sema_symtab_t *sema_symtab = context;
|
|
(void)context;
|
|
(void)node_type;
|
|
(void)node;
|
|
return;
|
|
}
|
|
|
|
static void decl_callback(void *context, scc_ast_node_type_t node_type,
|
|
void *node) {
|
|
if (node_type == SCC_AST_UNKNOWN || node == null) {
|
|
return;
|
|
}
|
|
scc_sema_symtab_t *sema_symtab = context;
|
|
scc_ast_decl_t *decl = SCC_AST_CAST_TO(scc_ast_decl_t, node);
|
|
|
|
scc_ast_type_t *type = scc_malloc(sizeof(scc_ast_type_t));
|
|
Assert(type != null);
|
|
if (decl->name == null) {
|
|
return;
|
|
}
|
|
if (decl->base.type == SCC_AST_DECL_STRUCT) {
|
|
scc_ast_type_struct_init(type, decl->name, decl);
|
|
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_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_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);
|
|
}
|
|
return;
|
|
}
|
|
|
|
static scc_ast_type_t *got_type_callback(void *context, const char *name) {
|
|
scc_sema_symtab_t *sema_symtab = context;
|
|
scc_ast_node_t *node = scc_sema_symtab_lookup_symbol(sema_symtab, name);
|
|
if (SCC_AST_IS_A(scc_ast_type_t, node)) {
|
|
scc_ast_type_t *type = scc_malloc(sizeof(scc_ast_type_t));
|
|
*type = *(scc_ast_type_t *)node;
|
|
return type;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
void scc_sema_init(scc_sema_callbacks_t *callbacks) {
|
|
scc_sema_symtab_t *sema_symtab = scc_malloc(sizeof(scc_sema_symtab_t));
|
|
if (sema_symtab == null) {
|
|
LOG_FATAL("out of memory");
|
|
return;
|
|
}
|
|
callbacks->context = sema_symtab;
|
|
callbacks->on_decl = decl_callback;
|
|
callbacks->on_expr = null;
|
|
callbacks->on_stmt = null;
|
|
callbacks->on_type = type_callback;
|
|
callbacks->got_type = got_type_callback;
|
|
|
|
scc_sema_symtab_init(sema_symtab);
|
|
scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_va_list",
|
|
&scc_ast_builtin_type_va_list.base);
|
|
scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_size_t",
|
|
&scc_ast_builtin_type_long_long.base);
|
|
scc_sema_symtab_add_symbol(sema_symtab, "__scc_builtin_ptrdiff_t",
|
|
&scc_ast_builtin_type_long_long.base);
|
|
}
|
|
|
|
void scc_sema_drop(scc_sema_callbacks_t *callbacks) {}
|