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

@@ -0,0 +1,99 @@
#ifndef SCC_TREE_DUMP_H
#define SCC_TREE_DUMP_H
#include "scc_core_str.h"
#include "scc_core_vec.h"
typedef struct scc_tree_dump {
scc_str_t buf; // 字符串缓冲区
SCC_VEC(cbool) stack; // 缩进栈:每个元素表示该层是否为最后一个子节点
cbool use_color; // 是否启用颜色
cbool line_start; // 当前是否在行首(需要输出缩进)
// 可配置的缩进字符串
const char *vertical; // "| "
const char *branch; // "|-"
const char *last_branch; // "`-"
const char *space; // " "
// 颜色字符串(当 use_color 为 false 时为空字符串)
const char *node_color; // 节点名称颜色
const char *value_color; // 值颜色
const char *branch_color; // 分支符号颜色
const char *reset_color; // 重置颜色
} scc_tree_dump_t;
/**
* @brief 初始化树形输出器
* @param td 输出器指针
* @param use_color 是否使用 ANSI 颜色
*/
void scc_tree_dump_init(scc_tree_dump_t *td, cbool use_color);
/**
* @brief 释放输出器占用的资源
*/
void scc_tree_dump_drop(scc_tree_dump_t *td);
/**
* @brief 清空当前缓冲区,但保留已分配内存
*/
void scc_tree_dump_clear(scc_tree_dump_t *td);
/**
* @brief 获取当前构建的字符串(以 '\0' 结尾)
* @return 内部缓冲区指针,不可 free
*/
const char *scc_tree_dump_cstr(scc_tree_dump_t *td);
/**
* @brief 将缓冲区内容通过回调输出,并清空缓冲区
* @param output 输出回调函数,接收字符串指针、长度、用户数据
* @param user 用户数据
*/
void scc_tree_dump_flush(scc_tree_dump_t *td,
void (*output)(const char *str, usize len, void *user),
void *user);
/**
* @brief 开始一个新行(自动输出缩进)
* @note 通常不需要手动调用,因为 append 系列函数会自动处理
*/
void scc_tree_dump_begin_line(scc_tree_dump_t *td);
/**
* @brief 追加普通字符串(自动处理行首缩进)
*/
void scc_tree_dump_append(scc_tree_dump_t *td, const char *s);
/**
* @brief 格式化追加printf 风格)
*/
void scc_tree_dump_append_fmt(scc_tree_dump_t *td, const char *fmt, ...);
/**
* @brief 追加带节点颜色的文本
*/
#define scc_tree_dump_node(td, fmt, ...) \
scc_tree_dump_append_fmt(td, "%s" fmt "%s", (td)->node_color, \
##__VA_ARGS__, (td)->reset_color)
/**
* @brief 追加带值颜色的格式化文本
*/
#define scc_tree_dump_value(td, fmt, ...) \
scc_tree_dump_append_fmt(td, "%s" fmt "%s", (td)->value_color, \
##__VA_ARGS__, (td)->reset_color)
/**
* @brief 推入新层级
* @param is_last 该层级是否是父节点的最后一个子节点
*/
void scc_tree_dump_push(scc_tree_dump_t *td, cbool is_last);
/**
* @brief 弹出当前层级
*/
void scc_tree_dump_pop(scc_tree_dump_t *td);
#endif // SCC_TREE_DUMP_H

View File

@@ -1,119 +0,0 @@
#ifndef __SCC_TREE_DUMP_H__
#define __SCC_TREE_DUMP_H__
#include <scc_core.h>
#define SCC_TREE_DUMP_VERTICAL "| "
#define SCC_TREE_DUMP_BRANCH "|-"
#define SCC_TREE_DUMP_LAST_BRANCH "`-"
#define SCC_TREE_DUMP_SPACE " "
#define SCC_TREE_DUMP_NODE_COLOR ANSI_FG_BLUE
#define SCC_TREE_DUMP_VALUE_COLOR ANSI_FG_GREEN
#define SCC_TREE_DUMP_BRANCH_COLOR ANSI_FG_YELLOW
#define SCC_TREE_DUMP_RESET_COLOR ANSI_NONE
// #define ANSI_FMT
typedef SCC_VEC(cbool) scc_ast_dump_stack_t;
typedef void (*scc_tree_dump_output_t)(void *userdata, const char *fmt, ...);
typedef struct {
scc_ast_dump_stack_t stack; ///< 每层是否为最后子节点
cbool use_color; ///< 是否使用颜色输出
const char *vertical;
const char *branch;
const char *last_branch;
const char *space;
const char *node_color; ///< 节点类型颜色
const char *value_color; ///< 值颜色
const char *branch_color; ///< 分支符号颜色
const char *reset_color; ///< 重置颜色
scc_tree_dump_output_t output_func;
void *output_userdata;
} scc_tree_dump_ctx_t;
static inline void scc_tree_dump_ctx_init(scc_tree_dump_ctx_t *ctx,
cbool use_color,
scc_tree_dump_output_t output_func,
void *output_userdata) {
ctx->use_color = use_color;
scc_vec_init(ctx->stack);
ctx->vertical = SCC_TREE_DUMP_VERTICAL;
ctx->branch = SCC_TREE_DUMP_BRANCH;
ctx->last_branch = SCC_TREE_DUMP_LAST_BRANCH;
ctx->space = SCC_TREE_DUMP_SPACE;
ctx->node_color = use_color ? SCC_TREE_DUMP_NODE_COLOR : "";
ctx->value_color = use_color ? SCC_TREE_DUMP_VALUE_COLOR : "";
ctx->branch_color = use_color ? SCC_TREE_DUMP_BRANCH_COLOR : "";
ctx->reset_color = use_color ? SCC_TREE_DUMP_RESET_COLOR : "";
ctx->output_func = output_func;
ctx->output_userdata = output_userdata;
}
#define scc_tree_dump_printf(ctx, fmt, ...) \
(ctx)->output_func((ctx)->output_userdata, fmt, ##__VA_ARGS__)
static inline void scc_tree_dump_ctx_drop(scc_tree_dump_ctx_t *ctx) {
scc_vec_free(ctx->stack);
}
// 打印缩进
static inline void scc_tree_print_indent(scc_tree_dump_ctx_t *ctx) {
scc_vec_foreach(ctx->stack, i) {
cbool last_child = scc_vec_at(ctx->stack, i);
const char *data = null;
if (i + 1 == scc_vec_size(ctx->stack)) {
// 最后一层打印分支符号
data = last_child ? ctx->last_branch : ctx->branch;
} else {
data = last_child ? ctx->space : ctx->vertical;
}
Assert(data != null);
if (ctx->use_color) {
ctx->output_func(ctx->output_userdata, "%s%s%s", ctx->branch_color,
data, ctx->reset_color);
} else {
ctx->output_func(ctx->output_userdata, "%s", data);
}
}
}
#define SCC_TREE_DUMP_PRINT_COLORED(ctx, color, before_str, fmt, after_str, \
...) \
(ctx)->output_func((ctx)->output_userdata, \
before_str "%s" fmt "%s" after_str, \
(ctx)->use_color ? color : "", ##__VA_ARGS__, \
(ctx)->use_color ? ANSI_NONE : "");
#define SCC_TREE_DUMP_PRINT_AROUND(ctx, color, around_str, fmt, ...) \
SCC_TREE_DUMP_PRINT_COLORED(ctx, color, around_str, fmt, around_str, \
##__VA_ARGS__)
#define SCC_TREE_DUMP_PRINT_PURE(ctx, color, fmt, ...) \
SCC_TREE_DUMP_PRINT_COLORED(ctx, color, "", fmt, "", ##__VA_ARGS__)
// 推入新的层级到栈中
static inline void scc_tree_dump_push_level(scc_tree_dump_ctx_t *ctx,
cbool is_last_child) {
scc_vec_push(ctx->stack, is_last_child);
}
// 弹出当前层级
static inline void scc_tree_dump_pop_level(scc_tree_dump_ctx_t *ctx) {
(void)scc_vec_pop(ctx->stack);
}
// 获取当前层级深度
static inline usize scc_tree_dump_depth(scc_tree_dump_ctx_t *ctx) {
return scc_vec_size(ctx->stack);
}
#endif /* __SCC_TREE_DUMP_H__ */

View File

@@ -0,0 +1,126 @@
#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); }