feat(pproc): 修改宏展开器以支持连续函数式宏调用

修改了预处理器宏展开功能,将输出类型从环形缓冲区改为向量,
并实现了对连续函数式宏调用的支持。现在可以正确处理像
g(z) -> f(x * (z)) 这样的宏替换场景,其中标识符可能被重新
定义为新的函数式宏。

BREAKING CHANGE: 函数签名 scc_pproc_expand_by_vec 的输出参数
从 scc_lexer_tok_ring_t* 改为 scc_lexer_tok_vec_t*
This commit is contained in:
zzy
2026-03-01 14:23:17 +08:00
parent 8cbb9e6987
commit 60cdfd2c33
4 changed files with 67 additions and 12 deletions

View File

@@ -29,7 +29,7 @@ void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
const scc_pproc_macro_t *macro);
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
scc_lexer_tok_vec_t *input,
scc_lexer_tok_ring_t *output,
scc_lexer_tok_vec_t *output,
cbool need_parse_defined);
#endif /* __SCC_PPROC_EXPAND_H__ */

View File

@@ -168,8 +168,10 @@ static void scc_pproc_parse_line_and_expand(scc_pproc_t *pp,
if (tok.type == SCC_TOK_ENDLINE)
break;
}
scc_pproc_expand_by_vec(&pp->macro_table, &org_toks, out_ring,
scc_lexer_tok_vec_t out_vec;
scc_pproc_expand_by_vec(&pp->macro_table, &org_toks, &out_vec,
need_parse_defined);
*out_ring = scc_lexer_array_to_ring(&out_vec);
}
/*

View File

@@ -2,6 +2,10 @@
#include <scc_lexer_utils.h>
#include <scc_pproc.h>
static void rescan(scc_pproc_expand_t *expand_ctx,
const scc_pproc_macro_t *macro,
scc_lexer_tok_vec_t *tok_buffer);
static scc_lexer_tok_t stringify_argument(scc_lexer_tok_vec_t *arg_tokens) {
// WRITE BY AI
scc_cstring_t str = scc_cstring_create();
@@ -104,13 +108,26 @@ void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
scc_vec_push(expaned_buffer, tok);
scc_pproc_parse_macro_arguments(input, &expaned_buffer, true);
}
while (1) {
scc_ring_peek(*input, tok, ok);
if (ok == false) {
break;
}
if (tok.type == SCC_TOK_L_PAREN) {
scc_pproc_parse_macro_arguments(input, &expaned_buffer, true);
} else {
break;
}
}
scc_pproc_expand_by_vec(macro_table, &expaned_buffer, output, false);
scc_lexer_tok_vec_t output_vec;
scc_pproc_expand_by_vec(macro_table, &expaned_buffer, &output_vec, false);
*output = scc_lexer_array_to_ring(&output_vec);
}
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
scc_lexer_tok_vec_t *input,
scc_lexer_tok_ring_t *output,
scc_lexer_tok_vec_t *output,
cbool need_parse_defined) {
scc_pproc_expand_t ctx;
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(input);
@@ -124,7 +141,7 @@ void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
scc_pproc_marco_table_init(ctx.expanded_set);
scc_pproc_expand_macro(&ctx);
*output = scc_lexer_array_to_ring(&ctx.output);
*output = ctx.output;
scc_pproc_macro_table_drop(ctx.expanded_set);
}
@@ -240,17 +257,51 @@ static void rescan(scc_pproc_expand_t *expand_ctx,
scc_lexer_tok_vec_t *tok_buffer) {
scc_pproc_expand_t rescan_ctx;
disable(expand_ctx, macro);
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(tok_buffer);
scc_copy_expand(expand_ctx, &rescan_ctx, &ring);
disable(expand_ctx, macro);
scc_pproc_expand_macro(&rescan_ctx);
enable(expand_ctx, macro);
scc_ring_free(ring);
scc_vec_foreach(rescan_ctx.output, i) {
scc_vec_push(expand_ctx->output, scc_vec_at(rescan_ctx.output, i));
}
enable(expand_ctx, macro);
if (scc_vec_size(expand_ctx->output) == 0) {
return;
}
scc_lexer_tok_t *end_tok =
&scc_vec_at(expand_ctx->output, scc_vec_size(expand_ctx->output) - 1);
if (scc_get_tok_subtype(end_tok->type) != SCC_TOK_SUBTYPE_IDENTIFIER) {
return;
}
scc_pproc_macro_t *end_macro =
scc_pproc_macro_table_get(expand_ctx->macro_table, &end_tok->lexeme);
if (end_macro == null || end_macro->type != SCC_PP_MACRO_FUNCTION) {
return;
}
int ok = false;
scc_lexer_tok_t tok;
scc_ring_peek(*expand_ctx->input, tok, ok);
if (ok && tok.type == SCC_TOK_L_PAREN) {
scc_lexer_tok_vec_t expaned_buffer;
scc_vec_init(expaned_buffer);
scc_vec_push(expaned_buffer, scc_vec_pop(expand_ctx->output));
scc_pproc_parse_macro_arguments(expand_ctx->input, &expaned_buffer,
true);
scc_lexer_tok_vec_t output = {0};
scc_pproc_expand_by_vec(expand_ctx->macro_table, &expaned_buffer,
&output, expand_ctx->need_parse_defined);
scc_vec_foreach(output, i) {
scc_vec_push(expand_ctx->output, scc_vec_at(output, i));
}
}
}
static int find_params(const scc_lexer_tok_t *tok,

View File

@@ -172,10 +172,12 @@ static void test_define_nested_macros(void) {
"f(x(0) * (f(x(0) * (x(0)))))\n"
"f(x(0) * (f(x(0) * (a))))\n");
TEST_CASE("NO NAME");
CHECK_PP_OUTPUT_EXACT("#define f() int\n"
"f()\n",
"int\n");
TEST_CASE("replace got new function-like macro");
CHECK_PP_OUTPUT_EXACT("#define f(a) f(x * (a))\n"
"#define g f\n"
"#define x 2\n"
"g(z)\n",
"f(2 * (z))\n");
}
static void test_undef_macros(void) {