feat(ast): 更新AST dump功能以使用新的树转储接口

- 将头文件中的tree_dump.h替换为scc_tree_dump.h
- 修改函数签名将scc_tree_dump_ctx_t改为scc_tree_dump_t
- 移除过时的宏定义和内联函数实现
- 使用新的scc_tree_dump_* API替代旧的PRINT_*宏
- 简化类型、表达式、语句和声明的转储逻辑
- 统一使用新的树转储接口进行节点和值的输出

feat(ast2ir): 实现逻辑运算符和一元运算符的IR转换

- 添加scc_ast2ir_logical_expr函数处理&&和||运算符
- 实现短路求值逻辑,包含分支控制流
- 添加对一元正号运算符的支持
- 实现取地址和间接寻址运算符
- 添加字符字面量解析支持转义序列

fix(ir): 修复字符串常量构建中的长度计算错误

- 修正数组长度计算从len+1改为len-1
- 调整字符串内容复制逻辑跳过引号边界
- 修正内存分配大小与实际数据长度匹配

refactor(ir): 更新IR转储模块使用统一的树转储接口

- 将IR转储上下文中的tree_dump_ctx_t替换为scc_tree_dump_t
- 更新初始化函数签名以使用新的转储接口类型
This commit is contained in:
zzy
2026-04-03 20:10:51 +08:00
parent 78e7c800ba
commit ca187c78f1
42 changed files with 1264 additions and 1212 deletions

View File

@@ -133,8 +133,8 @@ void scc_pproc_parse_function_macro(scc_pproc_t *pp,
if (idx++ % 2 != 0) {
LOG_FATAL("ERROR");
}
scc_cstring_t va_args = scc_cstring_from_cstr("__VA_ARGS__");
scc_cstring_free(&arg->lexeme);
scc_str_t va_args = scc_str_from_cstr("__VA_ARGS__");
scc_str_drop(&arg->lexeme);
arg->lexeme = va_args;
scc_vec_push(macro->params, *arg);
} else if (scc_get_tok_subtype(arg->type) ==
@@ -249,12 +249,12 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
SCC_ERROR(tok.loc, "invalid preprocessing directive");
goto ERROR;
}
int ret = keyword_cmp(scc_cstring_as_cstr(&tok.lexeme),
scc_cstring_len(&tok.lexeme));
int ret =
keyword_cmp(scc_str_as_cstr(&tok.lexeme), scc_str_len(&tok.lexeme));
if (ret == -1) {
scc_lexer_tok_drop(&tok);
SCC_ERROR(tok.loc, "expected preprocessor directive name, got '%s'",
scc_cstring_as_cstr(&tok.lexeme));
scc_str_as_cstr(&tok.lexeme));
goto ERROR;
}
scc_tok_type_t type = keywords[ret].tok_type;
@@ -362,7 +362,7 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
return; \
} \
if (scc_get_tok_subtype(tok.type) == SCC_TOK_SUBTYPE_LITERAL) { \
func_name(tok.loc, "%s", scc_cstring_as_cstr(&tok.lexeme)); \
func_name(tok.loc, "%s", scc_str_as_cstr(&tok.lexeme)); \
} \
scc_lexer_tok_drop(&tok); \
} \
@@ -382,6 +382,6 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) {
break;
}
ERROR:
LOG_WARN("Unhandled directive: %s", scc_cstring_as_cstr(&tok.lexeme));
LOG_WARN("Unhandled directive: %s", scc_str_as_cstr(&tok.lexeme));
scc_lexer_skip_until_newline(pp->cur_ring);
}

View File

@@ -18,8 +18,8 @@ static inline scc_lexer_tok_t scc_pproc_tok_copy(scc_pproc_expand_t *ctx,
static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
scc_lexer_tok_vec_t *arg_tokens) {
// WRITE BY AI
scc_cstring_t str = scc_cstring_create();
scc_cstring_append_ch(&str, '\"'); // 左引号
scc_str_t str = scc_str_empty();
scc_str_append_ch(&str, '\"'); // 左引号
int need_space = 0; // 是否需要插入空格
scc_lexer_tok_t *tok = null;
@@ -32,7 +32,7 @@ static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
// 需要空格且当前不是第一个有效token插入一个空格
if (need_space && i > 0) {
scc_cstring_append_ch(&str, ' ');
scc_str_append_ch(&str, ' ');
}
// 对字符串/字符常量内的 " 和 \ 进行转义
@@ -41,10 +41,10 @@ static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
// 注意lex包含两端的引号需要跳过首尾转义内部字符
// 简化:暂不处理内部转义,直接追加
}
scc_cstring_append(&str, &tok->lexeme);
scc_str_append(&str, &tok->lexeme);
need_space = 0;
}
scc_cstring_append_ch(&str, '\"'); // 右引号
scc_str_append_ch(&str, '\"'); // 右引号
scc_lexer_tok_t result;
result.type = SCC_TOK_STRING_LITERAL;
@@ -60,19 +60,19 @@ static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
static scc_lexer_tok_t concatenate_tokens(scc_pproc_expand_t *ctx,
const scc_lexer_tok_t *left,
const scc_lexer_tok_t *right) {
scc_cstring_t new_lex = scc_cstring_from_cstr("");
scc_str_t new_lex = scc_str_from_cstr("");
if (left != null) {
scc_cstring_append(&new_lex, &left->lexeme);
scc_str_append(&new_lex, &left->lexeme);
}
if (right != null) {
scc_cstring_append(&new_lex, &right->lexeme);
scc_str_append(&new_lex, &right->lexeme);
}
scc_lexer_t lexer;
scc_sstream_t sstream;
// new_lex 所有权转移
scc_sstream_init_by_buffer(&sstream, scc_cstring_as_cstr(&new_lex),
scc_cstring_len(&new_lex), true, 8);
scc_sstream_init_by_buffer(&sstream, scc_str_as_cstr(&new_lex),
scc_str_len(&new_lex), true, 8);
scc_lexer_init(&lexer, scc_sstream_to_ring(&sstream));
scc_lexer_tok_ring_t *ring = scc_lexer_to_ring(&lexer, 8, true);
@@ -269,7 +269,7 @@ expand_arguments(scc_pproc_macro_extened_params_t *expanded_params,
scc_vec_init(expanded_param);
scc_vec_foreach(splite_param, j) {
scc_lexer_tok_t tok = scc_vec_at(splite_param, j);
tok.lexeme = scc_cstring_copy(&tok.lexeme);
tok.lexeme = scc_str_copy(&tok.lexeme);
scc_vec_push(expanded_param, tok);
}
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(&expanded_param);
@@ -353,8 +353,8 @@ RETURN:
static int find_params(const scc_lexer_tok_t *tok,
const scc_pproc_macro_t *macro) {
scc_vec_foreach(macro->params, j) {
if (scc_cstring_cmp(&(tok->lexeme),
&(scc_vec_at(macro->params, j).lexeme)) == 0) {
if (scc_str_equal(&(tok->lexeme),
&(scc_vec_at(macro->params, j).lexeme)) == 0) {
return j;
}
}
@@ -437,8 +437,8 @@ static inline void expand_function_macro(scc_pproc_expand_t *ctx,
scc_lexer_tok_t tok =
scc_pproc_tok_copy(ctx, &scc_vec_at(macro->replaces, i));
if (tok.type == SCC_TOK_BLANK) {
scc_cstring_free(&tok.lexeme);
tok.lexeme = scc_cstring_from_cstr(" ");
scc_str_drop(&tok.lexeme);
tok.lexeme = scc_str_from_cstr(" ");
scc_vec_push(tok_buffer, tok);
continue;
}
@@ -449,8 +449,8 @@ static inline void expand_function_macro(scc_pproc_expand_t *ctx,
int right_idx = got_right_non_blank(i, &macro->replaces);
if (right_idx >= (int)macro->replaces.size) {
LOG_WARN("generate empty stringify");
scc_cstring_free(&tok.lexeme);
tok.lexeme = scc_cstring_from_cstr("");
scc_str_drop(&tok.lexeme);
tok.lexeme = scc_str_from_cstr("");
scc_vec_push(tok_buffer, tok);
break;
}
@@ -491,7 +491,7 @@ static inline void expand_function_macro(scc_pproc_expand_t *ctx,
scc_vec_size(right_vec) ? &scc_vec_at(right_vec, 0) : null;
// GNU ## extention
if (scc_strcmp(scc_cstring_as_cstr(&(right_tok->lexeme)),
if (scc_strcmp(scc_str_as_cstr(&(right_tok->lexeme)),
"__VA_ARGS__") == 0) {
if (scc_vec_size(right_vec) == 0) {
concact(ctx, &tok_buffer, right, true);
@@ -550,8 +550,8 @@ static inline void expand_object_macro(scc_pproc_expand_t *ctx,
scc_pproc_tok_copy(ctx, &scc_vec_at(macro->replaces, i));
if (tok.type == SCC_TOK_BLANK) {
// FIXME using function to warpper it
scc_cstring_free(&tok.lexeme);
tok.lexeme = scc_cstring_from_cstr(" ");
scc_str_drop(&tok.lexeme);
tok.lexeme = scc_str_from_cstr(" ");
} else if (tok.type == SCC_TOK_SHARP_SHARP) {
// ## contact
scc_lexer_tok_drop(&tok);
@@ -635,7 +635,7 @@ void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx) {
}
if (expand_ctx->need_parse_defined &&
scc_strcmp(scc_cstring_as_cstr(&tok.lexeme), "defined") == 0) {
scc_strcmp(scc_str_as_cstr(&tok.lexeme), "defined") == 0) {
scc_pos_t pos = tok.loc;
scc_lexer_tok_drop(&tok);
if (parse_defined(expand_ctx, &pos)) {
@@ -679,19 +679,19 @@ void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx) {
}
// FIXME 这可能不符合c语义
case SCC_PP_MACRO_BUILTIN__FILE__:
scc_cstring_free(&tok.lexeme);
scc_cstring_append_ch(&tok.lexeme, '"');
scc_cstring_append_cstr(&tok.lexeme, tok.loc.name,
scc_strlen(tok.loc.name));
scc_cstring_append_ch(&tok.lexeme, '"');
scc_str_drop(&tok.lexeme);
scc_str_append_ch(&tok.lexeme, '"');
scc_str_append_cstr(&tok.lexeme, tok.loc.name,
scc_strlen(tok.loc.name));
scc_str_append_ch(&tok.lexeme, '"');
tok.type = SCC_TOK_STRING_LITERAL;
scc_vec_push(expand_ctx->output, tok);
break;
case SCC_PP_MACRO_BUILTIN__LINE__:
scc_cstring_free(&tok.lexeme);
scc_str_drop(&tok.lexeme);
char *buff = scc_malloc(32);
scc_snprintf(buff, 32, "%zu", tok.loc.line);
tok.lexeme = scc_cstring_from_cstr(buff);
tok.lexeme = scc_str_from_cstr(buff);
scc_free(buff);
tok.type = SCC_TOK_INT_LITERAL;
scc_vec_push(expand_ctx->output, tok);

View File

@@ -148,8 +148,8 @@ static int parse_constant_condition(scc_pproc_t *pp,
if (tok.type == SCC_TOK_INT_LITERAL) {
// got int
const char *intstr = scc_cstring_as_cstr(&tok.lexeme);
for (int i = scc_cstring_len(&tok.lexeme) - 1; i >= 0; i--) {
const char *intstr = scc_str_as_cstr(&tok.lexeme);
for (int i = scc_str_len(&tok.lexeme) - 1; i >= 0; i--) {
res = res * 10 + intstr[i] - '0';
}
} else {

View File

@@ -2,9 +2,9 @@
#include <scc_core_ring.h>
#include <scc_pproc.h>
static int switch_file_stack(scc_pproc_t *pp, scc_cstring_t *fname,
scc_pos_t *pos, int is_system) {
scc_cstring_t fpath = scc_cstring_create();
static int switch_file_stack(scc_pproc_t *pp, scc_str_t *fname, scc_pos_t *pos,
int is_system) {
scc_str_t fpath = scc_str_empty();
int ret = 0;
const char *org_fname = pos->name;
@@ -12,10 +12,10 @@ static int switch_file_stack(scc_pproc_t *pp, scc_cstring_t *fname,
if (!is_system) {
const char parent[] = "/../";
// FIXME maybe it can eazy
scc_cstring_append_cstr(&fpath, org_fname, scc_strlen(org_fname));
scc_cstring_append_cstr(&fpath, parent, scc_strlen(parent));
scc_cstring_append(&fpath, fname);
ret = scc_fexists(scc_cstring_as_cstr(&fpath));
scc_str_append_cstr(&fpath, org_fname, scc_strlen(org_fname));
scc_str_append_cstr(&fpath, parent, scc_strlen(parent));
scc_str_append(&fpath, fname);
ret = scc_fexists(scc_str_as_cstr(&fpath));
if (ret == true) {
goto FOPEN;
}
@@ -23,17 +23,17 @@ static int switch_file_stack(scc_pproc_t *pp, scc_cstring_t *fname,
/* system default path and -I includes path */
scc_vec_foreach(pp->include_paths, i) {
scc_cstring_free(&fpath);
scc_cstring_t *syspath = &scc_vec_at(pp->include_paths, i);
scc_cstring_append(&fpath, syspath);
scc_cstring_append_ch(&fpath, '/');
scc_cstring_append(&fpath, fname);
ret = scc_fexists(scc_cstring_as_cstr(&fpath));
scc_str_drop(&fpath);
scc_str_t *syspath = &scc_vec_at(pp->include_paths, i);
scc_str_append(&fpath, syspath);
scc_str_append_ch(&fpath, '/');
scc_str_append(&fpath, fname);
ret = scc_fexists(scc_str_as_cstr(&fpath));
if (ret == true) {
goto FOPEN;
}
}
SCC_ERROR(*pos, "include file '%s' not found", scc_cstring_as_cstr(fname));
SCC_ERROR(*pos, "include file '%s' not found", scc_str_as_cstr(fname));
return -1;
FOPEN:
if ((int)scc_vec_size(pp->file_stack) >= pp->config.max_include_depth) {
@@ -44,7 +44,7 @@ FOPEN:
scc_pproc_file_t *file = scc_malloc(sizeof(scc_pproc_file_t));
Assert(file != null);
if (scc_sstream_init(&(file->sstream), scc_cstring_as_cstr(&fpath), 1024)) {
if (scc_sstream_init(&(file->sstream), scc_str_as_cstr(&fpath), 1024)) {
return -1;
}
scc_lexer_init(&(file->lexer), scc_sstream_to_ring(&(file->sstream)));
@@ -62,21 +62,21 @@ void scc_pproc_parse_include(scc_pproc_t *pp, scc_lexer_tok_t *include_tok,
scc_pos_t pos = include_tok->loc;
scc_lexer_tok_drop(include_tok);
scc_cstring_t line = scc_cstring_create();
scc_str_t line = scc_str_empty();
while (1) {
scc_ring_next_consume(*tok_ring, tok, ok);
if (!ok)
break;
if (scc_get_tok_subtype(tok.type) != SCC_TOK_SUBTYPE_EMPTYSPACE &&
scc_get_tok_subtype(tok.type) != SCC_TOK_SUBTYPE_COMMENT) {
scc_cstring_append(&line, &tok.lexeme);
scc_str_append(&line, &tok.lexeme);
}
scc_lexer_tok_drop(&tok);
}
scc_ring_free(*tok_ring);
const char *includename = scc_cstring_as_cstr(&line);
int len = scc_cstring_len(&line);
const char *includename = scc_str_as_cstr(&line);
int len = scc_str_len(&line);
if (len < 2) {
goto ERROR;
} else if (len == 2) {
@@ -94,19 +94,19 @@ void scc_pproc_parse_include(scc_pproc_t *pp, scc_lexer_tok_t *include_tok,
goto ERROR;
}
}
scc_cstring_t fname = scc_cstring_create();
scc_str_t fname = scc_str_empty();
for (int i = 1; i < len - 1; i++) {
scc_cstring_append_ch(&fname, includename[i]);
scc_str_append_ch(&fname, includename[i]);
}
scc_cstring_free(&line);
scc_str_drop(&line);
int is_system = includename[0] == '<';
if (switch_file_stack(pp, &fname, &pos, is_system)) {
// LOG_ERROR()
}
scc_cstring_free(&fname);
scc_str_drop(&fname);
return;
ERROR:
SCC_ERROR(pos,
"invalid include filename, expected \"FILENAME\" or <FILENAME>");
scc_cstring_free(&line);
scc_str_drop(&line);
}

View File

@@ -1,7 +1,7 @@
#include <pproc_macro.h>
// 创建宏对象
scc_pproc_macro_t *scc_pproc_macro_new(const scc_cstring_t *name,
scc_pproc_macro_t *scc_pproc_macro_new(const scc_str_t *name,
scc_pproc_macro_type_t type) {
scc_pproc_macro_t *macro = scc_malloc(sizeof(scc_pproc_macro_t));
if (!macro) {
@@ -9,7 +9,7 @@ scc_pproc_macro_t *scc_pproc_macro_new(const scc_cstring_t *name,
return null;
}
macro->name = scc_cstring_copy(name);
macro->name = scc_str_copy(name);
macro->type = type;
scc_vec_init(macro->params);
scc_vec_init(macro->replaces);
@@ -34,14 +34,14 @@ void scc_pproc_macro_drop(scc_pproc_macro_t *macro) {
}
scc_vec_free(macro->replaces);
scc_cstring_free(&macro->name);
scc_str_drop(&macro->name);
scc_free(macro);
}
// 添加对象宏
cbool scc_pproc_add_object_macro(scc_pproc_macro_table_t *macros,
const scc_cstring_t *name,
const scc_str_t *name,
const scc_lexer_tok_vec_t *replacement) {
if (!macros || !name || !replacement)
return false;
@@ -56,7 +56,7 @@ cbool scc_pproc_add_object_macro(scc_pproc_macro_table_t *macros,
scc_pproc_macro_t *existing =
scc_hashtable_get(&macros->table, &macro->name);
if (existing) {
LOG_WARN("Redefining macro: %s", scc_cstring_as_cstr(&macro->name));
LOG_WARN("Redefining macro: %s", scc_str_as_cstr(&macro->name));
scc_pproc_macro_drop(existing);
}
@@ -66,7 +66,7 @@ cbool scc_pproc_add_object_macro(scc_pproc_macro_table_t *macros,
// 添加函数宏
cbool scc_pproc_add_function_macro(scc_pproc_macro_table_t *macros,
const scc_cstring_t *name,
const scc_str_t *name,
const scc_lexer_tok_vec_t *params,
const scc_lexer_tok_vec_t *replacement) {
if (!macros || !name || !params || !replacement)
@@ -84,7 +84,7 @@ cbool scc_pproc_add_function_macro(scc_pproc_macro_table_t *macros,
scc_pproc_macro_t *existing =
scc_hashtable_get(&macros->table, &macro->name);
if (existing) {
LOG_WARN("Redefining macro: %s", scc_cstring_as_cstr(&macro->name));
LOG_WARN("Redefining macro: %s", scc_str_as_cstr(&macro->name));
scc_pproc_macro_drop(existing);
}
@@ -96,10 +96,10 @@ cbool scc_pproc_add_function_macro(scc_pproc_macro_table_t *macros,
scc_pproc_macro_t *scc_pproc_macro_table_set(scc_pproc_macro_table_t *pp,
scc_pproc_macro_t *macro) {
Assert(pp != null && macro != null && scc_cstring_len(&macro->name) != 0);
Assert(pp != null && macro != null && scc_str_len(&macro->name) != 0);
scc_pproc_macro_t *old = scc_hashtable_set(&pp->table, &macro->name, macro);
if (old && old != macro) {
LOG_WARN("same macro name `%s`", scc_cstring_as_cstr(&macro->name));
LOG_WARN("same macro name `%s`", scc_str_as_cstr(&macro->name));
scc_pproc_macro_drop(old);
}
return macro;
@@ -107,13 +107,13 @@ scc_pproc_macro_t *scc_pproc_macro_table_set(scc_pproc_macro_table_t *pp,
// 查找宏定义
scc_pproc_macro_t *scc_pproc_macro_table_get(scc_pproc_macro_table_t *pp,
const scc_cstring_t *name) {
const scc_str_t *name) {
return scc_hashtable_get(&pp->table, name);
}
// 从预处理器中删除宏
cbool scc_pproc_macro_table_remove(scc_pproc_macro_table_t *pp,
const scc_cstring_t *name) {
const scc_str_t *name) {
if (!pp || !name)
return false;
@@ -127,18 +127,18 @@ cbool scc_pproc_macro_table_remove(scc_pproc_macro_table_t *pp,
}
static u32 hash_func(const void *key) {
const scc_cstring_t *string = (const scc_cstring_t *)key;
return scc_strhash32(scc_cstring_as_cstr(string));
const scc_str_t *string = (const scc_str_t *)key;
return scc_strhash32(scc_str_as_cstr(string));
}
static int hash_cmp(const void *key1, const void *key2) {
const scc_cstring_t *str1 = (const scc_cstring_t *)key1;
const scc_cstring_t *str2 = (const scc_cstring_t *)key2;
const scc_str_t *str1 = (const scc_str_t *)key1;
const scc_str_t *str2 = (const scc_str_t *)key2;
if (str1->size != str2->size) {
return str1->size - str2->size;
}
return scc_strcmp(scc_cstring_as_cstr(str1), scc_cstring_as_cstr(str2));
return scc_strcmp(scc_str_as_cstr(str1), scc_str_as_cstr(str2));
}
void scc_pproc_marco_table_init(scc_pproc_macro_table_t *macros) {

View File

@@ -110,8 +110,7 @@ void scc_pproc_add_builtin_macros(scc_pproc_macro_table_t *macro_table) {
{"__LINE__", SCC_PP_MACRO_BUILTIN__LINE__},
};
for (usize i = 0; i < SCC_ARRLEN(builin_table); i += 1) {
scc_cstring_t builtin_name =
scc_cstring_from_cstr(builin_table[i].name);
scc_str_t builtin_name = scc_str_from_cstr(builin_table[i].name);
scc_pproc_macro_t *builtin =
scc_pproc_macro_new(&builtin_name, builin_table[i].type);
scc_pproc_macro_table_set(macro_table, builtin);
@@ -146,7 +145,7 @@ CONTINUE:
}
if (ret && scc_get_tok_subtype(tok->type) == SCC_TOK_SUBTYPE_INVALID) {
PanicFmt("Invalid token: %s", scc_cstring_as_cstr(&tok->lexeme));
PanicFmt("Invalid token: %s", scc_str_as_cstr(&tok->lexeme));
}
if (ret && !pp->ring_need_comment &&
scc_get_tok_subtype(tok->type) == SCC_TOK_SUBTYPE_COMMENT) {
@@ -180,7 +179,7 @@ void scc_pproc_drop(scc_pproc_t *pp) {
scc_ring_free(pp->expanded_ring);
scc_vec_foreach(pp->include_paths, i) {
scc_cstring_free(&scc_vec_at(pp->include_paths, i));
scc_str_drop(&scc_vec_at(pp->include_paths, i));
}
scc_vec_free(pp->include_paths);