#ifndef __SCC_TREE_DUMP_H__ #define __SCC_TREE_DUMP_H__ #include #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 #define SCC_TREE_DUMP_PRINT_COLORED(ctx, color, before_str, fmt, after_str, \ ...) \ scc_printf(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__) typedef SCC_VEC(cbool) scc_ast_dump_stack_t; 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_ctx_t; static inline void scc_tree_dump_ctx_init(scc_tree_dump_ctx_t *ctx, cbool use_color) { 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 : ""; } static inline void scc_tree_dump_ctx_drop(scc_tree_dump_ctx_t *ctx) { scc_vec_free(ctx->stack); } // 打印缩进 static 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) { scc_printf("%s%s%s", ctx->branch_color, data, ctx->reset_color); } else { scc_printf("%s", data); } } } // 推入新的层级到栈中 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__ */