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);
|
const scc_pproc_macro_t *macro);
|
||||||
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
|
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
|
||||||
scc_lexer_tok_vec_t *input,
|
scc_lexer_tok_vec_t *input,
|
||||||
scc_lexer_tok_ring_t *output,
|
scc_lexer_tok_vec_t *output,
|
||||||
cbool need_parse_defined);
|
cbool need_parse_defined);
|
||||||
|
|
||||||
#endif /* __SCC_PPROC_EXPAND_H__ */
|
#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)
|
if (tok.type == SCC_TOK_ENDLINE)
|
||||||
break;
|
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);
|
need_parse_defined);
|
||||||
|
*out_ring = scc_lexer_array_to_ring(&out_vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
#include <scc_lexer_utils.h>
|
#include <scc_lexer_utils.h>
|
||||||
#include <scc_pproc.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) {
|
static scc_lexer_tok_t stringify_argument(scc_lexer_tok_vec_t *arg_tokens) {
|
||||||
// WRITE BY AI
|
// WRITE BY AI
|
||||||
scc_cstring_t str = scc_cstring_create();
|
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_vec_push(expaned_buffer, tok);
|
||||||
scc_pproc_parse_macro_arguments(input, &expaned_buffer, true);
|
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,
|
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
|
||||||
scc_lexer_tok_vec_t *input,
|
scc_lexer_tok_vec_t *input,
|
||||||
scc_lexer_tok_ring_t *output,
|
scc_lexer_tok_vec_t *output,
|
||||||
cbool need_parse_defined) {
|
cbool need_parse_defined) {
|
||||||
scc_pproc_expand_t ctx;
|
scc_pproc_expand_t ctx;
|
||||||
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(input);
|
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_marco_table_init(ctx.expanded_set);
|
||||||
scc_pproc_expand_macro(&ctx);
|
scc_pproc_expand_macro(&ctx);
|
||||||
*output = scc_lexer_array_to_ring(&ctx.output);
|
*output = ctx.output;
|
||||||
scc_pproc_macro_table_drop(ctx.expanded_set);
|
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_lexer_tok_vec_t *tok_buffer) {
|
||||||
scc_pproc_expand_t rescan_ctx;
|
scc_pproc_expand_t rescan_ctx;
|
||||||
|
|
||||||
disable(expand_ctx, macro);
|
|
||||||
|
|
||||||
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(tok_buffer);
|
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(tok_buffer);
|
||||||
scc_copy_expand(expand_ctx, &rescan_ctx, &ring);
|
scc_copy_expand(expand_ctx, &rescan_ctx, &ring);
|
||||||
|
|
||||||
|
disable(expand_ctx, macro);
|
||||||
scc_pproc_expand_macro(&rescan_ctx);
|
scc_pproc_expand_macro(&rescan_ctx);
|
||||||
|
enable(expand_ctx, macro);
|
||||||
|
|
||||||
scc_ring_free(ring);
|
scc_ring_free(ring);
|
||||||
scc_vec_foreach(rescan_ctx.output, i) {
|
scc_vec_foreach(rescan_ctx.output, i) {
|
||||||
scc_vec_push(expand_ctx->output, scc_vec_at(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,
|
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) * (x(0)))))\n"
|
||||||
"f(x(0) * (f(x(0) * (a))))\n");
|
"f(x(0) * (f(x(0) * (a))))\n");
|
||||||
|
|
||||||
TEST_CASE("NO NAME");
|
TEST_CASE("replace got new function-like macro");
|
||||||
CHECK_PP_OUTPUT_EXACT("#define f() int\n"
|
CHECK_PP_OUTPUT_EXACT("#define f(a) f(x * (a))\n"
|
||||||
"f()\n",
|
"#define g f\n"
|
||||||
"int\n");
|
"#define x 2\n"
|
||||||
|
"g(z)\n",
|
||||||
|
"f(2 * (z))\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_undef_macros(void) {
|
static void test_undef_macros(void) {
|
||||||
|
|||||||
Reference in New Issue
Block a user