From 82021000a4f0af3ab9db17b87ec7a25090eed4e0 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Thu, 6 Aug 2026 00:32:34 +0800 Subject: [PATCH] 1, #include "stdio.h" of 'musl libc' ok, 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. --- core/scf_lex_word.h | 6 + examples/c89.c | 9 ++ examples/hello.c | 2 +- examples/hello.h | 4 - examples/unsigned_long_short.c | 18 +++ lex/scf_lex.c | 132 +++++++++++----- lex/scf_lex.h | 19 ++- lex/scf_lex_test.c | 2 +- lex/scf_macro.c | 96 +++++++++++- lex/scf_macro_expr.c | 53 +++---- parse/main.c | 211 ++++++++++++++++++++++++-- parse/scf_dfa_call.c | 6 +- parse/scf_dfa_function.c | 42 +++-- parse/scf_dfa_include.c | 41 ++--- parse/scf_dfa_new.c | 2 +- parse/scf_dfa_operator.c | 1 - parse/scf_dfa_type.c | 149 +++++++++++++++++- parse/scf_dfa_var.c | 12 +- parse/scf_parse.c | 27 +++- parse/scf_parse.h | 5 +- sysroot/include/{ => bits}/alltypes.h | 0 sysroot/include/{ => bits}/syscall.h | 0 sysroot/include/features.h | 40 +++++ sysroot/include/stdio.h | 2 +- sysroot/lib/__builtin__.h | 10 ++ 25 files changed, 726 insertions(+), 163 deletions(-) create mode 100644 examples/c89.c delete mode 100644 examples/hello.h create mode 100644 examples/unsigned_long_short.c rename sysroot/include/{ => bits}/alltypes.h (100%) rename sysroot/include/{ => bits}/syscall.h (100%) create mode 100644 sysroot/include/features.h create mode 100644 sysroot/lib/__builtin__.h diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index fae6d83..92a2b5d 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -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 index 0000000..5d4aaef --- /dev/null +++ b/examples/c89.c @@ -0,0 +1,9 @@ +int printf(const char* fmt, ...); + +int main() +{ + int restrict = 1; + + printf("restrict: %d\n", restrict); + return 0; +} diff --git a/examples/hello.c b/examples/hello.c index 52b0cd9..a4f61fe 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -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 index 281333b..0000000 --- a/examples/hello.h +++ /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 index 0000000..1b9eed5 --- /dev/null +++ b/examples/unsigned_long_short.c @@ -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; +} diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 5512eb6..693aef6 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -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; } diff --git a/lex/scf_lex.h b/lex/scf_lex.h index bacbe0d..0b6bb48 100644 --- a/lex/scf_lex.h +++ b/lex/scf_lex.h @@ -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); diff --git a/lex/scf_lex_test.c b/lex/scf_lex_test.c index 3617057..4ba9fdc 100644 --- a/lex/scf_lex_test.c +++ b/lex/scf_lex_test.c @@ -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; } diff --git a/lex/scf_macro.c b/lex/scf_macro.c index b4c8f3d..e85a408 100644 --- a/lex/scf_macro.c +++ b/lex/scf_macro.c @@ -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; diff --git a/lex/scf_macro_expr.c b/lex/scf_macro_expr.c index 8548a30..4c146ba 100644 --- a/lex/scf_macro_expr.c +++ b/lex/scf_macro_expr.c @@ -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; } diff --git a/parse/main.c b/parse/main.c index 61fe9e1..041367f 100644 --- a/parse/main.c +++ b/parse/main.c @@ -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; } diff --git a/parse/scf_dfa_call.c b/parse/scf_dfa_call.c index c264278..44eea36 100644 --- a/parse/scf_dfa_call.c +++ b/parse/scf_dfa_call.c @@ -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(); diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 9c4f0de..b9e0011 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -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) { diff --git a/parse/scf_dfa_include.c b/parse/scf_dfa_include.c index 071b05a..a40dd90 100644 --- a/parse/scf_dfa_include.c +++ b/parse/scf_dfa_include.c @@ -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; diff --git a/parse/scf_dfa_new.c b/parse/scf_dfa_new.c index 5920c8b..7ed91c4 100644 --- a/parse/scf_dfa_new.c +++ b/parse/scf_dfa_new.c @@ -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; } diff --git a/parse/scf_dfa_operator.c b/parse/scf_dfa_operator.c index c460f51..62345c6 100644 --- a/parse/scf_dfa_operator.c +++ b/parse/scf_dfa_operator.c @@ -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; } diff --git a/parse/scf_dfa_type.c b/parse/scf_dfa_type.c index 4cb546a..74b9429 100644 --- a/parse/scf_dfa_type.c +++ b/parse/scf_dfa_type.c @@ -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); diff --git a/parse/scf_dfa_var.c b/parse/scf_dfa_var.c index 63f5008..8a8a948 100644 --- a/parse/scf_dfa_var.c +++ b/parse/scf_dfa_var.c @@ -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); diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 1158571..38a3836 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -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; diff --git a/parse/scf_parse.h b/parse/scf_parse.h index 5e41f7a..2dbbcc5 100644 --- a/parse/scf_parse.h +++ b/parse/scf_parse.h @@ -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/alltypes.h b/sysroot/include/bits/alltypes.h similarity index 100% rename from sysroot/include/alltypes.h rename to sysroot/include/bits/alltypes.h diff --git a/sysroot/include/syscall.h b/sysroot/include/bits/syscall.h similarity index 100% rename from sysroot/include/syscall.h rename to sysroot/include/bits/syscall.h diff --git a/sysroot/include/features.h b/sysroot/include/features.h new file mode 100644 index 0000000..85cfb72 --- /dev/null +++ b/sysroot/include/features.h @@ -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 diff --git a/sysroot/include/stdio.h b/sysroot/include/stdio.h index 4ea4c17..77ef218 100644 --- a/sysroot/include/stdio.h +++ b/sysroot/include/stdio.h @@ -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 index 0000000..349657f --- /dev/null +++ b/sysroot/lib/__builtin__.h @@ -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; +}; -- 2.25.1