1, support recursive macro,
authoryu.dongliang <18588496441@163.com>
Wed, 12 Aug 2026 07:15:42 +0000 (15:15 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 12 Aug 2026 07:15:49 +0000 (15:15 +0800)
2, support fprintf() of musl-libc & global var of *.so,
3, fix: parse error for number expr with '()' of func ptr array.

13 files changed:
core/scf_lex_word.h
elf/scf_elf_link.c
examples/c_func_ptr_arg2.c [new file with mode: 0644]
examples/fprintf.c [new file with mode: 0644]
examples/macro_recursive.c [new file with mode: 0644]
lex/scf_lex.c
lex/scf_lex_util.c
lex/scf_macro.c
parse/scf_dfa.c
parse/scf_dfa.h
parse/scf_dfa_function.c
parse/scf_dfa_var.c
parse/scf_operator_handler_expr.c

index 54eeaea09b337c2c1e9e56a00177aabe0bc7735e..f8f6f0731043a2dfdaad821a045c863ad42423a3 100644 (file)
@@ -257,6 +257,8 @@ struct scf_lex_word_s
        scf_string_t*   file;   // original code file name
        int                             line;   // line in the code file above  
        int                             pos;    // position in the line above
+
+       uint8_t         macro_used_flag:1;
 };
 
 static inline int scf_lex_is_identity(scf_lex_word_t* w)
index d60d32e76ea2af886502d580a223821a1856d016..1b62609b9794647c738bc50000ce2e0d94b226e3 100644 (file)
@@ -985,7 +985,7 @@ static int link_relas(scf_elf_file_t* exec, char* afiles[], int nb_afiles, char*
                else
                        rela->r_info = ELF32_R_INFO(j + 1, ELF32_R_TYPE(rela->r_info));
 
-               scf_logi("j: %d, sym: %s, r_offset: %#lx, r_addend: %ld, got_flag: %d\n", j,
+               scf_logd("j: %d, sym: %s, r_offset: %#lx, r_addend: %ld, got_flag: %d\n", j,
                                sym->name, rela->r_offset, rela->r_addend, got_flag);
        }
 
diff --git a/examples/c_func_ptr_arg2.c b/examples/c_func_ptr_arg2.c
new file mode 100644 (file)
index 0000000..e8e8cf9
--- /dev/null
@@ -0,0 +1,7 @@
+
+int (*add_array_pt[1 + (2 + 1)])(int* array, int n, int (*add_pt)(int a, int b));
+
+int main()
+{
+       return 0;
+}
diff --git a/examples/fprintf.c b/examples/fprintf.c
new file mode 100644 (file)
index 0000000..30f5641
--- /dev/null
@@ -0,0 +1,7 @@
+#include<stdio.h>
+
+int main()
+{
+       fprintf(stdout, "hello world\n");
+       return 0;
+}
diff --git a/examples/macro_recursive.c b/examples/macro_recursive.c
new file mode 100644 (file)
index 0000000..789b34d
--- /dev/null
@@ -0,0 +1,12 @@
+int printf(const char* fmt, ...);
+
+#define A (B)
+#define B (A)
+
+int main()
+{
+       int A = 1;
+
+       printf("A: %d\n", A);
+       return 0;
+}
index 26dcbd317b12a5587615d60249ade89100006f64..37e57d59619ad630319620b4cf1807b8776594ff 100644 (file)
@@ -355,7 +355,6 @@ static int _lex_minus(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        return 0;
 }
 
-
 static int _lex_number(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
 {
        scf_lex_word_t* w  = NULL;
@@ -363,6 +362,7 @@ static int _lex_number(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        scf_char_t*     c1 = NULL;
        scf_char_t*     c2 = NULL;
 
+       int pos = lex->pos;
        int ret = 0;
 
        if ('0' == c0->c) {
@@ -398,7 +398,7 @@ static int _lex_number(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                                _lex_push_char(lex, c1);
 
                                if (c1->c < '0' || c1->c > '9') { // is 0
-                                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_INT);
+                                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_INT);
                                        w->data.u64 = atoi(s->data);
 
                                        w->text = s;
@@ -430,6 +430,8 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
 {
        scf_string_t* s = scf_string_cstr_len(c0->utf8, c0->len);
 
+       int pos = lex->pos;
+
        lex->pos += c0->len;
        free(c0);
        c0 = NULL;
@@ -456,33 +458,33 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
 
                        if (SCF_CSTR_CMP(s, "NULL")) {
 
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U64);
                                if (w)
                                        w->data.u64 = 0;
 
                        } else if (SCF_CSTR_CMP(s, "__LINE__")) {
 
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U64);
                                if (w)
                                        w->data.u64 = lex->nb_lines;
 
                        } else if (SCF_CSTR_CMP(s, "__FILE__")) {
 
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
+                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_STRING);
                                if (w)
                                        w->data.s = scf_string_clone(lex->file);
 
                        } else if (SCF_CSTR_CMP(s, "__func__")) {
 
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
+                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_STRING);
 
                        } else {
                                int type = _find_key_word(s);
 
                                if (-1 == type)
-                                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_ID);
+                                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_ID);
                                else
-                                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+                                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
                        }
 
                        if (w)
@@ -507,6 +509,8 @@ static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        scf_char_t*     c2 = _lex_pop_char(lex);
        scf_char_t*     c3;
 
+       int pos = lex->pos;
+
        if ('\\' == c1->c) {
                c3 = _lex_pop_char(lex);
 
@@ -517,7 +521,7 @@ static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                        scf_string_cat_cstr_len(s, c2->utf8, c2->len);
                        scf_string_cat_cstr_len(s, c3->utf8, 1);
 
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_CHAR);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_CHAR);
 
                        w->data.i64 = _find_escape_char(c2->c);
                        lex->pos   += c2->len + 3;
@@ -533,7 +537,7 @@ static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                scf_string_cat_cstr_len(s, c1->utf8, c1->len);
                scf_string_cat_cstr_len(s, c2->utf8, 1);
 
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_CHAR);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_CHAR);
 
                w->data.i64 = c1->c;
                lex->pos   += c1->len + 2;
@@ -558,13 +562,15 @@ static int _lex_string(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        scf_string_t*   s = scf_string_cstr_len(c0->utf8, 1);
        scf_string_t*   d = scf_string_alloc();
 
+       int pos = lex->pos;
+
        while (1) {
                scf_char_t* c1 = _lex_pop_char(lex);
 
                if ('\"' == c1->c) {
                        scf_string_cat_cstr_len(s, c1->utf8, 1);
 
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_STRING);
                        w->data.s = d;
                        w->text   = s;
                        d = NULL;
@@ -695,6 +701,8 @@ static void _lex_drop_to(scf_lex_t* lex, int c0, int c1)
                free(c);
                c = NULL;
 
+               lex->pos++;
+
                if ('\n' == tmp) {
                        lex->nb_lines++;
                        lex->pos = 0;
@@ -707,6 +715,13 @@ static void _lex_drop_to(scf_lex_t* lex, int c0, int c1)
                        c = _lex_pop_char(lex);
 
                        if (c1 == c->c) {
+                               lex->pos++;
+
+                               if ('\n' == c1) {
+                                       lex->nb_lines++;
+                                       lex->pos = 0;
+                               }
+
                                free(c);
                                c = NULL;
                                break;
@@ -755,6 +770,7 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
                        || '\r' == c->c || '\t' == c->c
                        || ' '  == c->c || '\\' == c->c) {
 
+               int pos  = lex->pos;
                int type = -1;
 
                if ('\n' == c->c) {
@@ -771,7 +787,7 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
                }
 
                if (type > 0) {
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
 
                        if (SCF_LEX_WORD_LF == type)
                                w->text = scf_string_cstr("LF");
index a6360e2ff1a7b07ef4a12eaf67c11a5684d7cdff..076641b685a65802e855c10e808a3ec9c0a83052 100644 (file)
@@ -246,6 +246,7 @@ int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
        scf_char_t*      c3;
        scf_lex_word_t*  w;
 
+       int      pos   = lex->pos;
        int      type  = -1;
        int      dot   = 0;
        int      exp   = 0;
@@ -339,20 +340,20 @@ next:
 
        if (exp > 0 || dot > 0) {
                if (SCF_LEX_WORD_CONST_FLOAT == type) {
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_FLOAT);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_FLOAT);
                        w->data.f = atof(s->data);
                } else {
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_DOUBLE);
                        w->data.d = atof(s->data);
                }
        } else {
                if (type > 0)
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
 
                else if (value & ~0xffffffffULL)
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U64);
                else
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U32);
 
                w->data.u64 = value;
        }
@@ -373,6 +374,7 @@ int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
        scf_char_t*      c2;
        scf_lex_word_t*  w;
 
+       int      pos   = lex->pos;
        int      type  = -1;
        uint64_t value = 0;
 
@@ -431,12 +433,12 @@ next:
        }
 
        if (type > 0)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
 
        else if (value & ~0xffffffffULL)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U64);
        else
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U32);
 
        w->data.u64 = value;
 
@@ -456,6 +458,7 @@ int _lex_number_base_8(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
        scf_char_t*      c2;
        scf_lex_word_t*  w;
 
+       int      pos   = lex->pos;
        int      type  = -1;
        uint64_t value = 0;
 
@@ -515,12 +518,13 @@ next:
        }
 
        if (type > 0)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
 
        else if (value & ~0xffffffffULL)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U64);
        else
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U32);
+
        w->data.u64 = value;
 
        w->text = s;
@@ -539,6 +543,7 @@ int _lex_number_base_2(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
        scf_char_t*      c2;
        scf_lex_word_t*  w;
 
+       int      pos   = lex->pos;
        int      type  = -1;
        uint64_t value = 0;
 
@@ -598,12 +603,13 @@ next:
        }
 
        if (type > 0)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
 
        else if (value & ~0xffffffffULL)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U64);
        else
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_U32);
+
        w->data.u64 = value;
 
        w->text = s;
@@ -622,6 +628,7 @@ int _lex_double(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
        scf_char_t*      c2;
        scf_lex_word_t*  w;
 
+       int  pos  = lex->pos;
        int  type = -1;
        char postfix[8];
        int  n = 0;
@@ -675,10 +682,10 @@ next:
        }
 
        if (SCF_LEX_WORD_CONST_FLOAT == type) {
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_FLOAT);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_FLOAT);
                w->data.f = atof(s->data);
        } else {
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_DOUBLE);
                w->data.d = atof(s->data);
        }
 
@@ -698,6 +705,8 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        scf_lex_word_t* w  = NULL;
        scf_string_t*   s  = scf_string_cstr_len(c0->utf8, c0->len);
 
+       int pos = lex->pos;
+
        lex->pos += c0->len;
 
        free(c0);
@@ -719,11 +728,11 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                        free(c2);
                        c2 = NULL;
 
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_VA_ARGS);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_VA_ARGS);
                        w->text = s;
                        s = NULL;
                } else {
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_RANGE);
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_RANGE);
                        w->text = s;
                        s = NULL;
 
@@ -758,7 +767,7 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                        return -EINVAL;
                }
 
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, type);
                if (!w) {
                        scf_string_free(s);
                        return -ENOMEM;
@@ -775,7 +784,7 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                if ('0' <= tmp && '9' >= tmp) // for double / float .5, .618, etc.
                        return _lex_double(lex, pword, s);
 
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_DOT);
                w->text = s;
                s = NULL;
        }
index e85a40862c9e4d13c0ec5b49d1f59223ad602437..c547825beda0b5f6b7269b2d21fb660a1d36fd1b 100644 (file)
@@ -1,4 +1,5 @@
 #include"scf_lex.h"
+#include"scf_stack.h"
 
 scf_macro_t* __find_macro(scf_lex_t* lex, scf_lex_word_t* w)
 {
@@ -341,6 +342,8 @@ int __parse_macro_define(scf_lex_t* lex, int def_flag)
 
                        w->next = NULL;
 
+                       scf_logi("'%s' in file: %s, line: %d\n", w->text->data, w->file->data, w->line);
+
                        *pp =  w;
                         pp = &w->next;
                         w  = NULL;
@@ -570,12 +573,40 @@ int __parse_macro_ifdef(scf_lex_t* lex, int def_flag)
        return __do_macro_if(lex, found == def_flag);
 }
 
-static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use, scf_vector_t* argv)
+static int __get_macro_argv(scf_lex_t* lex, scf_lex_word_t** h, scf_lex_word_t** w)
+{
+       if (h) {
+               if (!*h)
+                       return -EINVAL;
+
+               *w =  *h;
+               *h = (*h)->next;
+               return 0;
+       }
+
+       return __lex_pop_word(lex, w);
+}
+
+static void __clear_macro_argv(scf_vector_t* argv)
+{
+       scf_lex_word_t*  w;
+       int i;
+
+       for (i = 0; i < argv->size; i++) {
+               w  =        argv->data[i];
+
+               scf_slist_clear(w, scf_lex_word_t, next, scf_lex_word_free);
+       }
+
+       argv->size = 0;
+}
+
+static int __fill_macro_argv(scf_lex_t* lex, scf_lex_word_t** h, scf_macro_t* m, scf_lex_word_t* use, scf_vector_t* argv)
 {
        scf_lex_word_t** pp;
        scf_lex_word_t*  w = NULL;
 
-       int ret = __lex_pop_word(lex, &w);
+       int ret = __get_macro_argv(lex, h, &w);
        if (ret < 0)
                return ret;
 
@@ -590,12 +621,11 @@ static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use
 
        int n_lps = 0;
        int n_rps = 0;
-       int i;
 
        pp = NULL;
 
        while (1) {
-               ret = __lex_pop_word(lex, &w);
+               ret = __get_macro_argv(lex, h, &w);
                if (ret < 0)
                        return ret;
 
@@ -604,8 +634,9 @@ static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use
                                scf_loge("unexpected ',' in macro '%s', file: %s, line: %d\n", m->w->text->data, w->file->data, w->line);
 
                                scf_lex_word_free(w);
-                               ret = -1;
-                               goto error;
+
+                               __clear_macro_argv(argv);
+                               return -1;
                        }
 
                        w->next = NULL;
@@ -637,7 +668,9 @@ static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use
                        ret = scf_vector_add(argv, w);
                        if (ret < 0) {
                                scf_lex_word_free(w);
-                               goto error;
+
+                               __clear_macro_argv(argv);
+                               return ret;
                        }
                }
 
@@ -650,20 +683,12 @@ static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use
 
                scf_loge("macro '%s' needs %d args, but in fact give %d args,  file: %s, line: %d\n",
                                m->w->text->data, m->argv->size, argv->size, use->file->data, use->line);
-               ret = -1;
-               goto error;
-       }
-
-       return 0;
 
-error:
-       for (i = 0; i < argv->size; i++) {
-               w  =        argv->data[i];
-               scf_slist_clear(w, scf_lex_word_t, next, scf_lex_word_free);
+               __clear_macro_argv(argv);
+               return -1;
        }
 
-       argv->size = 0;
-       return ret;
+       return 0;
 }
 
 static int __convert_str(scf_lex_word_t* h)
@@ -711,28 +736,14 @@ static int __convert_str(scf_lex_word_t* h)
        return 0;
 }
 
-static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use)
+static int __use_macro(scf_lex_word_t** ph, scf_lex_t* lex, scf_macro_t* m, scf_vector_t* argv, scf_lex_word_t* use)
 {
        scf_lex_word_t** pp;
+       scf_lex_word_t*  h = NULL;
        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)
-                       return -ENOMEM;
 
-               int ret = __fill_macro_argv(lex, m, use, argv);
-               if (ret < 0) {
-                       scf_vector_free(argv);
-                       return ret;
-               }
-       }
-
-       h  = NULL;
        pp = &h;
 
        int ret  = 0;
@@ -746,7 +757,7 @@ static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use)
                        continue;
                }
 
-               scf_logd("p: '%s', line: %d:%d, hash: %d\n", p->text->data, p->line, p->pos, hash);
+               scf_logi("p: '%s', line: %d:%d, hash: %d\n", p->text->data, p->line, p->pos, hash);
 
                if (m->argv) {
                        assert(argv);
@@ -825,17 +836,6 @@ static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use)
        }
 
 error:
-       if (argv) {
-               for (i = 0; i < argv->size; i++) {
-                       w  =        argv->data[i];
-
-                       if (w)
-                               scf_slist_clear(w, scf_lex_word_t, next, scf_lex_word_free);
-               }
-
-               scf_vector_free(argv);
-               argv = NULL;
-       }
 
        if (ret < 0) {
                scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free);
@@ -868,6 +868,37 @@ error:
                                continue;
                        }
 
+               } else if (SCF_LEX_WORD_HASH2 == w1->type) {
+                       w2 = w1->next;
+
+                       if (SCF_LEX_WORD_ID != w->type) {
+                               scf_loge("%s:%d:%d, needs identity before '##'\n", w->file->data, w->line, w->pos);
+
+                               scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free);
+                               return -EINVAL;
+                       }
+
+                       if (!w2 || SCF_LEX_WORD_ID != w2->type) {
+                               scf_loge("%s:%d:%d, needs identity after '##'\n", w1->file->data, w1->line, w1->pos);
+
+                               scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free);
+                               return -EINVAL;
+                       }
+
+                       ret = scf_string_cat(w->text, w2->text);
+                       if (ret < 0) {
+                               scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free);
+                               return ret;
+                       }
+
+                       w->next = w2->next;
+
+                       scf_lex_word_free(w1);
+                       scf_lex_word_free(w2);
+                       w1 = NULL;
+                       w2 = NULL;
+                       continue;
+
                } else if (SCF_LEX_WORD_COMMA == w1->type) {
                        w2 = w1->next;
 
@@ -892,7 +923,7 @@ error:
                w = w->next;
        }
 
-#if 0
+#if 1
        w = h;
        while (w) {
                scf_logi("---------- %s, line: %d\n", w->text->data, w->line);
@@ -900,81 +931,152 @@ error:
        }
 #endif
 
-       *pp            = lex->word_list;
-       lex->word_list = h;
+       *ph = h;
        return 0;
 }
 
-static int __use_hash2(scf_lex_t* lex, scf_lex_word_t* prev)
+static int _find_used_macro(const void* v0, const void* v1)
 {
-       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;
-       };
+       const scf_macro_t* m0 = v0;
+       const scf_macro_t* m1 = v1;
 
-       scf_lex_word_free(after);
-       return ret;
+       return scf_string_cmp(m0->w->text, m1->w->text);
 }
 
-int __lex_use_macro(scf_lex_t* lex, scf_lex_word_t** pp)
+static int __recursive_use_macro(scf_lex_t* lex, scf_lex_word_t** h, scf_stack_t* used_macros)
 {
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w  = *pp;
-       scf_macro_t*    m;
+       scf_lex_word_t** pp = h;
+       scf_lex_word_t*  w;
+       scf_macro_t*     m;
 
-       *pp = NULL;
+       while (*pp) {
+               w = *pp;
 
-       while (SCF_LEX_WORD_ID == w->type) {
+               if (SCF_LEX_WORD_ID != w->type) {
+                       pp = &w->next;
+                       continue;
+               }
 
                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;
+               if (!m || scf_vector_find_cmp(used_macros, m, _find_used_macro)) {
+                       pp = &w->next;
                        continue;
                }
 
-               int ret = __lex_pop_word(lex, &w1);
-               if (ret < 0) {
-                       scf_lex_word_free(w);
+               int ret = scf_stack_push(used_macros, m);
+               if (ret < 0)
                        return ret;
+
+               scf_lex_word_t*  h_res  = NULL;
+               scf_lex_word_t*  h_next = w->next;
+               scf_vector_t*    argv   = NULL;
+
+               w->next = NULL;
+
+               if (m->argv) {
+                       argv = scf_vector_alloc();
+                       if (!argv) {
+                               scf_slist_clear(h_next, scf_lex_word_t, next, scf_lex_word_free);
+                               return -ENOMEM;
+                       }
+
+                       if (used_macros->size > 1)
+                               ret = __fill_macro_argv(lex, &h_next, m, w, argv);
+                       else
+                               ret = __fill_macro_argv(lex, NULL, m, w, argv);
+
+                       if (ret < 0) {
+                               scf_loge("macro '%s', m->argv->size: %d\n", m->w->text->data, m->argv->size);
+
+                               scf_vector_free(argv);
+                               scf_slist_clear(h_next, scf_lex_word_t, next, scf_lex_word_free);
+                               return ret;
+                       }
                }
 
-               if (SCF_LEX_WORD_HASH2 != w1->type) {
-                       scf_lex_push_word(lex, w1);
-                       break;
+               ret = __use_macro(&h_res, lex, m, argv, w);
+
+               if (argv) {
+                       __clear_macro_argv(argv);
+
+                       scf_vector_free(argv);
+                       argv = NULL;
                }
 
-               scf_lex_word_free(w1);
-               w1 = NULL;
+               if (ret < 0) {
+                       scf_slist_clear(h_next, scf_lex_word_t, next, scf_lex_word_free);
+                       return ret;
+               }
 
-               ret = __use_hash2(lex, w);
+               ret = __recursive_use_macro(lex, &h_res, used_macros);
                if (ret < 0) {
-                       scf_lex_word_free(w);
+                       scf_slist_clear(h_res,  scf_lex_word_t, next, scf_lex_word_free);
+                       scf_slist_clear(h_next, scf_lex_word_t, next, scf_lex_word_free);
                        return ret;
                }
+
+               *pp = h_res;
+
+               while (*pp)
+                       pp = &(*pp)->next;
+
+               *pp = h_next;
+
+               h_res  = NULL;
+               h_next = NULL;
+
+               scf_lex_word_free(w);
+               w = NULL;
+
+               scf_stack_pop(used_macros);
        }
 
-       *pp = w;
        return 0;
 }
+
+int __lex_use_macro(scf_lex_t* lex, scf_lex_word_t** pp)
+{
+       scf_stack_t*     used_macros;
+       scf_lex_word_t*  w = *pp;
+
+       if (SCF_LEX_WORD_ID != w->type
+                       || w->macro_used_flag
+                       || !__find_macro(lex, w))
+               return 0;
+
+       *pp = NULL;
+       w->next = NULL;
+
+       used_macros = scf_stack_alloc();
+       if (!used_macros) {
+               scf_lex_word_free(w);
+               return -ENOMEM;
+       }
+
+       int ret = __recursive_use_macro(lex, &w, used_macros);
+
+       scf_stack_free(used_macros);
+       used_macros = NULL;
+
+       if (ret < 0) {
+               scf_slist_clear(w, scf_lex_word_t, next, scf_lex_word_free);
+               return ret;
+       }
+
+       scf_lex_word_t** tail = &w;
+       scf_lex_word_t*  w2;
+
+       while (*tail) {
+               w2 = *tail;
+
+               w2->macro_used_flag = 1;
+
+               tail = &w2->next;
+       }
+
+       *tail = lex->word_list;
+       lex->word_list = w;
+
+       return __lex_pop_word(lex, pp);
+}
index ded71149abd04b4880de20c7b5d956cb04f7293f..b8b8fb2ffa39eca24a7d06b4d330d67f977d0d30 100644 (file)
@@ -4,6 +4,30 @@
 
 static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data, int pre_hook_flag);
 
+void scf_dfa_disable_hook(scf_dfa_hook_t* h, const char* name)
+{
+       while (h) {
+               if (!strcmp(name, h->node->name)) {
+                       h->disable_flag = 1;
+                       break;
+               }
+
+               h = h->next;
+       }
+}
+
+void scf_dfa_enable_hook(scf_dfa_hook_t* h, const char* name)
+{
+       while (h) {
+               if (!strcmp(name, h->node->name)) {
+                       h->disable_flag = 0;
+                       break;
+               }
+
+               h = h->next;
+       }
+}
+
 void scf_dfa_del_hook_by_name(scf_dfa_hook_t** pp, const char* name)
 {
        while (*pp) {
@@ -230,20 +254,25 @@ static int _scf_dfa_childs_parse_word(scf_dfa_t* dfa, scf_dfa_node_t** childs, i
 {
        assert(words->size > 0);
 
+       scf_dfa_node_t*  child;
+       scf_lex_word_t*  w;
+       scf_dfa_hook_t*  hook;
        int i;
+
        for (i = 0; i < nb_childs; i++) {
 
-               scf_dfa_node_t* child = childs[i];
-               scf_lex_word_t* w     = words->data[words->size - 1];
+               child = childs[i];
+               w     = words->data[words->size - 1];
 
                scf_logd("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data);
 
                int pre_hook_flag = 0;
 
-               scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_PRE]), w);
-               if (hook) {
-                       // if pre hook is set, deliver the word to the proper hook node.
-                       if (hook->node != child)
+               hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_PRE]), w);
+
+               if (hook && !hook->disable_flag) {
+
+                       if (hook->node != child) // if pre hook is set, deliver the word to the proper hook node.
                                continue;
                        pre_hook_flag = 1;
 
index d261f9df98caec4a226e532a59160cb19eecb214..a5ccd7d635de5bfbf5afea352512f54f42f86680 100644 (file)
@@ -39,6 +39,8 @@ struct scf_dfa_hook_s {
 
        scf_dfa_hook_t*     next;
        scf_dfa_node_t*     node;
+
+       uint8_t             disable_flag:1;
 };
 
 struct scf_dfa_node_s
@@ -163,4 +165,7 @@ int                     scf_dfa_parse_word(scf_dfa_t* dfa, void* word, void* dat
 void                    scf_dfa_del_hook        (scf_dfa_hook_t** pp, scf_dfa_hook_t* sentinel);
 void                    scf_dfa_del_hook_by_name(scf_dfa_hook_t** pp, const char* name);
 
+void                    scf_dfa_disable_hook(scf_dfa_hook_t* h, const char* name);
+void                    scf_dfa_enable_hook (scf_dfa_hook_t* h, const char* name);
+
 #endif
index b9e0011770f107fba816029a8c6060bf6f8bc007..2ac87de32f675bf4d0880391af7acf4e23a48965 100644 (file)
@@ -402,7 +402,7 @@ static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
                if (id && id->identity)
                        scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, d->pf_pointers);
        } else {
-               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE);
+//             SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE);
        }
 
        return SCF_DFA_NEXT_WORD;
@@ -679,6 +679,8 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, var,      ls,        ls);
        SCF_DFA_GET_MODULE_NODE(dfa, var,      rs,        rs);
        SCF_DFA_GET_MODULE_NODE(dfa, var,      assign,    assign);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,      comma,     var_comma);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,      semicolon, semicolon);
 
        // function pointer
        scf_dfa_node_add_child(base_type, pf_lp);
@@ -697,6 +699,12 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa)
        scf_dfa_node_add_child(pf_lp,     pf_lp);
        scf_dfa_node_add_child(pf_rp,     pf_rp);
 
+       // var with (), such as 'int (v) = 1;'
+       scf_dfa_node_add_child(pf_lp,     identity);
+       scf_dfa_node_add_child(pf_rp,     assign);
+       scf_dfa_node_add_child(pf_rp,     var_comma);
+       scf_dfa_node_add_child(pf_rp,     semicolon);
+
        scf_dfa_node_add_child(pf_rp,     lp);
 
        // function start
index 8e8c0834f409b606bec4b4309fd86e9fc2bf0b30..7f9028712dbd00ad8b91d0085b210d5e1bc87583 100644 (file)
@@ -506,6 +506,8 @@ static int _var_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        d->nb_lss++;
 
+       scf_dfa_disable_hook(dfa->hooks[SCF_DFA_HOOK_PRE], "function_pf_rp");
+
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -520,6 +522,8 @@ static int _var_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_logd("d->expr: %p\n", d->expr);
 
+       scf_dfa_enable_hook(dfa->hooks[SCF_DFA_HOOK_PRE], "function_pf_rp");
+
        if (!d->expr)
                return SCF_DFA_SWITCH_TO;
 
index 2976c51186009d9976c1221c94be1587706b221d..4606422edf672e54db12a01807192d677aebff50 100644 (file)
@@ -136,6 +136,10 @@ static int _scf_op_expr_expr(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, v
                return -1;
        }
 
+       scf_variable_t* v = _scf_operand_get(n);
+       if (v)
+               parent->result = scf_variable_ref(v);
+
        return 0;
 }
 
@@ -281,9 +285,8 @@ static int _scf_op_expr_binary(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
 
        if (scf_type_is_number(v0->type) && scf_type_is_number(v1->type)) {
 
-               if (!scf_variable_const(v0) || !scf_variable_const(v1)) {
+               if (!scf_variable_const(v0) || !scf_variable_const(v1))
                        return 0;
-               }
 
                assert(v0->type == v1->type);
 
@@ -731,6 +734,12 @@ int scf_expr_calculate(scf_ast_t* ast, scf_expr_t* e, scf_variable_t** pret)
        if (ret < 0)
                return ret;
 
+       if (SCF_OP_EXPR == node->type) {
+               node = node->nodes[0];
+
+               assert(SCF_OP_EXPR != node->type);
+       }
+
        v = _scf_operand_get(node);
 
        if (pret)