diff --git a/libs/pproc/include/pproc_expand.h b/libs/pproc/include/pproc_expand.h index 6e5cbc5..e1de3c5 100644 --- a/libs/pproc/include/pproc_expand.h +++ b/libs/pproc/include/pproc_expand.h @@ -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__ */ diff --git a/libs/pproc/src/pproc_directive.c b/libs/pproc/src/pproc_directive.c index 627d0a8..5387920 100644 --- a/libs/pproc/src/pproc_directive.c +++ b/libs/pproc/src/pproc_directive.c @@ -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); } /* diff --git a/libs/pproc/src/pproc_expand.c b/libs/pproc/src/pproc_expand.c index a9523c5..eb5b4e7 100644 --- a/libs/pproc/src/pproc_expand.c +++ b/libs/pproc/src/pproc_expand.c @@ -2,6 +2,10 @@ #include #include +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, diff --git a/libs/pproc/tests/test_pproc_unit.c b/libs/pproc/tests/test_pproc_unit.c index 19d9296..d505fdd 100644 --- a/libs/pproc/tests/test_pproc_unit.c +++ b/libs/pproc/tests/test_pproc_unit.c @@ -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) {