- 将头文件中的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 - 更新初始化函数签名以使用新的转储接口类型
127 lines
3.7 KiB
C
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); }
|