From: yu.dongliang <18588496441@163.com> Date: Fri, 3 Jul 2026 03:51:26 +0000 (+0800) Subject: 1, support macro expr in #if, X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=6c468f3624709cfc71102853f1cb7e52464551b5;p=scf.git 1, support macro expr in #if, 2, support C style function pointer, 3, support C style union & struct, 4, support trinary operator in #if macro expr. --- diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index 4a8010c..15dfb57 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -10,26 +10,26 @@ typedef struct scf_macro_s scf_macro_t; enum scf_lex_words { - SCF_LEX_WORD_PLUS = 0, // + - SCF_LEX_WORD_MINUS, // - - SCF_LEX_WORD_STAR, // * - SCF_LEX_WORD_DIV, // / div + SCF_LEX_WORD_PLUS = 0, // + + SCF_LEX_WORD_MINUS, // - + SCF_LEX_WORD_STAR, // * + SCF_LEX_WORD_DIV, // / div SCF_LEX_WORD_MOD, // % - SCF_LEX_WORD_INC, // ++ - SCF_LEX_WORD_DEC, // -- + SCF_LEX_WORD_INC, // ++ + SCF_LEX_WORD_DEC, // -- SCF_LEX_WORD_SHL, // << SCF_LEX_WORD_SHR, // >> - SCF_LEX_WORD_BIT_AND, // & - SCF_LEX_WORD_BIT_OR, // | - SCF_LEX_WORD_BIT_NOT, // ~ + SCF_LEX_WORD_BIT_AND, // & + SCF_LEX_WORD_BIT_OR, // | + SCF_LEX_WORD_BIT_NOT, // ~ + SCF_LEX_WORD_BIT_XOR, // ^ SCF_LEX_WORD_LOGIC_AND, // && SCF_LEX_WORD_LOGIC_OR, // || SCF_LEX_WORD_LOGIC_NOT, // ! - SCF_LEX_WORD_LOGIC_XOR, // xor SCF_LEX_WORD_ASSIGN, // = assign SCF_LEX_WORD_ADD_ASSIGN, // += @@ -64,10 +64,16 @@ enum scf_lex_words SCF_LEX_WORD_KEY_NEW, // create class object SCF_LEX_WORD_KEY_CONTAINER, // container_of SCF_LEX_WORD_KEY_VA_ARG, // va_arg + SCF_LEX_WORD_KEY_DEFINED, // #defined + + SCF_LEX_WORD_Q_MASK, // ? + SCF_LEX_WORD_COLON, // : colon SCF_LEX_WORD_ARROW, // -> arrow SCF_LEX_WORD_DOT, // . dot + SCF_LEX_N_OPS, // number of operators + SCF_LEX_WORD_RANGE, // .. range SCF_LEX_WORD_VAR_ARGS, // ... variable args @@ -81,7 +87,6 @@ enum scf_lex_words SCF_LEX_WORD_COMMA, // , comma SCF_LEX_WORD_SEMICOLON, // ; - SCF_LEX_WORD_COLON, // : colon SCF_LEX_WORD_SPACE, // ' ' space // eof diff --git a/examples/c_func_pointer.c b/examples/c_func_pointer.c new file mode 100644 index 0000000..f2bda8b --- /dev/null +++ b/examples/c_func_pointer.c @@ -0,0 +1,11 @@ +int printf(const char* fmt, ...); + +int (*pf)(const char* fmt, ...); + +int main() +{ + pf = printf; + + pf("hello world\n"); + return 0; +} diff --git a/examples/macro_if.c b/examples/macro_if.c new file mode 100644 index 0000000..d3bd497 --- /dev/null +++ b/examples/macro_if.c @@ -0,0 +1,10 @@ +#if 1 ? 2 < 3 ? 0 : 4 : 5 +int printf(const char* fmt, ...); +#else +#endif + +int main() +{ + printf("hello world\n"); + return 0; +} diff --git a/examples/union_float_reg.c b/examples/union_float_reg.c new file mode 100644 index 0000000..e1fe203 --- /dev/null +++ b/examples/union_float_reg.c @@ -0,0 +1,20 @@ +int printf(const char* fmt, ...); + +union Reg { + uint32_t data; + + struct { + uint32_t decimal:23; + uint32_t exp :8; + uint32_t sign:1; + }; +}; + +int main() +{ + Reg r; + r.data = 0x3f800000; + + printf("r.decimal: %#x, r.exp: %#x, r.sign: %#x\n", r.decimal, r.exp, r.sign); + return 0; +} diff --git a/lex/Makefile b/lex/Makefile index f6b9436..aa6938e 100644 --- a/lex/Makefile +++ b/lex/Makefile @@ -1,8 +1,9 @@ CFILES += ../util/scf_string.c +CFILES += ../core/scf_lex_word.c CFILES += scf_lex.c CFILES += scf_lex_util.c CFILES += scf_macro.c -CFILES += ../core/scf_lex_word.c +CFILES += scf_macro_expr.c CFILES += scf_lex_test.c CFLAGS += -g diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 148ec60..068b6c6 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -2,103 +2,104 @@ static scf_key_word_t key_words[] = { - {"if", SCF_LEX_WORD_KEY_IF}, - {"else", SCF_LEX_WORD_KEY_ELSE}, - - {"include", SCF_LEX_WORD_KEY_INCLUDE}, - {"define", SCF_LEX_WORD_KEY_DEFINE}, - {"undef", SCF_LEX_WORD_KEY_UNDEF}, - - {"ifdef", SCF_LEX_WORD_KEY_IFDEF}, - {"ifndef", SCF_LEX_WORD_KEY_IFNDEF}, - {"elif", SCF_LEX_WORD_KEY_ELIF}, - {"endif", SCF_LEX_WORD_KEY_ENDIF}, - - {"for", SCF_LEX_WORD_KEY_FOR}, - {"while", SCF_LEX_WORD_KEY_WHILE}, - {"do", SCF_LEX_WORD_KEY_DO}, - - {"break", SCF_LEX_WORD_KEY_BREAK}, - {"continue", SCF_LEX_WORD_KEY_CONTINUE}, - {"goto", SCF_LEX_WORD_KEY_GOTO}, - - {"switch", SCF_LEX_WORD_KEY_SWITCH}, - {"case", SCF_LEX_WORD_KEY_CASE}, - {"default", SCF_LEX_WORD_KEY_DEFAULT}, - - {"return", SCF_LEX_WORD_KEY_RETURN}, - - {"sizeof", SCF_LEX_WORD_KEY_SIZEOF}, - {"typeof", SCF_LEX_WORD_KEY_TYPEOF}, - - {"new", SCF_LEX_WORD_KEY_NEW}, - {"operator", SCF_LEX_WORD_KEY_OPERATOR}, - - {"_", SCF_LEX_WORD_KEY_UNDERLINE}, - - {"char", SCF_LEX_WORD_KEY_CHAR}, - - {"int", SCF_LEX_WORD_KEY_INT}, - {"float", SCF_LEX_WORD_KEY_FLOAT}, - {"double", SCF_LEX_WORD_KEY_DOUBLE}, - {"bit", SCF_LEX_WORD_KEY_BIT}, - {"bit2_t", SCF_LEX_WORD_KEY_BIT2}, - {"bit3_t", SCF_LEX_WORD_KEY_BIT3}, - {"bit4_t", SCF_LEX_WORD_KEY_BIT4}, - - {"int8_t", SCF_LEX_WORD_KEY_INT8}, - {"int1_t", SCF_LEX_WORD_KEY_INT1}, - {"int2_t", SCF_LEX_WORD_KEY_INT2}, - {"int3_t", SCF_LEX_WORD_KEY_INT3}, - {"int4_t", SCF_LEX_WORD_KEY_INT4}, - {"int16_t", SCF_LEX_WORD_KEY_INT16}, - {"int32_t", SCF_LEX_WORD_KEY_INT32}, - {"int64_t", SCF_LEX_WORD_KEY_INT64}, - - {"uint8_t", SCF_LEX_WORD_KEY_UINT8}, - {"uint16_t", SCF_LEX_WORD_KEY_UINT16}, - {"uint32_t", SCF_LEX_WORD_KEY_UINT32}, - {"uint64_t", SCF_LEX_WORD_KEY_UINT64}, - - {"intptr_t", SCF_LEX_WORD_KEY_INTPTR}, - {"uintptr_t", SCF_LEX_WORD_KEY_UINTPTR}, - - {"void", SCF_LEX_WORD_KEY_VOID}, - - {"va_start", SCF_LEX_WORD_KEY_VA_START}, - {"va_arg", SCF_LEX_WORD_KEY_VA_ARG}, - {"va_end", SCF_LEX_WORD_KEY_VA_END}, - - {"container", SCF_LEX_WORD_KEY_CONTAINER}, - - {"class", SCF_LEX_WORD_KEY_CLASS}, - {"typedef", SCF_LEX_WORD_KEY_TYPEDEF}, - - {"const", SCF_LEX_WORD_KEY_CONST}, - {"static", SCF_LEX_WORD_KEY_STATIC}, - {"extern", SCF_LEX_WORD_KEY_EXTERN}, - {"inline", SCF_LEX_WORD_KEY_INLINE}, - - {"async", SCF_LEX_WORD_KEY_ASYNC}, - {"await", SCF_LEX_WORD_KEY_AWAIT}, - - {"enum", SCF_LEX_WORD_KEY_ENUM}, - {"union", SCF_LEX_WORD_KEY_UNION}, - {"struct", SCF_LEX_WORD_KEY_STRUCT}, - - {".text", SCF_LEX_WORD_ASM_TEXT}, - {".data", SCF_LEX_WORD_ASM_DATA}, - {".global", SCF_LEX_WORD_ASM_GLOBAL}, - {".align", SCF_LEX_WORD_ASM_ALIGN}, - {".org", SCF_LEX_WORD_ASM_ORG}, - - {".fill", SCF_LEX_WORD_ASM_FILL}, - {".byte", SCF_LEX_WORD_ASM_BYTE}, - {".word", SCF_LEX_WORD_ASM_WORD}, - {".long", SCF_LEX_WORD_ASM_LONG}, - {".quad", SCF_LEX_WORD_ASM_QUAD}, - {".ascii", SCF_LEX_WORD_ASM_ASCII}, - {".asciz", SCF_LEX_WORD_ASM_ASCIZ}, + {SCF_CSTR("if"), SCF_LEX_WORD_KEY_IF}, + {SCF_CSTR("else"), SCF_LEX_WORD_KEY_ELSE}, + + {SCF_CSTR("include"), SCF_LEX_WORD_KEY_INCLUDE}, + {SCF_CSTR("define"), SCF_LEX_WORD_KEY_DEFINE}, + {SCF_CSTR("defined"), SCF_LEX_WORD_KEY_DEFINED}, + {SCF_CSTR("undef"), SCF_LEX_WORD_KEY_UNDEF}, + + {SCF_CSTR("ifdef"), SCF_LEX_WORD_KEY_IFDEF}, + {SCF_CSTR("ifndef"), SCF_LEX_WORD_KEY_IFNDEF}, + {SCF_CSTR("elif"), SCF_LEX_WORD_KEY_ELIF}, + {SCF_CSTR("endif"), SCF_LEX_WORD_KEY_ENDIF}, + + {SCF_CSTR("for"), SCF_LEX_WORD_KEY_FOR}, + {SCF_CSTR("while"), SCF_LEX_WORD_KEY_WHILE}, + {SCF_CSTR("do"), SCF_LEX_WORD_KEY_DO}, + + {SCF_CSTR("break"), SCF_LEX_WORD_KEY_BREAK}, + {SCF_CSTR("continue"), SCF_LEX_WORD_KEY_CONTINUE}, + {SCF_CSTR("goto"), SCF_LEX_WORD_KEY_GOTO}, + + {SCF_CSTR("switch"), SCF_LEX_WORD_KEY_SWITCH}, + {SCF_CSTR("case"), SCF_LEX_WORD_KEY_CASE}, + {SCF_CSTR("default"), SCF_LEX_WORD_KEY_DEFAULT}, + + {SCF_CSTR("return"), SCF_LEX_WORD_KEY_RETURN}, + + {SCF_CSTR("sizeof"), SCF_LEX_WORD_KEY_SIZEOF}, + {SCF_CSTR("typeof"), SCF_LEX_WORD_KEY_TYPEOF}, + + {SCF_CSTR("new"), SCF_LEX_WORD_KEY_NEW}, + {SCF_CSTR("operator"), SCF_LEX_WORD_KEY_OPERATOR}, + + {SCF_CSTR("_"), SCF_LEX_WORD_KEY_UNDERLINE}, + + {SCF_CSTR("char"), SCF_LEX_WORD_KEY_CHAR}, + + {SCF_CSTR("int"), SCF_LEX_WORD_KEY_INT}, + {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}, + {SCF_CSTR("bit4_t"), SCF_LEX_WORD_KEY_BIT4}, + + {SCF_CSTR("int8_t"), SCF_LEX_WORD_KEY_INT8}, + {SCF_CSTR("int1_t"), SCF_LEX_WORD_KEY_INT1}, + {SCF_CSTR("int2_t"), SCF_LEX_WORD_KEY_INT2}, + {SCF_CSTR("int3_t"), SCF_LEX_WORD_KEY_INT3}, + {SCF_CSTR("int4_t"), SCF_LEX_WORD_KEY_INT4}, + {SCF_CSTR("int16_t"), SCF_LEX_WORD_KEY_INT16}, + {SCF_CSTR("int32_t"), SCF_LEX_WORD_KEY_INT32}, + {SCF_CSTR("int64_t"), SCF_LEX_WORD_KEY_INT64}, + + {SCF_CSTR("uint8_t"), SCF_LEX_WORD_KEY_UINT8}, + {SCF_CSTR("uint16_t"), SCF_LEX_WORD_KEY_UINT16}, + {SCF_CSTR("uint32_t"), SCF_LEX_WORD_KEY_UINT32}, + {SCF_CSTR("uint64_t"), SCF_LEX_WORD_KEY_UINT64}, + + {SCF_CSTR("intptr_t"), SCF_LEX_WORD_KEY_INTPTR}, + {SCF_CSTR("uintptr_t"), SCF_LEX_WORD_KEY_UINTPTR}, + + {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}, + {SCF_CSTR("typedef"), SCF_LEX_WORD_KEY_TYPEDEF}, + + {SCF_CSTR("const"), SCF_LEX_WORD_KEY_CONST}, + {SCF_CSTR("static"), SCF_LEX_WORD_KEY_STATIC}, + {SCF_CSTR("extern"), SCF_LEX_WORD_KEY_EXTERN}, + {SCF_CSTR("inline"), SCF_LEX_WORD_KEY_INLINE}, + + {SCF_CSTR("async"), SCF_LEX_WORD_KEY_ASYNC}, + {SCF_CSTR("await"), SCF_LEX_WORD_KEY_AWAIT}, + + {SCF_CSTR("enum"), SCF_LEX_WORD_KEY_ENUM}, + {SCF_CSTR("union"), SCF_LEX_WORD_KEY_UNION}, + {SCF_CSTR("struct"), SCF_LEX_WORD_KEY_STRUCT}, + + {SCF_CSTR(".text"), SCF_LEX_WORD_ASM_TEXT}, + {SCF_CSTR(".data"), SCF_LEX_WORD_ASM_DATA}, + {SCF_CSTR(".global"), SCF_LEX_WORD_ASM_GLOBAL}, + {SCF_CSTR(".align"), SCF_LEX_WORD_ASM_ALIGN}, + {SCF_CSTR(".org"), SCF_LEX_WORD_ASM_ORG}, + + {SCF_CSTR(".fill"), SCF_LEX_WORD_ASM_FILL}, + {SCF_CSTR(".byte"), SCF_LEX_WORD_ASM_BYTE}, + {SCF_CSTR(".word"), SCF_LEX_WORD_ASM_WORD}, + {SCF_CSTR(".long"), SCF_LEX_WORD_ASM_LONG}, + {SCF_CSTR(".quad"), SCF_LEX_WORD_ASM_QUAD}, + {SCF_CSTR(".ascii"), SCF_LEX_WORD_ASM_ASCII}, + {SCF_CSTR(".asciz"), SCF_LEX_WORD_ASM_ASCIZ}, }; static scf_escape_char_t escape_chars[] = @@ -109,13 +110,16 @@ static scf_escape_char_t escape_chars[] = {'0', '\0'}, }; -int _find_key_word(const char* text) +int _find_key_word(const scf_string_t* text) { + scf_key_word_t* key; int i; - for (i = 0; i < sizeof(key_words) / sizeof(key_words[0]); i++) { - if (!strcmp(key_words[i].text, text)) - return key_words[i].type; + for (i = 0; i < sizeof(key_words) / sizeof(key_words[0]); i++) { + key = &key_words[i]; + + if (text->len == key->len && !memcmp(text->data, key->text, key->len)) + return key->type; } return -1; @@ -405,29 +409,29 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0) scf_lex_word_t* w = NULL; - if (!strcmp(s->data, "NULL")) { + if (SCF_CSTR_CMP(s, "NULL")) { w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); if (w) w->data.u64 = 0; - } else if (!strcmp(s->data, "__LINE__")) { + } else if (SCF_CSTR_CMP(s, "__LINE__")) { w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64); if (w) w->data.u64 = lex->nb_lines; - } else if (!strcmp(s->data, "__FILE__")) { + } else if (SCF_CSTR_CMP(s, "__FILE__")) { w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING); if (w) w->data.s = scf_string_clone(lex->file); - } else if (!strcmp(s->data, "__func__")) { + } else if (SCF_CSTR_CMP(s, "__func__")) { w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING); } else { - int type = _find_key_word(s->data); + int type = _find_key_word(s); if (-1 == type) w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_ID); @@ -798,6 +802,9 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) case ';': return _lex_op1_ll1(lex, pword, c, SCF_LEX_WORD_SEMICOLON); break; + case '?': + return _lex_op1_ll1(lex, pword, c, SCF_LEX_WORD_Q_MASK); + break; case ':': return _lex_op1_ll1(lex, pword, c, SCF_LEX_WORD_COLON); break; diff --git a/lex/scf_lex.h b/lex/scf_lex.h index 386ab3a..1e8a672 100644 --- a/lex/scf_lex.h +++ b/lex/scf_lex.h @@ -8,9 +8,13 @@ typedef struct scf_lex_s scf_lex_t; typedef struct { char* text; + int len; int type; } scf_key_word_t; +#define SCF_CSTR(_cstr) (_cstr), (sizeof(_cstr) - 1) +#define SCF_CSTR_CMP(_s, _cstr) (sizeof(_cstr) - 1 == (_s)->len && !memcmp((_s)->data, (_cstr), sizeof(_cstr) - 1)) + typedef struct { int origin; int escape; @@ -53,7 +57,6 @@ struct scf_lex_s 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 scf_lex_close(scf_lex_t* lex); @@ -63,6 +66,12 @@ int scf_lex_pop_word (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 __macro_if_expr(scf_lex_t* lex); + +int __macro_pop_to (scf_lex_t* lex, scf_lex_word_t** h, scf_lex_word_t** pw1, scf_lex_word_t** pw2); +int __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t** pw2); +int __macro_drop_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); @@ -70,9 +79,9 @@ 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); int _lex_number_base_8 (scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s); int _lex_number_base_2 (scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s); -int _lex_double (scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s); -int _lex_dot (scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0); +int _lex_double(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s); +int _lex_dot (scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0); int _lex_op1_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, int type0); int _lex_op2_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0, int type0, char* chs, int* types, int n); diff --git a/lex/scf_lex_util.c b/lex/scf_lex_util.c index 26e6417..5de3bd4 100644 --- a/lex/scf_lex_util.c +++ b/lex/scf_lex_util.c @@ -4,15 +4,15 @@ int _find_key_word(const char* text); static scf_key_word_t number_postfix[] = { - {"l", SCF_LEX_WORD_CONST_INT}, - {"ll", SCF_LEX_WORD_CONST_I64}, + {SCF_CSTR("l"), SCF_LEX_WORD_CONST_INT}, + {SCF_CSTR("ll"), SCF_LEX_WORD_CONST_I64}, - {"u", SCF_LEX_WORD_CONST_U32}, - {"ul", SCF_LEX_WORD_CONST_U32}, - {"ull", SCF_LEX_WORD_CONST_U64}, + {SCF_CSTR("u"), SCF_LEX_WORD_CONST_U32}, + {SCF_CSTR("ul"), SCF_LEX_WORD_CONST_U32}, + {SCF_CSTR("ull"), SCF_LEX_WORD_CONST_U64}, - {"f", SCF_LEX_WORD_CONST_FLOAT}, - {"lf", SCF_LEX_WORD_CONST_DOUBLE}, + {SCF_CSTR("f"), SCF_LEX_WORD_CONST_FLOAT}, + {SCF_CSTR("lf"), SCF_LEX_WORD_CONST_DOUBLE}, }; static int _lex_number_postfix(const char* postfix, int n) @@ -23,7 +23,7 @@ static int _lex_number_postfix(const char* postfix, int n) for (i = 0; i < sizeof(number_postfix) / sizeof(number_postfix[0]); i++) { key = &number_postfix[i]; - if (!strncmp(key->text, postfix, n)) + if (n == key->len && !memcmp(postfix, key->text, n)) return key->type; } diff --git a/lex/scf_macro.c b/lex/scf_macro.c index b8c1a71..dff36f5 100644 --- a/lex/scf_macro.c +++ b/lex/scf_macro.c @@ -1,6 +1,24 @@ #include"scf_lex.h" -static int __macro_drop_to_LF(scf_lex_t* lex) +scf_macro_t* __find_macro(scf_lex_t* lex, scf_lex_word_t* w) +{ + if (!lex->macros) + return NULL; + + scf_macro_t* m; + int i; + + for (i = lex->macros->size - 1; i >= 0; i--) { + m = lex->macros->data[i]; + + if (m->def_flag && !scf_string_cmp(m->w->text, w->text)) + return m; + } + + return NULL; +} + +int __macro_drop_to_LF(scf_lex_t* lex) { scf_lex_word_t* w = NULL; int type; @@ -14,12 +32,15 @@ static int __macro_drop_to_LF(scf_lex_t* lex) scf_lex_word_free(w); w = NULL; + if (SCF_LEX_WORD_EOF == type) + return -EINVAL; + } while (SCF_LEX_WORD_LF != type); return 0; } -static int __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t** pw2) +int __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t** pw2) { scf_lex_word_t* w1 = NULL; scf_lex_word_t* w2 = NULL; @@ -33,6 +54,11 @@ static int __macro_drop_to(scf_lex_t* lex, scf_lex_word_t** pw1, scf_lex_word_t* return ret; } + if (SCF_LEX_WORD_EOF == w1->type) { + scf_lex_word_free(w1); + return -EINVAL; + } + if (SCF_LEX_WORD_HASH != w1->type) { scf_lex_word_free(w1); w1 = NULL; @@ -75,7 +101,7 @@ end: return 0; } -static int __macro_pop_to(scf_lex_t* lex, scf_lex_word_t** h, scf_lex_word_t** pw1, scf_lex_word_t** pw2) +int __macro_pop_to(scf_lex_t* lex, scf_lex_word_t** h, scf_lex_word_t** pw1, scf_lex_word_t** pw2) { scf_lex_word_t* w1 = NULL; scf_lex_word_t* w2 = NULL; @@ -89,6 +115,11 @@ static int __macro_pop_to(scf_lex_t* lex, scf_lex_word_t** h, scf_lex_word_t** p return ret; } + if (SCF_LEX_WORD_EOF == w1->type) { + scf_lex_word_free(w1); + return -EINVAL; + } + if (SCF_LEX_WORD_HASH != w1->type) { w1->next = *h; *h = w1; @@ -278,15 +309,10 @@ int __parse_macro_define(scf_lex_t* lex, int def_flag) } if (lex->macros) { - int i; - for (i = lex->macros->size - 1; i >= 0; i--) { - m0 = lex->macros->data[i]; - - if (!scf_string_cmp(m->w->text, m0->w->text)) { - scf_logw("macro '%s' defined before in file: %s, line: %d\n", - m0->w->text->data, m0->w->file->data, m0->w->line); - break; - } + m0 = __find_macro(lex, m->w); + if (m0) { + scf_logw("macro '%s' defined before in file: %s, line: %d\n", + m0->w->text->data, m0->w->file->data, m0->w->line); } } else { lex->macros = scf_vector_alloc(); @@ -328,18 +354,8 @@ int __parse_macro_ifdef(scf_lex_t* lex, int def_flag) return ret; int found = 0; - int i; - - if (lex->macros) { - for (i = lex->macros->size - 1; i >= 0; i--) { - m = lex->macros->data[i]; - - if (m->def_flag && !scf_string_cmp(m->w->text, w->text)) { - found = 1; - break; - } - } - } + if (lex->macros && __find_macro(lex, w)) + found = 1; scf_logw("macro '%s', found: %d, def_flag: %d, file: %s, line: %d\n", w->text->data, found, def_flag, w->file->data, w->line); @@ -541,24 +557,6 @@ static int __convert_str(scf_lex_word_t* h) return 0; } -static scf_macro_t* __find_macro(scf_lex_t* lex, scf_lex_word_t* w) -{ - if (!lex->macros) - return NULL; - - scf_macro_t* m; - int i; - - for (i = lex->macros->size - 1; i >= 0; i--) { - m = lex->macros->data[i]; - - if (!scf_string_cmp(m->w->text, w->text)) - return m; - } - - return NULL; -} - static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use) { scf_lex_word_t** pp; diff --git a/lex/scf_macro_expr.c b/lex/scf_macro_expr.c new file mode 100644 index 0000000..cb1e217 --- /dev/null +++ b/lex/scf_macro_expr.c @@ -0,0 +1,612 @@ +#include"scf_lex.h" + +scf_macro_t* __find_macro(scf_lex_t* lex, scf_lex_word_t* w); + +typedef struct { + scf_lex_word_t** pp; + scf_lex_word_t* error; + + int n_lps; + int n_rps; +} scf_macro_ctx_t; + +typedef int (*scf_macro_operator_pt)(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand); +static int __macro_expr(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w, int n_consts, scf_lex_word_t** operand); + +static int macro_binary_priority[SCF_LEX_N_OPS] = +{ + [SCF_LEX_WORD_STAR ] = 1, + [SCF_LEX_WORD_DIV ] = 1, + [SCF_LEX_WORD_MOD ] = 1, + + [SCF_LEX_WORD_PLUS ] = 2, + [SCF_LEX_WORD_MINUS ] = 2, + + [SCF_LEX_WORD_SHL ] = 3, + [SCF_LEX_WORD_SHR ] = 3, + + [SCF_LEX_WORD_BIT_XOR ] = 4, + [SCF_LEX_WORD_BIT_AND ] = 4, + [SCF_LEX_WORD_BIT_OR ] = 4, + + [SCF_LEX_WORD_EQ ] = 5, + [SCF_LEX_WORD_NE ] = 5, + [SCF_LEX_WORD_GT ] = 5, + [SCF_LEX_WORD_LT ] = 5, + [SCF_LEX_WORD_GE ] = 5, + [SCF_LEX_WORD_LE ] = 5, + + [SCF_LEX_WORD_LOGIC_AND] = 6, + [SCF_LEX_WORD_LOGIC_OR ] = 6, + + [SCF_LEX_WORD_Q_MASK ] = 7, + [SCF_LEX_WORD_COLON ] = 8, +}; + +static int __macro_unary_operand(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t** operand) +{ + assert(!*operand); + + scf_lex_word_t* w0 = NULL; + + int ret = __lex_pop_word(lex, &w0); + if (ret < 0) + return ret; + + switch (w0->type) + { + case SCF_LEX_WORD_PLUS: + case SCF_LEX_WORD_MINUS: + case SCF_LEX_WORD_LOGIC_NOT: + case SCF_LEX_WORD_BIT_NOT: + case SCF_LEX_WORD_KEY_DEFINED: + case SCF_LEX_WORD_LP: + ret = __macro_expr(lex, ctx, w0, 1, operand); + if (ret < 0) + return ret; + break; + + case SCF_LEX_WORD_ID: + ret = __lex_use_macro(lex, &w0); + if (ret < 0) + return ret; + + default: + scf_logw("w0: %s, w0->data.u64: %ld\n", w0->text->data, w0->data.u64); + + *operand = w0; + + w0->next = NULL; + + *ctx->pp = w0; + ctx->pp = &w0->next; + break; + }; + + return 0; +} + +static int __macro_binary_operand(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* op, scf_lex_word_t** operand2) +{ + assert(!*operand2); + + scf_lex_word_t* op2 = NULL; + + int ret = __macro_unary_operand(lex, ctx, operand2); + if (ret < 0) + return ret; + + ret = __lex_pop_word(lex, &op2); + if (ret < 0) + return ret; + + if (SCF_LEX_WORD_RP == op2->type) { + op2->next = NULL; + + *ctx->pp = op2; + ctx->pp = &op2->next; + return 0; + } + + if (op2->type < SCF_LEX_N_OPS) { + int cur = macro_binary_priority[op ->type]; + int next = macro_binary_priority[op2->type]; + + if (next > 0 && next < cur) + return __macro_expr(lex, ctx, op2, 2, operand2); + } + + scf_lex_push_word(lex, op2); + return 0; +} + +#define MACRO_OPERATOR_BINARY(name, op) \ +static int __macro_binary_##name(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) \ +{ \ + assert(2 == n_consts); \ + assert(*operand); \ + \ + scf_lex_word_t* w0 = *operand; \ + scf_lex_word_t* w1 = NULL; \ + \ + int ret = __macro_binary_operand(lex, ctx, w_op, &w1); \ + if (ret < 0) \ + return ret; \ + \ + if (!scf_lex_is_const(w0)) { \ + scf_loge("\n"); \ + return -EINVAL; \ + } \ + \ + if (!scf_lex_is_const(w1)) { \ + scf_loge("\n"); \ + return -EINVAL; \ + } \ + \ + w0->data.i64 = w0->data.i64 op w1->data.i64; \ + scf_logi("op: %s, result: %ld, line: %d, pos: %d\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \ + \ + *operand = w0; \ + return 0; \ +} + +MACRO_OPERATOR_BINARY(mul, *) +MACRO_OPERATOR_BINARY(div, /) +MACRO_OPERATOR_BINARY(mod, %) + +MACRO_OPERATOR_BINARY(plus, +) +MACRO_OPERATOR_BINARY(minus, -) + +MACRO_OPERATOR_BINARY(shl, <<) +MACRO_OPERATOR_BINARY(shr, >>) + +MACRO_OPERATOR_BINARY(bit_xor, ^) +MACRO_OPERATOR_BINARY(bit_and, &) +MACRO_OPERATOR_BINARY(bit_or, |) + +MACRO_OPERATOR_BINARY(eq, ==) +MACRO_OPERATOR_BINARY(ne, !=) +MACRO_OPERATOR_BINARY(gt, >) +MACRO_OPERATOR_BINARY(lt, <) +MACRO_OPERATOR_BINARY(ge, >=) +MACRO_OPERATOR_BINARY(le, <=) + +MACRO_OPERATOR_BINARY(logic_and, &&) +MACRO_OPERATOR_BINARY(logic_or, ||) + +static int __macro_operator_defined(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) +{ + scf_lex_word_t* w0 = NULL; + + int ret = __lex_pop_word(lex, &w0); + if (ret < 0) + return ret; + + if (SCF_LEX_WORD_ID != w0->type) { + scf_loge("'%s' after 'defined' in #if is NOT an macro identity, file: %s, line: %d\n", + w0->text->data, w0->file->data, w0->line); + + ret = -EINVAL; + goto error; + } + + if (__find_macro(lex, w0)) + w0->data.i64 = 1; + else + w0->data.i64 = 0; + + w0->type = SCF_LEX_WORD_CONST_I64; + *operand = w0; + + scf_logi("w0: %s, result: %ld\n", w0->text->data, w0->data.i64); + + ret = 0; + +error: + w0->next = NULL; + *ctx->pp = w0; + ctx->pp = &w0->next; + return ret; +} + +#define MACRO_OPERATOR_UNARY(name, op) \ +static int __macro_unary_##name(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) \ +{ \ + assert(1 == n_consts); \ + assert(!*operand); \ + \ + int ret = __macro_unary_operand(lex, ctx, operand); \ + if (ret < 0) \ + return ret; \ + \ + if (!*operand) { \ + scf_loge("unary operand NOT found for '%s', file: %s, line: %d\n", \ + w_op->text->data, w_op->file->data, w_op->line); \ + return -EINVAL; \ + } \ + \ + scf_lex_word_t* w0 = *operand; \ + \ + if (!scf_lex_is_const(w0)) { \ + scf_loge("\n"); \ + 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); \ + return 0; \ +} + +MACRO_OPERATOR_UNARY(logic_not, !) +MACRO_OPERATOR_UNARY(bit_not, ~) + +MACRO_OPERATOR_UNARY(plus, +) +MACRO_OPERATOR_UNARY(minus, -) + +static int __macro_operator_plus(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) +{ + if (1 == n_consts) + return __macro_unary_plus(lex, ctx, w_op, n_consts, operand); + + else if (2 == n_consts) + return __macro_binary_plus(lex, ctx, w_op, n_consts, operand); + + scf_loge("\n"); + return -EINVAL; +} + +static int __macro_operator_minus(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) +{ + if (1 == n_consts) + return __macro_unary_minus(lex, ctx, w_op, n_consts, operand); + + else if (2 == n_consts) + return __macro_binary_minus(lex, ctx, w_op, n_consts, operand); + + scf_loge("\n"); + return -EINVAL; +} + +static int __macro_operator_cond(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) +{ + if (!*operand) { + scf_loge("NO 'cond expr' before '?', file: %s, line: %d\n", w_op->file->data, w_op->line); + return -EINVAL; + } + + scf_lex_word_t* cond = *operand; + scf_lex_word_t* _true = NULL; + scf_lex_word_t* _false = NULL; + scf_lex_word_t* op2 = NULL; + + int ret = __macro_unary_operand(lex, ctx, &_true); + if (ret < 0) + return ret; + + ret = __lex_pop_word(lex, &op2); + if (ret < 0) + return ret; + + if (op2->type < SCF_LEX_N_OPS) { + int cur = macro_binary_priority[w_op->type]; + int next = macro_binary_priority[op2->type]; + + if (next > 0 && next < cur) { + ret = __macro_expr(lex, ctx, op2, 2, &_true); + if (ret < 0) + return ret; + + ret = __lex_pop_word(lex, &op2); + if (ret < 0) + return ret; + } + } + + op2->next = NULL; + *ctx->pp = op2; + ctx->pp = &op2->next; + + switch (op2->type) + { + case SCF_LEX_WORD_Q_MASK: + + ret = __macro_operator_cond(lex, ctx, op2, 2, &_true); + if (ret < 0) + return ret; + break; + + case SCF_LEX_WORD_COLON: + break; + default: + scf_loge("'%s' is NOT ':' after '?', file: %s, line: %d, pos: %d\n", + op2->text->data, op2->file->data, op2->line, op2->pos); + return -EINVAL; + break; + }; + + ret = __macro_unary_operand(lex, ctx, &_false); + if (ret < 0) + return ret; + + if (cond->data.u64) + *operand = _true; + else + *operand = _false; + + scf_logi("op: %s, flag: %d, result: %ld, line: %d, pos: %d\n", + w_op->text->data, !!cond->data.u64, (*operand)->data.i64, w_op->line, w_op->pos); + return 0; +} + +static int __macro_operator_lp(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand); + +static int __macro_operator_rp(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) +{ + return 0; +} + +static scf_macro_operator_pt macro_operators[] = +{ + [SCF_LEX_WORD_LP ] = __macro_operator_lp, + [SCF_LEX_WORD_RP ] = __macro_operator_rp, + + [SCF_LEX_WORD_LOGIC_NOT ] = __macro_unary_logic_not, + [SCF_LEX_WORD_BIT_NOT ] = __macro_unary_bit_not, + [SCF_LEX_WORD_KEY_DEFINED] = __macro_operator_defined, + + [SCF_LEX_WORD_STAR ] = __macro_binary_mul, + [SCF_LEX_WORD_DIV ] = __macro_binary_div, + [SCF_LEX_WORD_MOD ] = __macro_binary_mod, + + [SCF_LEX_WORD_PLUS ] = __macro_operator_plus, + [SCF_LEX_WORD_MINUS ] = __macro_operator_minus, + + [SCF_LEX_WORD_SHL ] = __macro_binary_shl, + [SCF_LEX_WORD_SHR ] = __macro_binary_shr, + + [SCF_LEX_WORD_BIT_XOR ] = __macro_binary_bit_xor, + [SCF_LEX_WORD_BIT_AND ] = __macro_binary_bit_and, + [SCF_LEX_WORD_BIT_OR ] = __macro_binary_bit_or, + + [SCF_LEX_WORD_GT ] = __macro_binary_gt, + [SCF_LEX_WORD_LT ] = __macro_binary_lt, + [SCF_LEX_WORD_GE ] = __macro_binary_ge, + [SCF_LEX_WORD_LE ] = __macro_binary_le, + [SCF_LEX_WORD_EQ ] = __macro_binary_eq, + [SCF_LEX_WORD_NE ] = __macro_binary_ne, + + [SCF_LEX_WORD_LOGIC_AND ] = __macro_binary_logic_and, + [SCF_LEX_WORD_LOGIC_OR ] = __macro_binary_logic_or, + + [SCF_LEX_WORD_Q_MASK ] = __macro_operator_cond, +}; + +static int __macro_operator_lp(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w_op, int n_consts, scf_lex_word_t** operand) +{ + assert(!*operand); + + int ret = __macro_unary_operand(lex, ctx, operand); + if (ret < 0) + return ret; + + if (!*operand) { + scf_loge("unary operand NOT found for '%s', file: %s, line: %d\n", + w_op->text->data, w_op->file->data, w_op->line); + return -EINVAL; + } + + scf_lex_word_t* w0 = *operand; + scf_lex_word_t* op2 = NULL; + + if (!scf_lex_is_const(w0)) { + scf_loge("\n"); + return -EINVAL; + } + + ret = __lex_pop_word(lex, &op2); + if (ret < 0) + return ret; + + op2->next = NULL; + *ctx->pp = op2; + ctx->pp = &op2->next; + + scf_macro_operator_pt f; + + switch (op2->type) + { + case SCF_LEX_WORD_RP: + break; + + case SCF_LEX_WORD_STAR: + case SCF_LEX_WORD_DIV: + case SCF_LEX_WORD_MOD: + case SCF_LEX_WORD_PLUS: + case SCF_LEX_WORD_MINUS: + + case SCF_LEX_WORD_SHL: + case SCF_LEX_WORD_SHR: + case SCF_LEX_WORD_BIT_XOR: + case SCF_LEX_WORD_BIT_AND: + case SCF_LEX_WORD_BIT_OR: + + case SCF_LEX_WORD_EQ: + case SCF_LEX_WORD_NE: + case SCF_LEX_WORD_GT: + case SCF_LEX_WORD_LT: + case SCF_LEX_WORD_GE: + case SCF_LEX_WORD_LE: + + case SCF_LEX_WORD_LOGIC_AND: + case SCF_LEX_WORD_LOGIC_OR: + f = macro_operators[op2->type]; + if (!f) { + scf_loge("operator '%s' NOT supported in macro expr, file: %s, line: %d\n", + op2->text->data, op2->file->data, op2->line); + return -EINVAL; + } + + return f(lex, ctx, op2, 2, operand); + break; + + default: + scf_loge("\n"); + return -EINVAL; + break; + }; + + return 0; +} + +static int __macro_expr(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_word_t* w, int n_consts, scf_lex_word_t** operand) +{ + int ret; + + if (SCF_LEX_WORD_EOF == w->type) { + scf_loge("\n"); + + scf_lex_word_free(w); + return -EINVAL; + } + + if (SCF_LEX_WORD_LF == w->type) { + scf_loge("\n"); + + scf_lex_push_word(lex, w); + return -EINVAL; + } + + if (scf_lex_is_operator(w)) { + + w->next = NULL; + *ctx->pp = w; + ctx->pp = &w->next; + + scf_macro_operator_pt f = macro_operators[w->type]; + if (!f) { + scf_loge("operator '%s' NOT supported in macro expr, file: %s, line: %d\n", + w->text->data, w->file->data, w->line); + return -EINVAL; + } + + return f(lex, ctx, w, n_consts, operand); + } + + if (SCF_LEX_WORD_ID == w->type) { + + ret = __lex_use_macro(lex, &w); + if (ret < 0) + return ret; + } + + *operand = w; + + w->next = NULL; + *ctx->pp = w; + ctx->pp = &w->next; + return 0; +} + +int __macro_if_expr(scf_lex_t* lex) +{ + scf_lex_word_t* operand = NULL; + scf_lex_word_t* w = NULL; + scf_lex_word_t* h = NULL; + scf_macro_ctx_t ctx = {&h, 0, 0}; + + int ret = 0; + + while (1) { + ret = __lex_pop_word(lex, &w); + if (ret < 0) + goto error; + + if (SCF_LEX_WORD_LF == w->type) { + scf_lex_push_word(lex, w); + w = NULL; + break; + } + + if (SCF_LEX_WORD_EOF == w->type) { + scf_loge("un-wanted '%s' in macro expr, file: %s, line: %d\n", + w->text->data, w->file->data, w->line); + + ret = -EINVAL; + goto error; + } + + if (scf_lex_is_operator(w)) { + scf_macro_operator_pt f = macro_operators[w->type]; + if (!f) { + scf_loge("operator '%s' NOT supported in macro expr, file: %s, line: %d\n", + w->text->data, w->file->data, w->line); + + ret = -EINVAL; + goto error; + } + + w->next = NULL; + *ctx.pp = w; + ctx.pp = &w->next; + + if (operand) + ret = f(lex, &ctx, w, 2, &operand); + else + ret = f(lex, &ctx, w, 1, &operand); + + w = NULL; + if (ret < 0) + goto error; + continue; + } + + if (SCF_LEX_WORD_ID == w->type) { + + ret = __lex_use_macro(lex, &w); + if (ret < 0) + goto error; + } + + if (!scf_lex_is_const(w)) { + scf_loge("operand '%s' is NOT CONST in macro expr, file: %s, line: %d\n", + w->text->data, w->file->data, w->line); + + ret = -EINVAL; + goto error; + } + + scf_logi("w: %s, w->data.u64: %ld\n", w->text->data, w->data.u64); + + operand = w; + + w->next = NULL; + *ctx.pp = w; + ctx.pp = &w->next; + w = NULL; + } + + if (operand) + ret = !!operand->data.u64; + else + ret = 0; + +error: + if (w) { + w->next = NULL; + *ctx.pp = w; + w = NULL; + } + + while (h) { + 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_lex_word_free(w); + w = NULL; + } + + scf_logi("final flag: %d\n", ret); + return ret; +} diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 89147f9..c66cd26 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -458,13 +458,13 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -EINVAL; } - scf_x64_context_t* x64 = ctx->priv; - scf_function_t* f = x64->f; - scf_3ac_operand_t* src0 = c->srcs->data[0]; - scf_variable_t* var_pf = src0->dag_node->var; - scf_function_t* pf = var_pf->func_ptr; + scf_x64_context_t* x64 = ctx->priv; + scf_function_t* f = x64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_dag_node_t* dn = src->dag_node; + scf_function_t* pf = dn->var->func_ptr; - if (SCF_FUNCTION_PTR != var_pf->type || !pf) { + if (SCF_FUNCTION_PTR != dn->var->type || !pf) { scf_loge("\n"); return -EINVAL; } @@ -486,26 +486,17 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_instruction_t* inst; scf_instruction_t* inst_rsp = NULL; - int data_rela_size = f->data_relas->size; - int text_rela_size = f->text_relas->size; - scf_logd("f->data_relas->size: %d, f->text_relas->size: %d\n", f->data_relas->size, f->text_relas->size); - int ret; - int i; if (pf->rets) { ret = _x64_call_save_ret_regs(c, f, pf); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } } ret = x64_overflow_reg(rax, c, f); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } x64_call_rabi(NULL, NULL, c); @@ -517,10 +508,9 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) } ret = _x64_inst_call_argv(c, f); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } + uint32_t imm = ret > 0; mov = x64_find_OpCode(SCF_X64_MOV, 4,4, SCF_X64_I2G); @@ -543,8 +533,8 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) memcpy(inst_rsp->code + inst_rsp->len - 4, &size, 4); } - if (var_pf->const_literal_flag) { - assert(0 == src0->dag_node->color); + if (dn->var->const_literal_flag) { + assert(0 == dn->color); int32_t offset = 0; call = x64_find_OpCode(SCF_X64_CALL, 4,4, SCF_X64_I); @@ -560,33 +550,27 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) rela->inst_offset = 1; X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, pf); } else { - assert(0 != src0->dag_node->color); - - call = x64_find_OpCode(SCF_X64_CALL, 8,8, SCF_X64_E); + assert(0 != dn->color); - if (src0->dag_node->color > 0) { + scf_register_t* r_pf = NULL; + scf_rela_t* rela = NULL; - scf_register_t* r_pf = NULL; + call = x64_find_OpCode(SCF_X64_CALL, 8,8, SCF_X64_E); - ret = x64_select_reg(&r_pf, src0->dag_node, c, f, 1); - if (ret < 0) { - scf_loge("\n"); + if (dn->color > 0) { + ret = x64_select_reg(&r_pf, dn, c, f, 1); + if (ret < 0) return ret; - } inst = x64_make_inst_E(call, r_pf); X64_INST_ADD_CHECK(c, inst, NULL); - - inst->OpCode = (scf_OpCode_t*)call; } else { - scf_rela_t* rela = NULL; - - inst = x64_make_inst_M(&rela, call, var_pf, NULL); + inst = x64_make_inst_M(&rela, call, dn->var, NULL); X64_INST_ADD_CHECK(c, inst, rela); - X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, pf); - - inst->OpCode = (scf_OpCode_t*)call; + X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL); } + + inst->OpCode = (scf_OpCode_t*)call; } if (stack_size > 0) { @@ -603,18 +587,14 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (pf->rets && pf->rets->size > 0 && c->dsts) { nb_updated = _x64_call_update_dsts(c, f, updated_regs, X64_ABI_RET_NB * 2); - if (nb_updated < 0) { - scf_loge("\n"); + if (nb_updated < 0) return nb_updated; - } } if (save_size > 0) { ret = x64_pop_regs(c, saved_regs, save_size >> 3, updated_regs, nb_updated); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; - } } f->call_flag = 1; diff --git a/parse/Makefile b/parse/Makefile index 4f6e832..5374945 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -3,6 +3,7 @@ CFILES += ../util/scf_graph.c CFILES += ../lex/scf_lex.c CFILES += ../lex/scf_lex_util.c CFILES += ../lex/scf_macro.c +CFILES += ../lex/scf_macro_expr.c CFILES += scf_parse_util.c CFILES += scf_parse.c diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 14f4394..40b293d 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -8,6 +8,9 @@ typedef struct { scf_block_t* parent_block; + int pf_pointers; + int pf_lps; + int pf_rps; } dfa_fun_data_t; int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) @@ -17,31 +20,81 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) return SCF_DFA_ERROR; } - scf_parse_t* parse = dfa->priv; - scf_ast_t* ast = parse->ast; - dfa_identity_t* id = scf_stack_pop(d->current_identities); - dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; + scf_parse_t* parse = dfa->priv; + scf_ast_t* ast = parse->ast; + dfa_identity_t* id = scf_stack_pop(d->current_identities); + dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; - scf_function_t* f; - scf_variable_t* v; - scf_block_t* b; + scf_variable_t* v_pf = NULL; + scf_function_t* f; + scf_variable_t* v; + scf_block_t* b; + scf_type_t* t; if (!id || !id->identity) { scf_loge("function identity not found\n"); return SCF_DFA_ERROR; } + uint32_t local_flag = 0; + uint32_t global_flag = 0; + uint32_t member_flag = 0; + b = ast->current_block; while (b) { - if (b->node.type >= SCF_STRUCT) + if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type) break; b = (scf_block_t*)b->node.parent; } + if (!b) { + local_flag = 0; + global_flag = 1; + member_flag = 0; + + } else if (SCF_FUNCTION == b->node.type) { + local_flag = 1; + global_flag = 0; + member_flag = 0; + + } else if (b->node.type >= SCF_STRUCT) { + local_flag = 0; + global_flag = 0; + member_flag = 1; + } + + assert(global_flag || local_flag || member_flag); + + if (fd->pf_pointers > 0) { + t = NULL; + + int pf_pointers = fd->pf_pointers; + + fd->pf_pointers = 0; + + int ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR); + if (ret < 0) + return ret; + + v_pf = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, 0, pf_pointers, NULL); + if (!v_pf) + return -ENOMEM; + + scf_scope_push_var(ast->current_block->scope, v_pf); + + ret = scf_string_cat_cstr(id->identity->text, "_pt"); + if (ret < 0) + return ret; + + v_pf->local_flag = local_flag; + v_pf->global_flag = global_flag; + v_pf->member_flag = member_flag; + } + f = scf_function_alloc(id->identity); if (!f) return SCF_DFA_ERROR; - f->member_flag = !!b; + f->member_flag = member_flag; free(id); id = NULL; @@ -109,9 +162,28 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) SCF_XCHG(f->rets->data[i], f->rets->data[j]); } - scf_scope_push_function(ast->current_block->scope, f); + if (!f->member_flag || v_pf) { + + b = ast->current_block; + while (b) { + if (b->node.file_flag) + break; + b = (scf_block_t*)b->node.parent; + } + + scf_scope_push_function(b->scope, f); + + scf_node_add_child((scf_node_t*)b, (scf_node_t*)f); - scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)f); + if (v_pf) { + v_pf->static_flag = f->static_flag; + v_pf->func_ptr = f; + } + } else { + scf_scope_push_function(ast->current_block->scope, f); + + scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)f); + } fd ->parent_block = ast->current_block; ast->current_block = (scf_block_t*)f; @@ -223,6 +295,49 @@ static int _function_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* dat return SCF_DFA_NEXT_WORD; } +static int _function_action_pf_star(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_data_t* d = data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; + + fd->pf_pointers++; + + return SCF_DFA_NEXT_WORD; +} + +static int _function_action_pf_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_data_t* d = data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; + + fd->pf_lps++; + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE); + + return SCF_DFA_NEXT_WORD; +} + +static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_data_t* d = data; + dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index]; + dfa_identity_t* id = scf_stack_top(d->current_identities); + + fd->pf_rps++; + + if (fd->pf_rps == fd->pf_lps) { + fd->pf_rps = 0; + fd->pf_lps = 0; + + if (id && id->identity) + scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, fd->pf_pointers); + } else { + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE); + } + + return SCF_DFA_NEXT_WORD; +} + static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -390,12 +505,16 @@ static int _function_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _dfa_init_module_function(scf_dfa_t* dfa) { - SCF_DFA_MODULE_NODE(dfa, function, comma, scf_dfa_is_comma, _function_action_comma); - SCF_DFA_MODULE_NODE(dfa, function, vargs, scf_dfa_is_vargs, _function_action_vargs); - SCF_DFA_MODULE_NODE(dfa, function, end, scf_dfa_is_entry, _function_action_end); + SCF_DFA_MODULE_NODE(dfa, function, comma, scf_dfa_is_comma, _function_action_comma); + SCF_DFA_MODULE_NODE(dfa, function, vargs, scf_dfa_is_vargs, _function_action_vargs); + SCF_DFA_MODULE_NODE(dfa, function, end, scf_dfa_is_entry, _function_action_end); + + SCF_DFA_MODULE_NODE(dfa, function, lp, scf_dfa_is_lp, _function_action_lp); + SCF_DFA_MODULE_NODE(dfa, function, rp, scf_dfa_is_rp, _function_action_rp); - SCF_DFA_MODULE_NODE(dfa, function, lp, scf_dfa_is_lp, _function_action_lp); - SCF_DFA_MODULE_NODE(dfa, function, rp, scf_dfa_is_rp, _function_action_rp); + SCF_DFA_MODULE_NODE(dfa, function, pf_star, scf_dfa_is_star, _function_action_pf_star); + SCF_DFA_MODULE_NODE(dfa, function, pf_lp, scf_dfa_is_lp, _function_action_pf_lp); + SCF_DFA_MODULE_NODE(dfa, function, pf_rp, scf_dfa_is_rp, _function_action_pf_rp); scf_parse_t* parse = dfa->priv; dfa_data_t* d = parse->dfa_data; @@ -437,6 +556,10 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, function, lp, lp); SCF_DFA_GET_MODULE_NODE(dfa, function, rp, rp); + SCF_DFA_GET_MODULE_NODE(dfa, function, pf_star, pf_star); + SCF_DFA_GET_MODULE_NODE(dfa, function, pf_lp, pf_lp); + SCF_DFA_GET_MODULE_NODE(dfa, function, pf_rp, pf_rp); + SCF_DFA_GET_MODULE_NODE(dfa, type, _const, _const); SCF_DFA_GET_MODULE_NODE(dfa, type, base_type, base_type); SCF_DFA_GET_MODULE_NODE(dfa, identity, identity, type_name); @@ -445,6 +568,21 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, type, identity, identity); SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block); + // function pointer + scf_dfa_node_add_child(base_type, pf_lp); + scf_dfa_node_add_child(type_name, pf_lp); + scf_dfa_node_add_child(star, pf_lp); + + scf_dfa_node_add_child(pf_lp, pf_star); + scf_dfa_node_add_child(pf_star, identity); + scf_dfa_node_add_child(identity, pf_rp); + + scf_dfa_node_add_child(pf_star, pf_star); + scf_dfa_node_add_child(pf_lp, pf_lp); + scf_dfa_node_add_child(pf_rp, pf_rp); + + scf_dfa_node_add_child(pf_rp, lp); + // function start scf_dfa_node_add_child(identity, lp); diff --git a/parse/scf_dfa_macro.c b/parse/scf_dfa_macro.c index 66ba0ea..61e5cd2 100644 --- a/parse/scf_dfa_macro.c +++ b/parse/scf_dfa_macro.c @@ -4,182 +4,124 @@ extern scf_dfa_module_t dfa_module_macro; -static inline int _macro_action_if(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_lex_word_t* w = words->data[words->size - 1]; - scf_lex_word_t* w1 = dfa->ops->pop_word(dfa); - scf_lex_word_t* w2; - scf_lex_word_t* w3; - - if (!w1) - return SCF_DFA_ERROR; - if (!scf_lex_is_const_integer(w1)) { - scf_loge("the condition after '#if' must be a const integer, file: %s, line: %d\n", w->file->data, w->line); - return SCF_DFA_ERROR; +static int __macro_do_if_else(scf_lex_t* lex, scf_lex_word_t* w, int flag) +{ + scf_lex_word_t* h = NULL; + scf_lex_word_t* w1 = NULL; + scf_lex_word_t* w2 = NULL; + + int ret = __macro_drop_to_LF(lex); + if (ret < 0) { + scf_loge("'#endif' NOT found for '#%s' in file: %s, line: %d\n", w->text->data, w->file->data, w->line); + return ret; } - int flag = w1->data.u32; - - scf_lex_word_free(w1); - w1 = NULL; - - while (1) { - w1 = dfa->ops->pop_word(dfa); - if (!w1) - return SCF_DFA_ERROR; - - int type = w1->type; + if (!flag) { + ret = __macro_drop_to(lex, &w1, &w2); + if (ret < 0) + return ret; - scf_lex_word_free(w1); - w1 = NULL; + if (SCF_LEX_WORD_KEY_ENDIF == w2->type) { + scf_lex_word_free(w2); + scf_lex_word_free(w1); - if (SCF_LEX_WORD_EOF == type) { - scf_loge("'#endif' NOT found for '#if' in file: %s, line: %d\n", w->file->data, w->line); - return SCF_DFA_ERROR; + return __macro_drop_to_LF(lex); } - if (SCF_LEX_WORD_LF == type) - break; + scf_lex_push_word(lex, w2); + scf_lex_push_word(lex, w1); + return SCF_DFA_OK; } - scf_lex_word_t* h = NULL; + ret = __macro_pop_to(lex, &h, &w1, &w2); + if (ret < 0) { + scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free); + return ret; + } - int n_if = 1; + int type = w2->type; - while (1) { - w1 = dfa->ops->pop_word(dfa); - if (!w1) - goto error; - w1->next = NULL; + scf_lex_word_free(w2); + scf_lex_word_free(w1); + w1 = NULL; + w2 = NULL; - if (SCF_LEX_WORD_EOF == w1->type) { - scf_loge("'#endif' NOT found for '#if' in file: %s, line: %d\n", w->file->data, w->line); - scf_lex_word_free(w1); - goto error; - } + while (SCF_LEX_WORD_KEY_ENDIF != type) { - if (SCF_LEX_WORD_HASH == w1->type) { - w2 = dfa->ops->pop_word(dfa); - if (!w2) { - scf_lex_word_free(w1); - goto error; - } - w2->next = NULL; - - scf_logd("'#%s' file: %s, line: %d\n", w2->text->data, w2->file->data, w2->line); - - if (SCF_LEX_WORD_EOF == w2->type) { - scf_loge("'#endif' NOT found for '#if' in file: %s, line: %d\n", w->file->data, w->line); - scf_lex_word_free(w2); - scf_lex_word_free(w1); - goto error; - } - - if (n_if < 1) { - scf_loge("extra '#%s' without an '#if' in file: %s, line: %d\n", w2->text->data, w2->file->data, w2->line); - scf_lex_word_free(w2); - scf_lex_word_free(w1); - goto error; - } - - if (SCF_LEX_WORD_KEY_ELSE == w2->type || SCF_LEX_WORD_KEY_ENDIF == w2->type) { - w3 = dfa->ops->pop_word(dfa); - if (!w3) { - scf_lex_word_free(w2); - scf_lex_word_free(w1); - goto error; - } - w3->next = NULL; - - if (SCF_LEX_WORD_LF != w3->type) { - scf_loge("'\\n' NOT found after '#%s' in file: %s, line: %d\n", w2->text->data, w2->file->data, w2->line); - scf_lex_word_free(w3); - scf_lex_word_free(w2); - scf_lex_word_free(w1); - goto error; - } - - if (SCF_LEX_WORD_KEY_ELSE == w2->type) { - if (1 == n_if) { - flag = !flag; - scf_lex_word_free(w3); - scf_lex_word_free(w2); - scf_lex_word_free(w1); - continue; - } - } else { - if (0 == --n_if) { - scf_lex_word_free(w3); - scf_lex_word_free(w2); - scf_lex_word_free(w1); - break; - } - } - - if (flag) - w2->next = w3; - else - scf_lex_word_free(w3); - w3 = NULL; - - } else if (SCF_LEX_WORD_KEY_IF == w2->type) { - n_if++; - } - - if (flag) - w1->next = w2; - else - scf_lex_word_free(w2); - w2 = NULL; + ret = __macro_drop_to(lex, &w1, &w2); + if (ret < 0) { + scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free); + return ret; } - if (flag) { - while (w1) { - w2 = w1->next; - w1->next = h; - h = w1; - w1 = w2; - } - } else - scf_lex_word_free(w1); + type = w2->type; + + scf_lex_word_free(w2); + scf_lex_word_free(w1); w1 = NULL; + w2 = NULL; + } + + ret = __macro_drop_to_LF(lex); + if (ret < 0) { + scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free); + return ret; } while (h) { - w = h; - scf_logd("'%s' file: %s, line: %d\n", w->text->data, w->file->data, w->line); - h = w->next; - dfa->ops->push_word(dfa, w); + w1 = h; + h = h->next; + + scf_lex_push_word(lex, w1); } return SCF_DFA_OK; +} -error: - while (h) { - w = h; - h = w->next; - scf_lex_word_free(w); - } - return SCF_DFA_ERROR; +static int _macro_action_if(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]; + + int flag = __macro_if_expr(parse->lex); + if (flag < 0) + return flag; + + return __macro_do_if_else(parse->lex, w, flag); +} + +static int _macro_action_else(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + scf_lex_word_t* w = words->data[words->size - 1]; + + return __macro_do_if_else(parse->lex, w, 1); } static int _dfa_init_module_macro(scf_dfa_t* dfa) { - SCF_DFA_MODULE_NODE(dfa, macro, hash, scf_dfa_is_hash, scf_dfa_action_next); - SCF_DFA_MODULE_NODE(dfa, macro, _if, scf_dfa_is_if, _macro_action_if); + SCF_DFA_MODULE_NODE(dfa, macro, hash, scf_dfa_is_hash, scf_dfa_action_next); + SCF_DFA_MODULE_NODE(dfa, macro, _if, scf_dfa_is_if, _macro_action_if); + SCF_DFA_MODULE_NODE(dfa, macro, _elif, scf_dfa_is_elif, _macro_action_if); + SCF_DFA_MODULE_NODE(dfa, macro, _else, scf_dfa_is_else, _macro_action_else); return SCF_DFA_OK; } static int _dfa_init_syntax_macro(scf_dfa_t* dfa) { - SCF_DFA_GET_MODULE_NODE(dfa, macro, hash, hash); - SCF_DFA_GET_MODULE_NODE(dfa, macro, _if, _if); + SCF_DFA_GET_MODULE_NODE(dfa, macro, hash, hash); + SCF_DFA_GET_MODULE_NODE(dfa, macro, _if, _if); + SCF_DFA_GET_MODULE_NODE(dfa, macro, _elif, _elif); + SCF_DFA_GET_MODULE_NODE(dfa, macro, _else, _else); scf_vector_add(dfa->syntaxes, hash); scf_dfa_node_add_child(hash, _if); + scf_dfa_node_add_child(hash, _elif); + scf_dfa_node_add_child(hash, _else); return 0; } diff --git a/parse/scf_dfa_util.h b/parse/scf_dfa_util.h index d007d15..ece4260 100644 --- a/parse/scf_dfa_util.h +++ b/parse/scf_dfa_util.h @@ -256,6 +256,13 @@ static inline int scf_dfa_is_if(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_KEY_IF == w->type; } +static inline int scf_dfa_is_elif(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_ELIF == w->type; +} + static inline int scf_dfa_is_else(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; diff --git a/parse/scf_operator_handler_expr.c b/parse/scf_operator_handler_expr.c index 62faa07..2976c51 100644 --- a/parse/scf_operator_handler_expr.c +++ b/parse/scf_operator_handler_expr.c @@ -706,24 +706,32 @@ scf_operator_handler_pt scf_find_expr_operator_handler(const int type) int scf_expr_calculate(scf_ast_t* ast, scf_expr_t* e, scf_variable_t** pret) { - if (!e || !e->nodes || e->nb_nodes <= 0) - return -1; - - if (scf_expr_semantic_analysis(ast, e) < 0) - return -1; + if (!e) + return -EINVAL; - scf_handler_data_t d = {0}; - scf_variable_t* v; + scf_handler_data_t d = {0}; + scf_variable_t* v; + scf_node_t* node = e; - if (!scf_type_is_var(e->nodes[0]->type)) { + if (SCF_OP_EXPR == e->type) { - if (_scf_expr_calculate_internal(ast, e->nodes[0], &d) < 0) { + if (!e->nodes || e->nb_nodes != 1) { scf_loge("\n"); - return -1; + return -EINVAL; } + + node = e->nodes[0]; } - v = _scf_operand_get(e->nodes[0]); + int ret = scf_expr_semantic_analysis(ast, node); + if (ret < 0) + return ret; + + ret = _scf_expr_calculate_internal(ast, node, &d); + if (ret < 0) + return ret; + + v = _scf_operand_get(node); if (pret) *pret = scf_variable_ref(v); diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 6ba2ae3..7769eb9 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -3177,17 +3177,22 @@ int scf_expr_semantic_analysis(scf_ast_t* ast, scf_expr_t* e) { scf_handler_data_t d = {0}; - if (!e->nodes || e->nb_nodes != 1) { - scf_loge("\n"); - return -1; - } + scf_node_t* node = e; - int ret = _scf_expr_calculate_internal(ast, e->nodes[0], &d); - if (ret < 0) { - scf_loge("\n"); - return -1; + if (SCF_OP_EXPR == e->type) { + + if (!e->nodes || e->nb_nodes != 1) { + scf_loge("\n"); + return -EINVAL; + } + + node = e->nodes[0]; } + int ret = _scf_expr_calculate_internal(ast, node, &d); + if (ret < 0) + return ret; + return 0; } diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 76d5120..00b910f 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -1797,7 +1797,7 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions) } assert(scf_list_empty(&h)); -// scf_basic_block_print_list(&f->basic_block_list_head); + scf_basic_block_print_list(&f->basic_block_list_head); } int ret = scf_optimize(parse->ast, functions); diff --git a/util/scf_string.c b/util/scf_string.c index a1afd01..bd33b0f 100644 --- a/util/scf_string.c +++ b/util/scf_string.c @@ -1,6 +1,6 @@ #include"scf_string.h" -#define SCF_STRING_NUMBER_INC 4 +#define SCF_STRING_NUMBER_INC 7 scf_string_t* scf_string_alloc() { diff --git a/util/scf_string.h b/util/scf_string.h index dcf1af4..9e433a4 100644 --- a/util/scf_string.h +++ b/util/scf_string.h @@ -4,12 +4,11 @@ #include"scf_vector.h" typedef struct { - intptr_t capacity; size_t len; + intptr_t capacity; uint8_t* data; } scf_string_t; - scf_string_t* scf_string_alloc(); scf_string_t* scf_string_clone(const scf_string_t* s); diff --git a/util/scf_vector.h b/util/scf_vector.h index 78f1de4..a747bd6 100644 --- a/util/scf_vector.h +++ b/util/scf_vector.h @@ -64,6 +64,7 @@ static inline int scf_vector_extend(scf_vector_t* v, int size) v->capacity = size; } + v->size = size; return 0; }