Files
scc/libs/tree_dump/src/scc_tree_dump.c
zzy ca187c78f1 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
- 更新初始化函数签名以使用新的转储接口类型
2026-04-03 20:10:51 +08:00

127 lines
3.7 KiB
C

#include <scc_tree_dump.h>
#define DEFAULT_VERTICAL "| "
#define DEFAULT_BRANCH "|-"
#define DEFAULT_LAST_BRANCH "`-"
#define DEFAULT_SPACE " "
#define NODE_COLOR "\033[34m"
#define VALUE_COLOR "\033[32m"
#define BRANCH_COLOR "\033[33m"
#define RESET_COLOR "\033[0m"
void scc_tree_dump_init(scc_tree_dump_t *td, cbool use_color) {
scc_str_init(&td->buf);
scc_vec_init(td->stack);
td->use_color = use_color;
td->line_start = true;
td->vertical = DEFAULT_VERTICAL;
td->branch = DEFAULT_BRANCH;
td->last_branch = DEFAULT_LAST_BRANCH;
td->space = DEFAULT_SPACE;
td->node_color = use_color ? NODE_COLOR : "";
td->value_color = use_color ? VALUE_COLOR : "";
td->branch_color = use_color ? BRANCH_COLOR : "";
td->reset_color = use_color ? RESET_COLOR : "";
}
void scc_tree_dump_drop(scc_tree_dump_t *td) {
scc_str_drop(&td->buf);
scc_vec_free(td->stack);
}
void scc_tree_dump_clear(scc_tree_dump_t *td) {
scc_str_clear(&td->buf);
td->line_start = true;
}
const char *scc_tree_dump_cstr(scc_tree_dump_t *td) {
return scc_str_as_cstr(&td->buf);
}
void scc_tree_dump_flush(scc_tree_dump_t *td,
void (*output)(const char *str, usize len, void *user),
void *user) {
if (td->buf.size > 1 && output) {
output(td->buf.data, td->buf.size - 1, user);
}
scc_tree_dump_clear(td);
}
void scc_tree_dump_begin_line(scc_tree_dump_t *td) {
if (!td->line_start) {
// 如果不在行首,先换行(表示上一行结束)
if (td->buf.size > 1) {
scc_str_append_ch(&td->buf, '\n');
}
}
// 输出缩进
usize depth = scc_vec_size(td->stack);
for (usize i = 0; i < depth; i++) {
cbool last = scc_vec_at(td->stack, i);
const char *prefix;
if (i + 1 == depth) {
prefix = last ? td->last_branch : td->branch;
} else {
prefix = last ? td->space : td->vertical;
}
if (td->use_color) {
scc_str_append_fmt(&td->buf, "%s%s%s", td->branch_color, prefix,
td->reset_color);
} else {
scc_str_append_cstr(&td->buf, prefix, scc_strlen(prefix));
}
}
td->line_start = false;
}
void scc_tree_dump_append(scc_tree_dump_t *td, const char *s) {
if (td->line_start) {
scc_tree_dump_begin_line(td);
}
scc_str_append_cstr(&td->buf, s, scc_strlen(s));
}
void scc_tree_dump_append_fmt(scc_tree_dump_t *td, const char *fmt, ...) {
if (td->line_start) {
scc_tree_dump_begin_line(td);
}
va_list args;
va_start(args, fmt);
// 计算所需长度
va_list args_copy;
va_copy(args_copy, args);
usize len = scc_vsnprintf(null, 0, fmt, args_copy);
va_end(args_copy);
if (len == 0) {
va_end(args);
return;
}
// 确保缓冲区容量足够
if (td->buf.size + len + 1 > td->buf.cap) {
usize new_cap = td->buf.cap;
while (new_cap < td->buf.size + len + 1) {
new_cap = new_cap ? new_cap * 2 : 16;
}
char *new_data = (char *)scc_realloc(td->buf.data, new_cap);
Assert(new_data != null);
td->buf.data = new_data;
td->buf.cap = new_cap;
}
scc_vsnprintf(td->buf.data + td->buf.size - (td->buf.size == 0 ? 0 : 1),
len + 1, fmt, args);
va_end(args);
if (td->buf.size == 0) {
td->buf.size = 1;
}
td->buf.size += len;
td->buf.data[td->buf.size - 1] = '\0';
}
void scc_tree_dump_push(scc_tree_dump_t *td, cbool is_last) {
scc_vec_push(td->stack, is_last);
}
void scc_tree_dump_pop(scc_tree_dump_t *td) { (void)scc_vec_pop(td->stack); }