From 515e1499dcc0629bab22121c7db0191dcdbbd743 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Fri, 27 Sep 2024 17:27:26 +0800 Subject: [PATCH] use 'while loop' instead of 'recursive call' for macro --- lex/scf_lex.c | 219 +++++++++++++++++++++++++++++++------------------ util/scf_def.h | 2 + 2 files changed, 142 insertions(+), 79 deletions(-) diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 87eff60..7b34b47 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -1054,18 +1054,13 @@ static int __parse_macro_argv(scf_lex_t* lex, scf_macro_t* m) return 0; } -static int __parse_macro_define(scf_lex_t* lex, scf_lex_word_t* w0, scf_lex_word_t* w1) +static int __parse_macro_define(scf_lex_t* lex) { scf_lex_word_t** pp; scf_lex_word_t* w = NULL; scf_macro_t* m; scf_macro_t* m0; - scf_lex_word_free(w0); - scf_lex_word_free(w1); - w0 = NULL; - w1 = NULL; - int ret = __lex_pop_word(lex, &w); if (ret < 0) return ret; @@ -1157,44 +1152,6 @@ static int __parse_macro_define(scf_lex_t* lex, scf_lex_word_t* w0, scf_lex_word return 0; } -static int __parse_macro(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_word_t* w0) -{ - scf_lex_word_t* w1 = NULL; - - int ret = __lex_pop_word(lex, &w1); - if (ret < 0) { - scf_lex_word_free(w0); - return ret; - } - - switch (w1->type) { - - case SCF_LEX_WORD_KEY_INCLUDE: - - scf_lex_push_word(lex, w1); - *pword = w0; - return 0; - - break; - case SCF_LEX_WORD_KEY_DEFINE: - - ret = __parse_macro_define(lex, w0, w1); - if (ret < 0) - return ret; - break; - - default: - scf_loge("unknown macro '%s', file: %s, line: %d\n", w1->text->data, w1->file->data, w1->line); - - scf_lex_word_free(w0); - scf_lex_word_free(w1); - return -1; - break; - }; - - return scf_lex_pop_word(lex, pword); -} - static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use, scf_vector_t* argv) { scf_lex_word_t** pp; @@ -1316,55 +1273,51 @@ static int __convert_str(scf_lex_word_t* h) return 0; } -static int __use_macro(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_word_t* w) +static scf_macro_t* __find_macro(scf_lex_t* lex, scf_lex_word_t* w) { - scf_lex_word_t** pp; - scf_lex_word_t* p; - scf_lex_word_t* h; - scf_vector_t* argv = NULL; - scf_macro_t* m; - - if (!lex->macros) { - *pword = w; - return 0; - } + if (!lex->macros) + return NULL; + scf_macro_t* m; int i; + for (i = lex->macros->size - 1; i >= 0; i--) { m = lex->macros->data[i]; if (!scf_string_cmp(m->w->text, w->text)) - break; + return m; } - if (i < 0) { - *pword = w; - return 0; - } + return NULL; +} + +static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use) +{ + scf_lex_word_t** pp; + scf_lex_word_t* p; + scf_lex_word_t* h; + scf_lex_word_t* w; + scf_lex_word_t* prev; + scf_vector_t* argv = NULL; if (m->argv) { argv = scf_vector_alloc(); - if (!argv) { - scf_lex_word_free(w); + if (!argv) return -ENOMEM; - } - int ret = __fill_macro_argv(lex, m, w, argv); + int ret = __fill_macro_argv(lex, m, use, argv); if (ret < 0) { - scf_lex_word_free(w); scf_vector_free(argv); return ret; } } - scf_lex_word_free(w); - w = NULL; - h = NULL; pp = &h; int ret = 0; int hash = 0; + int i; for (p = m->text_list; p; p = p->next) { @@ -1373,10 +1326,7 @@ static int __use_macro(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_word_t* w continue; } - if (SCF_LEX_WORD_HASH2 == p->type) { - hash = 2; - continue; - } + scf_logd("p: %s, line: %d, hash: %d\n", p->text->data, p->line, hash); if (m->argv) { assert(argv); @@ -1452,8 +1402,81 @@ error: #endif *pp = lex->word_list; lex->word_list = h; + return 0; +} + +static int __use_hash2(scf_lex_t* lex, scf_lex_word_t* prev) +{ + scf_lex_word_t* after = NULL; + + int ret = __lex_pop_word(lex, &after); + if (ret < 0) + return ret; + + switch (after->type) { + + case SCF_LEX_WORD_ID: + ret = scf_string_cat(prev->text, after->text); + break; + + default: + ret = -1; + scf_loge("needs identity after '##', file: %s, line: %d\n", after->file->data, after->line); + break; + }; - return scf_lex_pop_word(lex, pword); + scf_lex_word_free(after); + return ret; +} + +int __lex_use_macro(scf_lex_t* lex, scf_lex_word_t** pp) +{ + scf_lex_word_t* w1 = NULL; + scf_lex_word_t* w = *pp; + scf_macro_t* m; + + *pp = NULL; + + while (SCF_LEX_WORD_ID == w->type) { + + m = __find_macro(lex, w); + if (m) { + int ret = __use_macro(lex, m, w); + + scf_lex_word_free(w); + w = NULL; + if (ret < 0) + return ret; + + ret = __lex_pop_word(lex, &w); + if (ret < 0) + return ret; + continue; + } + + int ret = __lex_pop_word(lex, &w1); + if (ret < 0) { + scf_lex_word_free(w); + return ret; + } + + if (SCF_LEX_WORD_HASH2 != w1->type) { + scf_lex_push_word(lex, w1); + break; + } + + scf_lex_word_free(w1); + w1 = NULL; + + ret = __use_hash2(lex, w); + if (ret < 0) { + scf_lex_word_free(w); + return ret; + } + } + + *pp = w; + return 0; } int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) @@ -1461,18 +1484,56 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) if (!lex || !lex->fp || !pword) return -EINVAL; - scf_lex_word_t* w = NULL; + scf_lex_word_t* w = NULL; + scf_lex_word_t* w1 = NULL; int ret = __lex_pop_word(lex, &w); if (ret < 0) return ret; - if (SCF_LEX_WORD_HASH == w->type) - return __parse_macro(lex, pword, w); + // parse macro + while (SCF_LEX_WORD_HASH == w->type) { + + ret = __lex_pop_word(lex, &w1); + if (ret < 0) { + scf_lex_word_free(w); + return ret; + } + + switch (w1->type) { + case SCF_LEX_WORD_KEY_INCLUDE: + + scf_lex_push_word(lex, w1); + *pword = w; + return 0; + break; + + case SCF_LEX_WORD_KEY_DEFINE: + ret = __parse_macro_define(lex); + break; + default: + scf_loge("unknown macro '%s', file: %s, line: %d\n", w1->text->data, w1->file->data, w1->line); + ret = -1; + break; + }; - //use macro to identity - if (scf_lex_is_identity(w)) - return __use_macro(lex, pword, w); + scf_lex_word_free(w); + scf_lex_word_free(w1); + w = NULL; + w1 = NULL; + + if (ret < 0) + return ret; + + ret = __lex_pop_word(lex, &w); + if (ret < 0) + return ret; + } + + // use macro to pre-process source code + ret = __lex_use_macro(lex, &w); + if (ret < 0) + return ret; *pword = w; return 0; diff --git a/util/scf_def.h b/util/scf_def.h index 55b1def..d8dea71 100644 --- a/util/scf_def.h +++ b/util/scf_def.h @@ -43,6 +43,8 @@ static inline uint64_t scf_zero_extend(uint64_t src, int src_bits) return src; } +#define scf_object_of(mp, type, member) ((type*)((char*)mp - offsetof(type, member))) + #define SCF_XCHG(x, y) \ do {\ typeof(x) tmp = x; \ -- 2.25.1