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:
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user