1, #include "stdio.h" of 'musl libc' ok,
authoryu.dongliang <18588496441@163.com>
Wed, 5 Aug 2026 16:32:34 +0000 (00:32 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 5 Aug 2026 16:32:46 +0000 (00:32 +0800)
2, #if expr only has const integer & identity,
3, support '__builtin_va_list, __builtin_va_start(), __builtin_va_arg(), __builtin_va_end()',
4, support -D to define macro in cmd line,
5, fix: macro in *.c defined before can't be found in *.h files by #include,
6, add option -p to parse the source code only, not compile or make 3ac code,
7, close some logs.

25 files changed:
core/scf_lex_word.h
examples/c89.c [new file with mode: 0644]
examples/hello.c
examples/hello.h [deleted file]
examples/unsigned_long_short.c [new file with mode: 0644]
lex/scf_lex.c
lex/scf_lex.h
lex/scf_lex_test.c
lex/scf_macro.c
lex/scf_macro_expr.c
parse/main.c
parse/scf_dfa_call.c
parse/scf_dfa_function.c
parse/scf_dfa_include.c
parse/scf_dfa_new.c
parse/scf_dfa_operator.c
parse/scf_dfa_type.c
parse/scf_dfa_var.c
parse/scf_parse.c
parse/scf_parse.h
sysroot/include/bits/alltypes.h [moved from sysroot/include/alltypes.h with 100% similarity]
sysroot/include/bits/syscall.h [moved from sysroot/include/syscall.h with 100% similarity]
sysroot/include/features.h [new file with mode: 0644]
sysroot/include/stdio.h
sysroot/lib/__builtin__.h [new file with mode: 0644]

index fae6d83066da709f0b16982d4c60437101f84fc1..92a2b5da1db9b43b1308f66ddc0350139504a1da 100644 (file)
@@ -145,7 +145,13 @@ enum scf_lex_words
        // data types
        SCF_LEX_WORD_KEY_CHAR,          // char
 
+       SCF_LEX_WORD_KEY_SHORT,     // short
        SCF_LEX_WORD_KEY_INT,       // int
+       SCF_LEX_WORD_KEY_LONG,      // long
+
+       SCF_LEX_WORD_KEY_SIGNED,    //   signed
+       SCF_LEX_WORD_KEY_UNSIGNED,  // unsigned
+
        SCF_LEX_WORD_KEY_FLOAT,     // float
        SCF_LEX_WORD_KEY_DOUBLE,    // double
 
diff --git a/examples/c89.c b/examples/c89.c
new file mode 100644 (file)
index 0000000..5d4aaef
--- /dev/null
@@ -0,0 +1,9 @@
+int printf(const char* fmt, ...);
+
+int main()
+{
+       int restrict = 1;
+
+       printf("restrict: %d\n", restrict);
+       return 0;
+}
index 52b0cd96925bc98baaacee6933dbea933591bdfc..a4f61fef73fe30dab1eada50de8fb146bad4b610 100644 (file)
@@ -1,4 +1,4 @@
-#include"hello.h"
+#include"stdio.h"
 
 int main()
 {
diff --git a/examples/hello.h b/examples/hello.h
deleted file mode 100644 (file)
index 281333b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef HELLO_H
-#define HELLO_H
-int printf(const char* fmt, ...);
-#endif
diff --git a/examples/unsigned_long_short.c b/examples/unsigned_long_short.c
new file mode 100644 (file)
index 0000000..1b9eed5
--- /dev/null
@@ -0,0 +1,18 @@
+int printf(const char* fmt, ...);
+
+int main()
+{
+       short int si = 3;
+       long int li = 4;
+
+       long long ll = 5;
+
+       unsigned long ul = 6;
+
+       signed s = 7;
+       unsigned u = 8;
+
+       printf("si: %d, li: %d, ll: %ld, ul: %lu, s: %d, u: %u\n",
+                       si, li, ll, ul, s, u);
+       return 0;
+}
index 5512eb647e750882b8fc4e1fef5525a606fb7114..693aef63bcfe7bb99533289fadc5168802c89ca6 100644 (file)
@@ -49,9 +49,16 @@ static scf_key_word_t  key_words[] =
 
        {SCF_CSTR("char"),      SCF_LEX_WORD_KEY_CHAR},
 
+       {SCF_CSTR("short"),     SCF_LEX_WORD_KEY_SHORT},
        {SCF_CSTR("int"),       SCF_LEX_WORD_KEY_INT},
+       {SCF_CSTR("long"),      SCF_LEX_WORD_KEY_LONG},
+
+       {SCF_CSTR("signed"),    SCF_LEX_WORD_KEY_SIGNED},
+       {SCF_CSTR("unsigned"),  SCF_LEX_WORD_KEY_UNSIGNED},
+
        {SCF_CSTR("float"),     SCF_LEX_WORD_KEY_FLOAT},
        {SCF_CSTR("double"),    SCF_LEX_WORD_KEY_DOUBLE},
+
        {SCF_CSTR("bit"),       SCF_LEX_WORD_KEY_BIT},
        {SCF_CSTR("bit2_t"),    SCF_LEX_WORD_KEY_BIT2},
        {SCF_CSTR("bit3_t"),    SCF_LEX_WORD_KEY_BIT3},
@@ -76,10 +83,6 @@ static scf_key_word_t  key_words[] =
 
        {SCF_CSTR("void"),      SCF_LEX_WORD_KEY_VOID},
 
-       {SCF_CSTR("va_start"),  SCF_LEX_WORD_KEY_VA_START},
-       {SCF_CSTR("va_arg"),    SCF_LEX_WORD_KEY_VA_ARG},
-       {SCF_CSTR("va_end"),    SCF_LEX_WORD_KEY_VA_END},
-
        {SCF_CSTR("container"), SCF_LEX_WORD_KEY_CONTAINER},
 
        {SCF_CSTR("class"),     SCF_LEX_WORD_KEY_CLASS},
@@ -110,6 +113,10 @@ static scf_key_word_t  key_words[] =
        {SCF_CSTR(".quad"),     SCF_LEX_WORD_ASM_QUAD},
        {SCF_CSTR(".ascii"),    SCF_LEX_WORD_ASM_ASCII},
        {SCF_CSTR(".asciz"),    SCF_LEX_WORD_ASM_ASCIZ},
+
+       {SCF_CSTR("__builtin_va_start"),  SCF_LEX_WORD_KEY_VA_START},
+       {SCF_CSTR("__builtin_va_arg"),    SCF_LEX_WORD_KEY_VA_ARG},
+       {SCF_CSTR("__builtin_va_end"),    SCF_LEX_WORD_KEY_VA_END},
 };
 
 static scf_escape_char_t  escape_chars[] =
@@ -158,7 +165,7 @@ static int _find_escape_char(const int c)
        return c;
 }
 
-int    scf_lex_open(scf_lex_t** plex, const char* path, scf_string_t* text, int c_version)
+int    scf_lex_open(scf_lex_t** plex, const char* path, scf_string_t* text, int c_version, scf_lex_word_t* include)
 {
        if (!plex || !path)
                return -EINVAL;
@@ -173,6 +180,16 @@ int        scf_lex_open(scf_lex_t** plex, const char* path, scf_string_t* text, int c_v
                return -ENOMEM;
        }
 
+       if (include) {
+               lex->included = scf_lex_word_clone(include);
+
+               if (!lex->included) {
+                       scf_string_free(lex->file);
+                       free(lex);
+                       return -ENOMEM;
+               }
+       }
+
        if (!text) {
                lex->fp = fopen(path, "r");
                if (!lex->fp) {
@@ -180,6 +197,9 @@ int scf_lex_open(scf_lex_t** plex, const char* path, scf_string_t* text, int c_v
                        getcwd(cwd, 4095);
                        scf_loge("open file '%s' failed, errno: %d, default path dir: %s\n", path, errno, cwd);
 
+                       if (lex->included)
+                               scf_lex_word_free(lex->included);
+
                        scf_string_free(lex->file);
                        free(lex);
                        return -1;
@@ -216,6 +236,9 @@ int scf_lex_close(scf_lex_t* lex)
 
                scf_string_free(lex->file);
 
+               if (lex->included)
+                       scf_lex_word_free(lex->included);
+
                if (lex->fp)
                        fclose(lex->fp);
                free(lex);
@@ -453,17 +476,6 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                                w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING);
 
                        } else {
-                               if (SCF_C99 == lex->c_version
-                                               && (SCF_CSTR_CMP(s, "restrict")
-                                                       || SCF_CSTR_CMP(s, "__restrict")
-                                                       || SCF_CSTR_CMP(s, "__restrict__"))) {
-
-                                       scf_string_free(s);
-                                       s = NULL;
-
-                                       return __lex_pop_word(lex, pword);
-                               }
-
                                int type = _find_key_word(s);
 
                                if (-1 == type)
@@ -702,6 +714,26 @@ static void _lex_drop_to(scf_lex_t* lex, int c0, int c1)
        }
 }
 
+int __lex_drop_space(scf_lex_t* lex, scf_lex_word_t** pword)
+{
+       scf_lex_word_t*  w = NULL;
+
+       while (1) {
+               int ret = __lex_pop_word(lex, &w);
+               if (ret < 0)
+                       return ret;
+
+               if (SCF_LEX_WORD_SPACE != w->type)
+                       break;
+
+               scf_lex_word_free(w);
+               w = NULL;
+       }
+
+       *pword = w;
+       return 0;
+}
+
 int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
 {
        scf_list_t*             l = NULL;
@@ -722,26 +754,34 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
                        || '\r' == c->c || '\t' == c->c
                        || ' '  == c->c || '\\' == c->c) {
 
+               int type = -1;
+
                if ('\n' == c->c) {
                        if (SCF_UTF8_LF == c->flag || lex->asm_flag)
-                       {
-                               w       = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_LF);
-                               w->text = scf_string_cstr("LF");
-                               *pword  = w;
-
-                               free(c);
-                               c = NULL;
-
-                               lex->nb_lines++;
-                               lex->pos = 0;
-                               return 0;
-                       }
+                               type = SCF_LEX_WORD_LF;
 
                        lex->nb_lines++;
                        lex->pos = 0;
-               } else
+               } else {
                        lex->pos++;
 
+                       if ('\t' == c->c || ' ' == c->c || '\\' == c->c)
+                               type = SCF_LEX_WORD_SPACE;
+               }
+
+               if (type > 0) {
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+
+                       if (SCF_LEX_WORD_LF == type)
+                               w->text = scf_string_cstr("LF");
+                       else
+                               w->text = scf_string_cstr_len(c->utf8, c->len);
+                       *pword = w;
+
+                       free(c);
+                       return 0;
+               }
+
                free(c);
                c = _lex_pop_char(lex);
        }
@@ -1036,25 +1076,30 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
        scf_lex_word_t* w  = NULL;
        scf_lex_word_t* w1 = NULL;
 
-       int ret = __lex_pop_word(lex, &w);
+       int ret = __lex_drop_space(lex, &w);
        if (ret < 0)
                return ret;
 
        // parse macro
        while (SCF_LEX_WORD_HASH == w->type) {
 
-               ret = __lex_pop_word(lex, &w1);
+               ret = __lex_drop_space(lex, &w1);
                if (ret < 0) {
                        scf_lex_word_free(w);
                        return ret;
                }
 
-               switch (w1->type) {
+               switch (w1->type)
+               {
                        case SCF_LEX_WORD_KEY_INCLUDE:
+                               ret = __parse_macro_include(lex);
+                               if (ret < 0)
+                                       break;
+
                        case SCF_LEX_WORD_KEY_ENDIF:
                                scf_lex_push_word(lex, w1);
-                               *pword = w;
-                               return 0;
+                               w1 = NULL;
+                               goto end;
                                break;
 
                        case SCF_LEX_WORD_KEY_IF:
@@ -1095,8 +1140,8 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
                        default:
                                if (lex->asm_flag) {
                                        scf_lex_push_word(lex, w1);
-                                       *pword = w;
-                                       return 0;
+                                       w1 = NULL;
+                                       goto end;
                                }
 
                                scf_loge("unknown macro '%s', file: %s, line: %d\n", w1->text->data, w1->file->data, w1->line);
@@ -1112,7 +1157,7 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
                if (ret < 0)
                        return ret;
 
-               ret = __lex_pop_word(lex, &w);
+               ret = __lex_drop_space(lex, &w);
                if (ret < 0)
                        return ret;
        }
@@ -1122,6 +1167,19 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
        if (ret < 0)
                return ret;
 
+end:
+       if (SCF_C99 == lex->c_version
+                       && SCF_LEX_WORD_ID == w->type
+                       && (SCF_CSTR_CMP(w->text, "restrict")
+                               || SCF_CSTR_CMP(w->text, "__restrict")
+                               || SCF_CSTR_CMP(w->text, "__restrict__"))) {
+
+               scf_lex_word_free(w);
+               w = NULL;
+
+               return scf_lex_pop_word(lex, pword);
+       }
+
        *pword = w;
        return 0;
 }
index bacbe0d79061f1a47d96dd86902d4ddefda4cb0e..0b6bb48e23e9c7972dd66dcc30a5147593c0360a 100644 (file)
@@ -6,8 +6,8 @@
 typedef struct scf_char_s  scf_char_t;
 typedef struct scf_lex_s   scf_lex_t;
 
-#define SCF_C89 0
-#define SCF_C99 1
+#define SCF_C89 1
+#define SCF_C99 2
 
 typedef struct {
        char*   text;
@@ -55,6 +55,8 @@ struct scf_lex_s
        int             nb_lines;
        int             pos;
 
+       scf_lex_word_t* included; // where cur file is included by '#include'
+
        uint8_t         asm_flag:1;
 };
 
@@ -63,14 +65,16 @@ int _find_key_word(const scf_string_t* text);
 scf_char_t*  _lex_pop_char (scf_lex_t* lex);
 void         _lex_push_char(scf_lex_t* lex, scf_char_t* c);
 
-int     scf_lex_open (scf_lex_t** plex, const char* path, scf_string_t* text, int c_version);
+int     scf_lex_open (scf_lex_t** plex, const char* path, scf_string_t* text, int c_version, scf_lex_word_t* include);
 int  scf_lex_close(scf_lex_t*   lex);
 
 void scf_lex_push_word(scf_lex_t* lex, scf_lex_word_t*   word);
 int  scf_lex_pop_word (scf_lex_t* lex, scf_lex_word_t** pword);
 
+int    __lex_drop_space(scf_lex_t* lex, scf_lex_word_t** pword);
 int    __lex_pop_word (scf_lex_t* lex, scf_lex_word_t** pword);
 int    __lex_use_macro(scf_lex_t* lex, scf_lex_word_t** pp);
+int    __lex_add_macro(scf_lex_t* lex, const char* name, const int64_t value);
 
 int    __macro_if_expr(scf_lex_t* lex);
 
@@ -80,10 +84,11 @@ int    __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t** pw
 int    __macro_drop_to_LF (scf_lex_t* lex);
 int    __macro_print_to_LF(scf_lex_t* lex);
 
-int    __parse_macro_define(scf_lex_t* lex, int def_flag);
-int    __parse_macro_ifdef (scf_lex_t* lex, int def_flag);
-int    __parse_macro_if    (scf_lex_t* lex);
-int    __parse_macro_else  (scf_lex_t* lex);
+int    __parse_macro_include(scf_lex_t* lex);
+int    __parse_macro_define (scf_lex_t* lex, int def_flag);
+int    __parse_macro_ifdef  (scf_lex_t* lex, int def_flag);
+int    __parse_macro_if     (scf_lex_t* lex);
+int    __parse_macro_else   (scf_lex_t* lex);
 
 int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s);
 int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s);
index 3617057d4094dce79cc3d1e0c8803a66991b6104..4ba9fdc90bf0c6318ef87eece3c29d2490b9860e 100644 (file)
@@ -4,7 +4,7 @@ int main(int argc, char* argv[])
 {
        scf_lex_t*      lex = NULL;
 
-       if (scf_lex_open(&lex, argv[1], NULL, SCF_C99) < 0) {
+       if (scf_lex_open(&lex, argv[1], NULL, SCF_C99, NULL) < 0) {
                scf_loge("\n");
                return -1;
        }
index b4c8f3debc4ce92197bae33daec8465f576ac067..e85a40862c9e4d13c0ec5b49d1f59223ad602437 100644 (file)
@@ -78,7 +78,7 @@ int __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t** pw2)
 
        while (1) {
                if (!w1) {
-                       int ret = __lex_pop_word(lex, &w1);
+                       int ret = __lex_drop_space(lex, &w1);
                        if (ret < 0)
                                return ret;
                }
@@ -94,7 +94,7 @@ int __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t** pw2)
                        continue;
                }
 
-               int ret = __lex_pop_word(lex, &w2);
+               int ret = __lex_drop_space(lex, &w2);
                if (ret < 0) {
                        scf_lex_word_free(w1);
                        return ret;
@@ -156,7 +156,7 @@ int __macro_pop_to(scf_lex_t* lex, scf_lex_word_t** h, scf_lex_word_t** pw1, scf
                        continue;
                }
 
-               int ret = __lex_pop_word(lex, &w2);
+               int ret = __lex_drop_space(lex, &w2);
                if (ret < 0) {
                        scf_lex_word_free(w1);
                        return ret;
@@ -202,7 +202,7 @@ static int __parse_macro_argv(scf_lex_t* lex, scf_macro_t* m)
        int id    = 0;
 
        while (1) {
-               int ret = __lex_pop_word(lex, &w);
+               int ret = __lex_drop_space(lex, &w);
                if (ret < 0)
                        return ret;
 
@@ -285,7 +285,7 @@ int __parse_macro_define(scf_lex_t* lex, int def_flag)
        scf_macro_t*     m;
        scf_macro_t*     m0;
 
-       int ret = __lex_pop_word(lex, &w);
+       int ret = __lex_drop_space(lex, &w);
        if (ret < 0)
                return ret;
 
@@ -323,6 +323,10 @@ int __parse_macro_define(scf_lex_t* lex, int def_flag)
                        scf_macro_free(m);
                        return ret;
                }
+
+       } else if (SCF_LEX_WORD_SPACE == w->type) {
+               scf_lex_word_free(w);
+               w = NULL;
        }
 
        pp = &m->text_list;
@@ -335,12 +339,14 @@ int __parse_macro_define(scf_lex_t* lex, int def_flag)
                                break;
                        }
 
+                       w->next = NULL;
+
                        *pp =  w;
                         pp = &w->next;
                         w  = NULL;
                }
 
-               ret = __lex_pop_word(lex, &w);
+               ret = __lex_drop_space(lex, &w);
                if (ret < 0) {
                        scf_macro_free(m);
                        return ret;
@@ -402,6 +408,7 @@ static int __do_macro_if(scf_lex_t* lex, int flag)
                return ret;
        }
 
+
        int type = w2->type;
 
        scf_lex_word_free(w2);
@@ -459,12 +466,87 @@ int __parse_macro_else(scf_lex_t* lex)
        return __do_macro_if(lex, 1);
 }
 
+int __parse_macro_include(scf_lex_t* lex)
+{
+       scf_lex_word_t*  w  = NULL;
+       scf_lex_word_t*  w1 = NULL;
+
+       int ret = __lex_drop_space(lex, &w);
+       if (ret < 0)
+               return ret;
+
+       if (SCF_LEX_WORD_CONST_STRING == w->type) {
+               scf_lex_push_word(lex, w);
+               return 0;
+
+       } else if (SCF_LEX_WORD_LT != w->type) {
+               scf_loge("%s:%d:%d, unknown '%s' after '#include'\n", w->file->data, w->line, w->pos, w->text->data);
+
+               scf_lex_word_free(w);
+               return -EINVAL;
+       }
+
+       assert(!w->data.s);
+
+       int type;
+       do {
+               ret = __lex_drop_space(lex, &w1);
+               if (ret < 0) {
+                       scf_lex_word_free(w);
+                       return ret;
+               }
+
+               type = w1->type;
+
+               if (SCF_LEX_WORD_LF == type || SCF_LEX_WORD_EOF == type) {
+                       scf_loge("%s:%d:%d, NOT found '>' after '#include' until '%s'\n", w->file->data, w->line, w->pos, w->text->data);
+
+                       scf_lex_word_free(w1);
+                       scf_lex_word_free(w);
+                       return -EINVAL;
+               }
+
+               if (SCF_LEX_WORD_GT != type) {
+                       ret = 0;
+
+                       if (w->data.s)
+                               ret = scf_string_cat(w->data.s, w1->text);
+                       else {
+                               w->data.s = scf_string_clone(w1->text);
+                               if (!w->data.s)
+                                       ret = -ENOMEM;
+                       }
+
+                       if (ret < 0) {
+                               scf_lex_word_free(w1);
+                               scf_lex_word_free(w);
+                               return ret;
+                       }
+               }
+
+               ret = scf_string_cat(w->text, w1->text);
+
+               scf_lex_word_free(w1);
+               w1 = NULL;
+
+               if (ret < 0) {
+                       scf_lex_word_free(w);
+                       return ret;
+               }
+       } while (SCF_LEX_WORD_GT != type);
+
+       w->type = SCF_LEX_WORD_CONST_STRING;
+
+       scf_lex_push_word(lex, w);
+       return 0;
+}
+
 int __parse_macro_ifdef(scf_lex_t* lex, int def_flag)
 {
        scf_lex_word_t*  w = NULL;
        scf_macro_t*     m;
 
-       int ret = __lex_pop_word(lex, &w);
+       int ret = __lex_drop_space(lex, &w);
        if (ret < 0)
                return ret;
 
index 8548a303c0e0941c7dd5b1ee9c24ca38d391506a..4c146baf99cec1ff5c9080edaf05266ccfaf3de1 100644 (file)
@@ -52,7 +52,7 @@ static int __macro_unary_operand(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w
 
        scf_lex_word_t* w0 = NULL;
 
-       int ret = __lex_pop_word(lex, &w0);
+       int ret = __lex_drop_space(lex, &w0);
        if (ret < 0)
                return ret;
 
@@ -78,7 +78,7 @@ static int __macro_unary_operand(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w
                                return ret;
 
                default:
-                       scf_logw("w0: %s, w0->data.u64: %ld\n", w0->text->data, w0->data.u64);
+                       scf_logd("w0: %s, w0->data.u64: %ld\n", w0->text->data, w0->data.u64);
 
                        *operand = w0;
 
@@ -102,7 +102,7 @@ static int __macro_binary_operand(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_
        if (ret < 0)
                return ret;
 
-       ret = __lex_pop_word(lex, &op2);
+       ret = __lex_drop_space(lex, &op2);
        if (ret < 0)
                return ret;
 
@@ -141,14 +141,14 @@ static int __macro_binary_##name(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w
        if (ret < 0) \
                return ret; \
        \
-       if (!scf_lex_is_const(w0)) \
+       if (!scf_lex_is_const_integer(w0) && !scf_lex_is_identity(w0)) \
                return -EINVAL; \
        \
-       if (!scf_lex_is_const(w1)) \
+       if (!scf_lex_is_const_integer(w1) && !scf_lex_is_identity(w1)) \
                return -EINVAL; \
        \
        w0->data.i64 = w0->data.i64 op w1->data.i64; \
-       scf_logi("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \
+       scf_logd("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \
        \
        *operand = w0; \
        return 0; \
@@ -183,7 +183,7 @@ static int __macro_binary_logic_and(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_le
        scf_lex_word_t*  w0 = *operand;
        scf_lex_word_t*  w1 = NULL;
 
-       if (!scf_lex_is_const(w0)) {
+       if (!scf_lex_is_const_integer(w0) && !scf_lex_is_identity(w0)) {
                scf_loge("\n");
                return -EINVAL;
        }
@@ -194,7 +194,7 @@ static int __macro_binary_logic_and(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_le
                if (ret < 0)
                        return ret;
 
-               if (!scf_lex_is_const(w1)) {
+               if (!scf_lex_is_const_integer(w1) && !scf_lex_is_identity(w1)) {
                        scf_loge("\n");
                        return -EINVAL;
                }
@@ -202,7 +202,7 @@ static int __macro_binary_logic_and(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_le
                w0->data.i64 = w0->data.i64 && w1->data.i64;
        }
 
-       scf_logi("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos);
+       scf_logd("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos);
 
        *operand = w0;
        return 0;
@@ -216,7 +216,7 @@ static int __macro_binary_logic_or(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex
        scf_lex_word_t*  w0 = *operand;
        scf_lex_word_t*  w1 = NULL;
 
-       if (!scf_lex_is_const(w0)) {
+       if (!scf_lex_is_const_integer(w0) && !scf_lex_is_identity(w0)) {
                scf_loge("\n");
                return -EINVAL;
        }
@@ -227,7 +227,7 @@ static int __macro_binary_logic_or(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex
                if (ret < 0)
                        return ret;
 
-               if (!scf_lex_is_const(w1)) {
+               if (!scf_lex_is_const_integer(w1) && !scf_lex_is_identity(w1)) {
                        scf_loge("\n");
                        return -EINVAL;
                }
@@ -235,7 +235,7 @@ static int __macro_binary_logic_or(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex
                w0->data.i64 = w0->data.i64 || w1->data.i64;
        }
 
-       scf_logi("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos);
+       scf_logd("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos);
 
        *operand = w0;
        return 0;
@@ -250,7 +250,7 @@ static int __macro_operator_defined(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_le
        int n_rps = 0;
 
        while (1) {
-               ret = __lex_pop_word(lex, &w0);
+               ret = __lex_drop_space(lex, &w0);
                if (ret < 0)
                        return ret;
 
@@ -282,13 +282,13 @@ static int __macro_operator_defined(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_le
        w0->type = SCF_LEX_WORD_CONST_I64;
        *operand = w0;
 
-       scf_logi("w0: %s, result: %ld\n", w0->text->data, w0->data.i64);
+       scf_logd("w0: %s, result: %ld\n", w0->text->data, w0->data.i64);
 
        w0 = NULL;
 
        while (n_rps < n_lps) {
 
-               ret = __lex_pop_word(lex, &w0);
+               ret = __lex_drop_space(lex, &w0);
                if (ret < 0)
                        return ret;
 
@@ -328,11 +328,11 @@ static int __macro_unary_##name(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_wo
        \
        scf_lex_word_t*  w0 = *operand; \
        \
-       if (!scf_lex_is_const(w0)) \
+       if (!scf_lex_is_const_integer(w0) && !scf_lex_is_identity(w0)) \
                return -EINVAL; \
        \
        w0->data.u64 = op w0->data.u64; \
-       scf_logi("op: %s, result: %ld, line: %d, pos: %d\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \
+       scf_logd("op: %s, result: %ld, line: %d, pos: %d\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \
        return 0; \
 }
 
@@ -384,7 +384,7 @@ static int __macro_operator_cond(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w
        if (ret < 0)
                return ret;
 
-       ret = __lex_pop_word(lex, &op2);
+       ret = __lex_drop_space(lex, &op2);
        if (ret < 0)
                return ret;
 
@@ -397,7 +397,7 @@ static int __macro_operator_cond(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w
                        if (ret < 0)
                                return ret;
 
-                       ret = __lex_pop_word(lex, &op2);
+                       ret = __lex_drop_space(lex, &op2);
                        if (ret < 0)
                                return ret;
                }
@@ -521,10 +521,10 @@ static int __macro_operator_lp(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_wor
        scf_lex_word_t*  w0  = *operand;
        scf_lex_word_t*  op2 = NULL;
 
-       if (!scf_lex_is_const(w0))
+       if (!scf_lex_is_const_integer(w0) && !scf_lex_is_identity(w0))
                return -EINVAL;
 
-       ret = __lex_pop_word(lex, &op2);
+       ret = __lex_drop_space(lex, &op2);
        if (ret < 0)
                return ret;
 
@@ -644,7 +644,7 @@ int __macro_if_expr(scf_lex_t* lex)
        int ret = 0;
 
        while (1) {
-               ret = __lex_pop_word(lex, &w);
+               ret = __lex_drop_space(lex, &w);
                if (ret < 0)
                        goto error;
 
@@ -697,7 +697,8 @@ int __macro_if_expr(scf_lex_t* lex)
                                goto error;
                }
 
-               if (!scf_lex_is_const(w)) {
+               if (!scf_lex_is_const_integer(w) && !scf_lex_is_identity(w)) {
+
                        scf_loge("operand '%s' is NOT CONST in macro expr, file: %s, line: %d\n",
                                        w->text->data, w->file->data, w->line);
 
@@ -713,7 +714,7 @@ int __macro_if_expr(scf_lex_t* lex)
                        goto error;
                }
 
-               scf_logi("w: %s, w->data.u64: %ld\n", w->text->data, w->data.u64);
+               scf_logd("w: %s, w->data.u64: %ld\n", w->text->data, w->data.u64);
 
                operand = w;
 
@@ -739,12 +740,12 @@ error:
                w = h;
                h = w->next;
 
-               scf_logi("\033[34m macro: %s, position: %d,%d\033[0m\n", w->text->data, w->line, w->pos);
+               scf_logd("\033[34m macro: %s, position: %d,%d\033[0m\n", w->text->data, w->line, w->pos);
 
                scf_lex_word_free(w);
                w = NULL;
        }
 
-       scf_logi("final flag: %d\n", ret);
+       scf_logd("final flag: %d\n", ret);
        return ret;
 }
index 61fe9e19c02065367eaac5421f85aca796168b76..041367f6466fcba72f38655c017db897c0d907aa 100644 (file)
@@ -3,6 +3,11 @@
 #include"scf_x64.h"
 #include"scf_elf_link.h"
 
+static char* __h_files[] =
+{
+       "../sysroot/lib/__builtin__.h",
+};
+
 static char* __objs[] =
 {
        "_start.o",
@@ -40,13 +45,17 @@ static char* __arm32_sofiles[] =
 
 void usage(char* path)
 {
-       fprintf(stderr, "Usage: %s [-std=..] [-c] [-d] [-t] [-a arch] [-s sysroot] [-Iinclude / -I include] [-lsofile / -l sofile] [-Lsopath / -L sopath] [-o out] src0 [src1]\n\n", path);
+       fprintf(stderr, "Usage: %s [-std=..] [-c] [-p/-t] [-d] [-a arch] [-s sysroot] [-Dmacro / -D macro] [-Iinclude / -I include] [-lsofile / -l sofile] [-Lsopath / -L sopath] [-o out] src0 [src1]\n\n", path);
        fprintf(stderr, "-std: c89 or c99 version\n");
        fprintf(stderr, "-c: only compile,  not link\n");
-       fprintf(stderr, "-t: only 3ac code, not compile\n");
+       fprintf(stderr, "-p: only parse,    not compile\n");
+       fprintf(stderr, "-t: only 3ac code, not compile\n\n");
+
        fprintf(stderr, "-a: select cpu arch (x64, arm64, naja, or eda), default is x64\n");
        fprintf(stderr, "-s: sysroot dir, default is '../lib'\n");
-       fprintf(stderr, "-d: output dynamic library .so\n");
+       fprintf(stderr, "-d: output dynamic library .so\n\n");
+
+       fprintf(stderr, "-D: define a macro\n");
        fprintf(stderr, "-I: include paths for .h file\n");
        fprintf(stderr, "-l: file name of lib*.so / lib*.a, NOT include prefix 'lib' & post fix '.so' or '.a'\n");
        fprintf(stderr, "-L: file paths for .so / .a file\n");
@@ -168,6 +177,110 @@ int add_so_files(scf_vector_t* vec, const scf_vector_t* lib_paths, const scf_vec
        return 0;
 }
 
+int add_macro(scf_vector_t* macros, const char* s)
+{
+       scf_string_t*    file;
+       scf_lex_word_t*  w0;
+       scf_lex_word_t*  w1;
+       scf_macro_t*     m;
+
+       double  d    = 0.0;
+       int64_t i64  = 1;
+       int     type = SCF_LEX_WORD_CONST_I64;
+
+       scf_logi("s: %s\n", s);
+
+       file = scf_string_cstr("__stdc__.h");
+       if (!file)
+               return -ENOMEM;
+
+       w0 = scf_lex_word_alloc(file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w0)
+               goto w0_error;
+
+       const char* p = s;
+       while (*p && '=' != *p)
+               p++;
+
+       w0->text = scf_string_cstr_len(s, (size_t)(p - s));
+       if (!w0->text)
+               goto t0_error;
+
+       if ('=' == *p) {
+               p++;
+
+               s = p;
+               while (*p && '.' != *p)
+                       p++;
+
+               scf_logi("s: %s\n", s);
+
+               if ('.' == *p) {
+                       type = SCF_LEX_WORD_CONST_DOUBLE;
+                       d    = atof(s);
+
+               } else if ('0' <= *s && *s <= '9')
+                       i64 = atol(s);
+               else
+                       type = SCF_LEX_WORD_CONST_STRING;
+       }
+
+       w1 = scf_lex_word_alloc(file, 0, 0, type);
+       if (!w1)
+               goto t0_error;
+
+       if (SCF_LEX_WORD_CONST_I64 == type) {
+               w1->data.i64 = i64;
+
+               char buf[128];
+               int n = snprintf(buf, sizeof(buf) - 1, "%ld", i64);
+
+               w1->text = scf_string_cstr_len(buf, n);
+
+       } else if (SCF_LEX_WORD_CONST_DOUBLE == type) {
+               w1->data.d = d;
+
+               w1->text = scf_string_cstr(s);
+       } else {
+               w1->data.s = scf_string_cstr(s);
+               if (!w1->data.s)
+                       goto t1_error;
+
+               w1->text = scf_string_clone(w1->data.s);
+       }
+       if (!w1->text)
+               goto t1_error;
+
+       m = scf_macro_alloc(w0);
+       if (!m)
+               goto t1_error;
+
+       m->text_list = w1;
+       w1->next = NULL;
+       w1 = NULL;
+       w0 = NULL;
+
+       scf_string_free(file);
+       file = NULL;
+
+       int ret = scf_vector_add(macros, m);
+       if (ret < 0) {
+               scf_macro_free(m);
+               return ret;
+       }
+
+       m->def_flag = 1;
+       return 0;
+
+t1_error:
+       scf_lex_word_free(w1);
+t0_error:
+       scf_lex_word_free(w0);
+w0_error:
+       scf_string_free(file);
+       return -ENOMEM;
+}
+
 int main(int argc, char* argv[])
 {
        if (argc < 2) {
@@ -185,11 +298,13 @@ int main(int argc, char* argv[])
        scf_vector_t* sofiles = scf_vector_alloc();
        scf_vector_t* srcs    = scf_vector_alloc();
        scf_vector_t* objs    = scf_vector_alloc();
+       scf_vector_t* macros  = scf_vector_alloc();
 
        if (!inc_paths
                        || !lib_paths
                        || !lib_files
-                       || !afiles || !sofiles || !srcs || !objs) {
+                       || !afiles || !sofiles || !srcs || !objs
+                       || !macros) {
                ret = -ENOMEM;
                goto error;
        }
@@ -202,10 +317,18 @@ int main(int argc, char* argv[])
        char* out       = NULL;
        int   link      = 1;
        int   _3ac      = 0;
+       int   _parse    = 0;
        int   dyn       = 0;
        int   c_version = SCF_C99;
 
        int i;
+       for (i = 0; i < sizeof(__h_files) / sizeof(__h_files[0]); i++) {
+
+               ret = scf_vector_add(srcs, __h_files[i]);
+               if (ret < 0)
+                       goto error;
+       }
+
        for (i = 1; i < argc; i++) {
 
                if ('-' == argv[i][0]) {
@@ -215,9 +338,17 @@ int main(int argc, char* argv[])
                                continue;
                        }
 
+                       if ('p' == argv[i][1]) {
+                               link = 0;
+                               _3ac = 0;
+                               _parse = 1;
+                               continue;
+                       }
+
                        if ('t' == argv[i][1]) {
                                link = 0;
                                _3ac = 1;
+                               _parse = 0;
                                continue;
                        }
 
@@ -225,6 +356,7 @@ int main(int argc, char* argv[])
                                dyn  = 1;
                                link = 1;
                                _3ac = 0;
+                               _parse = 0;
                                continue;
                        }
 
@@ -286,6 +418,10 @@ int main(int argc, char* argv[])
                        scf_vector_t* vec = NULL;
 
                        switch (argv[i][1]) {
+                               case 'D':
+                                       vec = macros;
+                                       break;
+
                                case 'I':
                                        vec = inc_paths;
                                        break;
@@ -320,7 +456,10 @@ int main(int argc, char* argv[])
                        } else
                                fname = argv[i] + 2;
 
-                       ret = scf_vector_add(vec, fname);
+                       if (vec == macros)
+                               ret = add_macro(macros, fname);
+                       else
+                               ret = scf_vector_add(vec, fname);
                        if (ret < 0)
                                goto error;
 
@@ -366,6 +505,19 @@ int main(int argc, char* argv[])
 
        printf("\n");
 
+       switch (c_version) {
+               case SCF_C99:
+                       ret = add_macro(macros, "__STDC_VERSION__=199901");
+                       if (ret < 0)
+                               goto error;
+
+               case SCF_C89:
+                       ret = add_macro(macros, "__STDC__=1");
+                       if (ret < 0)
+                               goto error;
+                       break;
+       };
+
        char* obj  = "1.o";
        char* exec = "1.out";
 
@@ -390,23 +542,47 @@ int main(int argc, char* argv[])
 
                        assert(file);
 
-                       ret = scf_parse_file(parse, file);
+                       scf_vector_t* _macros = scf_vector_clone(macros);
+                       if (!_macros) {
+                               ret = -ENOMEM;
+                               goto error;
+                       }
+
+                       scf_macro_t*  m;
+                       int j;
+
+                       for (j = 0; j < _macros->size; j++) {
+                               m  =        _macros->data[j];
+
+                               m->refs++;
+                       }
+
+                       ret = scf_parse_file(parse, file, &_macros, NULL);
+
+                       if (_macros) {
+                               scf_vector_clear(_macros, ( void (*)(void*) )scf_macro_free);
+                               scf_vector_free(_macros);
+                               _macros = NULL;
+                       }
+
                        if (ret < 0) {
                                scf_loge("parse file '%s' failed\n", file);
                                goto error;
                        }
                }
 
-               ret = scf_parse_compile(parse, arch, _3ac);
-               if (ret < 0) {
-                       scf_loge("\n");
-                       goto error;
-               }
+               if (!_parse) {
+                       ret = scf_parse_compile(parse, arch, _3ac);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               goto error;
+                       }
 
-               ret = scf_parse_to_obj(parse, obj, arch);
-               if (ret < 0) {
-                       scf_loge("\n");
-                       goto error;
+                       ret = scf_parse_to_obj(parse, obj, arch);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               goto error;
+                       }
                }
 
                scf_parse_close(parse);
@@ -498,5 +674,10 @@ error:
                scf_vector_free(objs);
        }
 
+       if (macros) {
+               scf_vector_clear(macros, ( void (*)(void*) )scf_macro_free);
+               scf_vector_free(macros);
+       }
+
        return ret;
 }
index c264278e9c00d7c13efc27fd14d496470cfb3d31..44eea36f77c12b129ee9feeeef851911a300fffa 100644 (file)
@@ -117,7 +117,7 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
-       scf_logi("d->expr: %p, OP: %d\n", d->expr, d->expr->type);
+       scf_logd("d->expr: %p, OP: %d\n", d->expr, d->expr->type);
 
        cd->func           = node_pf;
        cd->call           = node_call;
@@ -169,7 +169,7 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_stack_pop(s);
 
-       scf_logi("d->expr: %p\n", d->expr);
+       scf_logd("d->expr: %p\n", d->expr);
 
        if (cd->parent_expr) {
                if (cd->func)
@@ -233,7 +233,7 @@ static int _call_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                scf_loge("\n");
                return SCF_DFA_ERROR;
        }
-       scf_logi("d->expr: %p\n", d->expr);
+       scf_logd("d->expr: %p\n", d->expr);
 
        if (!cd->argv)
                cd->argv = scf_vector_alloc();
index 9c4f0dee5b4f3b6a2ae6f5091bb22ff8bda228fe..b9e0011770f107fba816029a8c6060bf6f8bc007 100644 (file)
@@ -16,6 +16,8 @@ typedef struct {
 
 } dfa_fun_data_t;
 
+int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id);
+
 int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
 {
        scf_parse_t*     parse = dfa->priv;
@@ -230,12 +232,16 @@ int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d)
                        assert(t);
 
                        if (!t->type) {
-                               scf_loge("NO type found for '%s', file: %s, line: %d\n",
-                                               t->identity->text->data,
-                                               t->identity->file->data, t->identity->line);
+                               int ret = _type_find_type(dfa, t);
 
-                               free(t);
-                               return SCF_DFA_ERROR;
+                               if (ret < 0 || !t->type) {
+                                       scf_loge("NO type found for '%s', file: %s, line: %d\n",
+                                                       t->identity->text->data,
+                                                       t->identity->file->data, t->identity->line);
+
+                                       free(t);
+                                       return SCF_DFA_ERROR;
+                               }
                        }
                        break;
 
@@ -246,13 +252,17 @@ int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d)
                        assert(v && v->identity);
 
                        if (!t->type) {
-                               scf_loge("NO type found for '%s', file: %s, line: %d\n",
-                                               t->identity->text->data,
-                                               t->identity->file->data, t->identity->line);
+                               int ret = _type_find_type(dfa, t);
 
-                               free(t);
-                               free(v);
-                               return SCF_DFA_ERROR;
+                               if (ret < 0 || !t->type) {
+                                       scf_loge("NO type found for '%s', file: %s, line: %d\n",
+                                                       t->identity->text->data,
+                                                       t->identity->file->data, t->identity->line);
+
+                                       free(t);
+                                       free(v);
+                                       return SCF_DFA_ERROR;
+                               }
                        }
                        break;
                default:
@@ -269,8 +279,14 @@ int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d)
                        w = v->identity;
 
                if (SCF_VAR_VOID == t->type->node.type && 0 == t->nb_pointers) {
-                       scf_loge("\n");
-                       return SCF_DFA_ERROR;
+                       if (v) {
+                               free(v);
+                               v = NULL;
+                       }
+
+                       free(t);
+                       t = NULL;
+                       return SCF_DFA_NEXT_WORD;
                }
 
                if (!d->current_var) {
index 071b05a0c6a9be7da70e4703f0588a6e52293e7b..a40dd90a347064ea9efafddf45d28f5fa421abbd 100644 (file)
@@ -38,11 +38,14 @@ static int _include_path(uint8_t** path, scf_parse_t* parse, const scf_string_t*
 
 static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       scf_parse_t*     parse  = dfa->priv;
-       dfa_data_t*      d      = data;
-       scf_lex_word_t*  w      = words->data[words->size - 1];
-       scf_lex_t*       lex    = parse->lex;
-       scf_block_t*     cur    = parse->ast->current_block;
+       assert(words->size >= 2);
+
+       scf_parse_t*     parse   = dfa->priv;
+       dfa_data_t*      d       = data;
+       scf_lex_word_t*  include = words->data[words->size - 2];
+       scf_lex_word_t*  w       = words->data[words->size - 1];
+       scf_lex_t*       lex     = parse->lex;
+       scf_block_t*     cur     = parse->ast->current_block;
 
        assert(w->data.s);
 
@@ -52,7 +55,7 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (ret < 0)
                return ret;
        else if (0 == ret) {
-               scf_loge("include '%s' NOT found, at file: %s, line:%d\n", w->data.s->data, w->file->data, w->line);
+               scf_loge("%s:%d:%d, include file '%s' NOT found\n", w->file->data, w->line, w->pos, w->data.s->data);
                return SCF_DFA_ERROR;
        }
 
@@ -63,33 +66,17 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        parse->lex = NULL;
 
-       ret = scf_parse_file(parse, path);
+       ret = scf_parse_file(parse, path, &lex->macros, include);
        if (ret < 0) {
                scf_loge("parse file '%s' failed, 'include' line: %d\n", path, w->line);
                goto error;
        }
 
-       if (parse->lex && parse->lex != lex && parse->lex->macros) { // copy macros
+       if (parse->lex && parse->lex != lex && parse->lex->macros) {
+               assert(!lex->macros);
 
-               if (!lex->macros) {
-                       lex->macros = scf_vector_clone(parse->lex->macros);
-
-                       if (!lex->macros) {
-                               ret = -ENOMEM;
-                               goto error;
-                       }
-               } else {
-                       ret = scf_vector_cat(lex->macros, parse->lex->macros);
-                       if (ret < 0)
-                               goto error;
-               }
-
-               scf_macro_t* m;
-               int i;
-               for (i = 0; i < parse->lex->macros->size; i++) {
-                       m  =        parse->lex->macros->data[i];
-                       m->refs++;
-               }
+               lex->macros        = parse->lex->macros;
+               parse->lex->macros = NULL;
        }
 
        ret = SCF_DFA_NEXT_WORD;
index 5920c8b7d1f8d183050c2c634411ef11347edc74..7ed91c4ad39665bdbeca419417b96dec82fb9a33 100644 (file)
@@ -161,7 +161,7 @@ static int _new_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        md->new = NULL;
 
-       scf_logi("d->expr: %p\n", d->expr);
+       scf_logd("d->expr: %p\n", d->expr);
 
        return SCF_DFA_NEXT_WORD;
 }
index c460f51c3b7b4ff8ec64fe69b35a63d86e50563c..62345c69404283e972d0d1a702f5af8d859d6a04 100644 (file)
@@ -290,7 +290,6 @@ static int _operator_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        d->nb_lps = 0;
        d->nb_rps = 0;
 
-       scf_logi("\n");
        return SCF_DFA_OK;
 }
 
index 4cb546a47c56df8fc284957a677c79041a7de750..74b94295d64b31b7321c6681a1449aaa254ffd5b 100644 (file)
@@ -6,6 +6,124 @@ extern scf_dfa_module_t dfa_module_type;
 
 int __class_add_type(scf_ast_t* ast, scf_lex_word_t* key, scf_lex_word_t* name);
 
+typedef struct {
+       int type;
+       int n;
+       int keys[8];
+
+} type_filter_t;
+
+static type_filter_t  base_type_filters[] =
+{
+       {SCF_VAR_U8,     2, SCF_LEX_WORD_KEY_UNSIGNED, SCF_LEX_WORD_KEY_CHAR},
+       {SCF_VAR_U16,    2, SCF_LEX_WORD_KEY_UNSIGNED, SCF_LEX_WORD_KEY_SHORT},
+       {SCF_VAR_U16,    3, SCF_LEX_WORD_KEY_UNSIGNED, SCF_LEX_WORD_KEY_SHORT, SCF_LEX_WORD_KEY_INT},
+       {SCF_VAR_U32,    2, SCF_LEX_WORD_KEY_UNSIGNED, SCF_LEX_WORD_KEY_INT},
+       {SCF_VAR_U64,    2, SCF_LEX_WORD_KEY_UNSIGNED, SCF_LEX_WORD_KEY_LONG},
+       {SCF_VAR_U64,    3, SCF_LEX_WORD_KEY_UNSIGNED, SCF_LEX_WORD_KEY_LONG, SCF_LEX_WORD_KEY_LONG},
+
+       {SCF_VAR_I8,     2, SCF_LEX_WORD_KEY_SIGNED,   SCF_LEX_WORD_KEY_CHAR},
+       {SCF_VAR_I16,    2, SCF_LEX_WORD_KEY_SIGNED,   SCF_LEX_WORD_KEY_SHORT},
+       {SCF_VAR_I16,    3, SCF_LEX_WORD_KEY_SIGNED,   SCF_LEX_WORD_KEY_SHORT, SCF_LEX_WORD_KEY_INT},
+       {SCF_VAR_I32,    2, SCF_LEX_WORD_KEY_SIGNED,   SCF_LEX_WORD_KEY_INT},
+       {SCF_VAR_I64,    2, SCF_LEX_WORD_KEY_SIGNED,   SCF_LEX_WORD_KEY_LONG},
+       {SCF_VAR_I64,    3, SCF_LEX_WORD_KEY_SIGNED,   SCF_LEX_WORD_KEY_LONG, SCF_LEX_WORD_KEY_LONG},
+
+       {SCF_VAR_INTPTR, 2, SCF_LEX_WORD_KEY_LONG,     SCF_LEX_WORD_KEY_INT},
+       {SCF_VAR_INTPTR, 2, SCF_LEX_WORD_KEY_LONG,     SCF_LEX_WORD_KEY_LONG},
+       {SCF_VAR_DOUBLE, 2, SCF_LEX_WORD_KEY_LONG,     SCF_LEX_WORD_KEY_DOUBLE},
+
+       {SCF_VAR_I16,    2, SCF_LEX_WORD_KEY_SHORT,    SCF_LEX_WORD_KEY_INT},
+};
+
+static int _base_type_filter(scf_dfa_t* dfa, scf_vector_t* words, scf_stack_t* s)
+{
+       if (s->size <= 1)
+               return 0;
+
+       scf_parse_t*     parse = dfa->priv;
+       scf_ast_t*       ast   = parse->ast;
+       scf_lex_word_t*  w;
+       dfa_identity_t*  id;
+       type_filter_t*   tf;
+       int i;
+       int j;
+
+       assert(words->size >= s->size);
+
+       i = words->size - 2;
+       j = s->size - 1;
+
+       while (i >= 0 && j > 0) {
+               w = words->data[i];
+
+               if (!scf_lex_is_base_type(w))
+                       break;
+
+               i--;
+               j--;
+       }
+
+       assert(j >= 0);
+
+       if (s->size - j <= 1)
+               return 0;
+
+       for (i = 0; i < sizeof(base_type_filters) / sizeof(base_type_filters[0]); i++) {
+               tf = &base_type_filters[i];
+
+               if (tf->n != s->size - j)
+                       continue;
+
+               int k;
+               for (k = j; k < s->size; k++) {
+                       id =        s->data[k];
+
+                       if (id->type_w->type != tf->keys[k - j])
+                               break;
+               }
+
+               if (k >= s->size) {
+                       id = s->data[j];
+
+                       id->type = scf_block_find_type_type(ast->current_block, tf->type);
+                       if (!id->type)
+                               goto error;
+
+                       w = dfa->ops->pop_word(dfa);
+                       if (!w)
+                               return -ENOMEM;
+                       dfa->ops->push_word(dfa, w);
+
+                       if (!scf_lex_is_base_type(w)) {
+
+                               while (s->size > j + 1) {
+                                       id = scf_stack_pop(s);
+
+                                       free(id);
+                                       id = NULL;
+                               }
+                       }
+
+                       return 0;
+               }
+       }
+
+error:
+       id = s->data[j];
+
+       scf_loge("%s:%d:%d, NOT support type: ", id->type_w->file->data, id->type_w->line, id->type_w->pos);
+
+       for ( ; j < s->size; j++) {
+               id    = s->data[j];
+
+               printf("%s ", id->type_w->text->data);
+       }
+       printf("\n");
+
+       return -1;
+}
+
 static int _type_is__struct(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
@@ -98,6 +216,9 @@ static int _type_action_base_type(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        d->inline_flag   = 0;
        d->typedef_flag  = 0;
 
+       if (_base_type_filter(dfa, words, s) < 0)
+               return SCF_DFA_ERROR;
+
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -207,10 +328,12 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
                        }
                }
 
-               ret = _type_find_type(dfa, type);
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return ret;
+               if (!type->type) {
+                       ret = _type_find_type(dfa, type);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               return ret;
+                       }
                }
 
                if (d->typedef_flag) {
@@ -236,8 +359,8 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
 
 static int _type_action_star(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       dfa_data_t* d  = data;
-       dfa_identity_t*   id = scf_stack_top(d->current_identities);
+       dfa_data_t*      d  = data;
+       dfa_identity_t*  id = scf_stack_top(d->current_identities);
 
        assert(id);
 
@@ -302,11 +425,13 @@ static int _dfa_init_module_type(scf_dfa_t* dfa)
        SCF_DFA_MODULE_NODE(dfa, type, _struct,   _type_is__struct,     NULL);
 
        SCF_DFA_MODULE_NODE(dfa, type, _typedef,  scf_dfa_is_typedef,   _type_action_typedef);
-       SCF_DFA_MODULE_NODE(dfa, type, _const,    scf_dfa_is_const,     _type_action_const);
        SCF_DFA_MODULE_NODE(dfa, type, _static,   scf_dfa_is_static,    _type_action_static);
        SCF_DFA_MODULE_NODE(dfa, type, _extern,   scf_dfa_is_extern,    _type_action_extern);
        SCF_DFA_MODULE_NODE(dfa, type, _inline,   scf_dfa_is_inline,    _type_action_inline);
 
+       SCF_DFA_MODULE_NODE(dfa, type, _const,    scf_dfa_is_const,     _type_action_const);
+       SCF_DFA_MODULE_NODE(dfa, type, vconst,    scf_dfa_is_const,     _type_action_const);
+
        SCF_DFA_MODULE_NODE(dfa, type, base_type, scf_dfa_is_base_type, _type_action_base_type);
        SCF_DFA_MODULE_NODE(dfa, type, identity,  scf_dfa_is_identity,  _type_action_identity);
        SCF_DFA_MODULE_NODE(dfa, type, star,      scf_dfa_is_star,      _type_action_star);
@@ -322,10 +447,11 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, type,     entry,     entry);
 
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _typedef,  _typedef);
-       SCF_DFA_GET_MODULE_NODE(dfa, type,     _const,    _const);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _static,   _static);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _extern,   _extern);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _inline,   _inline);
+       SCF_DFA_GET_MODULE_NODE(dfa, type,     _const,    _const);
+       SCF_DFA_GET_MODULE_NODE(dfa, type,     vconst,    vconst);
 
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _struct,   _struct);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     base_type, base_type);
@@ -377,6 +503,9 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
        scf_dfa_node_add_child(_extern,   _const);
        scf_dfa_node_add_child(_inline,   _const);
 
+       // for long long, long int, long double, short int, ...
+       scf_dfa_node_add_child(base_type, base_type);
+
        // struct / union / class
        scf_dfa_node_add_child(_struct,   type_name);
        scf_dfa_node_add_child(type_name, class_semicolon); // only declare
@@ -393,6 +522,10 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
        scf_dfa_node_add_child(base_type, var_name);
        scf_dfa_node_add_child(type_name, var_name);
 
+       // const pointer, like 'uint8_t* const p'
+       scf_dfa_node_add_child(star,      vconst);
+       scf_dfa_node_add_child(vconst,    var_name);
+
        // multi-return-value function
        scf_dfa_node_add_child(base_type, comma);
        scf_dfa_node_add_child(star,      comma);
index 63f5008edc22268dacd4e319e1667ebcc789f9ac..8a8a94818c06f04a10560702279dafc177c6a616 100644 (file)
@@ -578,10 +578,14 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
        d->nb_lss = 0;
        d->nb_rss = 0;
 
-       id = scf_stack_pop(d->current_identities);
-       assert(id && id->type);
-       free(id);
-       id = NULL;
+       while (d->current_identities->size > 0)
+       {
+               id = scf_stack_pop(d->current_identities);
+               assert(id && id->type);
+
+               free(id);
+               id = NULL;
+       }
 
        if (d->current_var) {
                scf_variable_size(d->current_var);
index 11585714fd24afcae24d7a3a522559d55830bbcc..38a3836d6a89103fefa2e69eba6ec0eddd2bbaa0 100644 (file)
@@ -42,6 +42,11 @@ scf_base_type_t  base_types[] =
        {"intptr_t",  SCF_VAR_INTPTR,   sizeof(void*)},
        {"uintptr_t", SCF_VAR_UINTPTR,  sizeof(void*)},
        {"funcptr",   SCF_FUNCTION_PTR, sizeof(void*)},
+
+       {"short",     SCF_VAR_I16,    2},
+       {"signed",    SCF_VAR_INT,    4},
+       {"unsigned",  SCF_VAR_U32,    4},
+       {"long",      SCF_VAR_INTPTR, sizeof(void*)},
 };
 
 int scf_parse_open(scf_parse_t** pparse, const scf_vector_t* inc_paths, int c_version)
@@ -104,7 +109,7 @@ int scf_parse_close(scf_parse_t* parse)
        return 0;
 }
 
-int scf_parse_file(scf_parse_t* parse, const char* path)
+int scf_parse_file(scf_parse_t* parse, const char* path, scf_vector_t** macros, scf_lex_word_t* include)
 {
        if (!parse || !path)
                return -EINVAL;
@@ -119,13 +124,24 @@ int scf_parse_file(scf_parse_t* parse, const char* path)
 
        lex = cur->lex_list;
        while (lex) {
-               if (!strcmp(lex->file->data, path))
-                       return 0;
+               if (!strcmp(lex->file->data, path)) {
+
+                       if (!include) {
+                               scf_loge("repeated compile file '%s'\n", path);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       assert(lex->included);
+
+                       scf_logw("%s:%d:%d, repeated #include file '%s', prev at %s:%d:%d\n",
+                                       include->file->data, include->line, include->pos, path,
+                                       lex->included->file->data, lex->included->line, lex->included->pos);
+               }
 
                lex = lex->next;
        }
 
-       if (scf_lex_open(&parse->lex, path, NULL, parse->c_version) < 0)
+       if (scf_lex_open(&parse->lex, path, NULL, parse->c_version, include) < 0)
                return -1;
 
        if (cur == ast->root_block)
@@ -134,6 +150,9 @@ int scf_parse_file(scf_parse_t* parse, const char* path)
        parse->lex->next = cur->lex_list;
        cur->lex_list    = parse->lex;
 
+       parse->lex->macros = *macros;
+       *macros = NULL;
+
        dfa_data_t*      d = parse->dfa_data;
        scf_lex_word_t*  w = NULL;
 
index 5e41f7a1c97eccce74dac0dc44377112ae709b8a..2dbbcc5ab5209a7d1e34052cf091f1bf6cb8a73b 100644 (file)
@@ -125,10 +125,9 @@ int scf_parse_dfa_init(scf_parse_t* parse);
 int scf_parse_open (scf_parse_t** pparse, const scf_vector_t* inc_paths, int c_version);
 int scf_parse_close(scf_parse_t*   parse);
 
-int scf_parse_file(scf_parse_t* parse, const char* path);
-
+int scf_parse_file   (scf_parse_t* parse, const char* path, scf_vector_t** macros, scf_lex_word_t* include);
 int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac);
-int scf_parse_to_obj (scf_parse_t* parse, const char* out, const char* arch);
+int scf_parse_to_obj (scf_parse_t* parse, const char* out,  const char* arch);
 
 int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec);
 int _find_function  (scf_node_t* node, void* arg, scf_vector_t* vec);
diff --git a/sysroot/include/features.h b/sysroot/include/features.h
new file mode 100644 (file)
index 0000000..85cfb72
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _FEATURES_H
+#define _FEATURES_H
+
+#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE 1
+#endif
+
+#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)
+#define _BSD_SOURCE 1
+#endif
+
+#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \
+ && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \
+ && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
+#define _BSD_SOURCE 1
+#define _XOPEN_SOURCE 700
+#endif
+
+#if __STDC_VERSION__ >= 199901L
+#define __restrict restrict
+#elif !defined(__GNUC__)
+#define __restrict
+#endif
+
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+#define __inline inline
+#elif !defined(__GNUC__)
+#define __inline
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#elif defined(__GNUC__)
+#define _Noreturn __attribute__((__noreturn__))
+#else
+#define _Noreturn
+#endif
+
+#define __REDIR(x,y) __typeof__(x) x __asm__(#y)
+
+#endif
index 4ea4c17077a3bd5c7ee6144d1a8c9e46549bc920..77ef218e946e87ae6e74f7be365e0ed1534b3775 100644 (file)
@@ -30,7 +30,7 @@ extern "C" {
 #elif defined(__cplusplus)
 #define NULL 0L
 #else
-#define NULL ((void*)0)
+//#define NULL ((void*)0)
 #endif
 
 #undef EOF
diff --git a/sysroot/lib/__builtin__.h b/sysroot/lib/__builtin__.h
new file mode 100644 (file)
index 0000000..349657f
--- /dev/null
@@ -0,0 +1,10 @@
+struct __builtin_va_list
+{
+       uint8_t*  iptr;
+       uint8_t*  fptr;
+       uint8_t*  optr;
+
+       intptr_t  ireg;
+       intptr_t  freg;
+       intptr_t  others;
+};