1, support const double / float literal number such as .618, .5f, etc.
authoryu.dongliang <18588496441@163.com>
Tue, 9 Jun 2026 11:02:52 +0000 (19:02 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 9 Jun 2026 11:02:57 +0000 (19:02 +0800)
2, support const number calculate with u64 type.

12 files changed:
core/scf_calculate.c
core/scf_calculate.h
core/scf_calculate_i32.c
core/scf_calculate_i64.c
core/scf_calculate_u32.c
core/scf_calculate_u64.c [new file with mode: 0644]
examples/const_postfix.c [new file with mode: 0644]
examples/float_inc.c
lex/scf_lex_test.c
lex/scf_lex_util.c
parse/Makefile
util/scf_string.c

index 2e429c1b69105e966805cf0f74e1253dd27e0422..6f068ad7f8b220fc799074d00a8bf2b11b1cdd3c 100644 (file)
@@ -3,6 +3,7 @@
 #include"scf_calculate_i32.c"
 #include"scf_calculate_u32.c"
 #include"scf_calculate_i64.c"
+#include"scf_calculate_u64.c"
 #include"scf_calculate_float.c"
 #include"scf_calculate_double.c"
 
@@ -99,6 +100,37 @@ scf_calculate_t  base_calculates[] =
        {"i64", SCF_OP_GE,        SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_ge},
        {"i64", SCF_OP_LE,        SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_le},
 
+       // u64
+       {"u64", SCF_OP_ADD,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_add},
+       {"u64", SCF_OP_SUB,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_sub},
+       {"u64", SCF_OP_MUL,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_mul},
+       {"u64", SCF_OP_DIV,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_div},
+       {"u64", SCF_OP_MOD,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_mod},
+
+       {"u64", SCF_OP_SHL,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_shl},
+       {"u64", SCF_OP_SHR,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_shr},
+
+       {"u64", SCF_OP_INC,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_inc},
+       {"u64", SCF_OP_DEC,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_dec},
+
+       {"u64", SCF_OP_NEG,       SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_neg},
+
+       {"u64", SCF_OP_BIT_AND,   SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_and},
+       {"u64", SCF_OP_BIT_OR,    SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_or},
+       {"u64", SCF_OP_BIT_NOT,   SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_not},
+
+       {"u64", SCF_OP_LOGIC_AND, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_and},
+       {"u64", SCF_OP_LOGIC_OR,  SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_or},
+       {"u64", SCF_OP_LOGIC_NOT, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_not},
+
+       {"u64", SCF_OP_GT,        SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_gt},
+       {"u64", SCF_OP_LT,        SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_lt},
+
+       {"u64", SCF_OP_EQ,        SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_eq},
+       {"u64", SCF_OP_NE,        SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_ne},
+       {"u64", SCF_OP_GE,        SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_ge},
+       {"u64", SCF_OP_LE,        SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_le},
+
        {"float", SCF_OP_ADD,       SCF_VAR_FLOAT, SCF_VAR_FLOAT, SCF_VAR_FLOAT, scf_float_add},
        {"float", SCF_OP_SUB,       SCF_VAR_FLOAT, SCF_VAR_FLOAT, SCF_VAR_FLOAT, scf_float_sub},
        {"float", SCF_OP_MUL,       SCF_VAR_FLOAT, SCF_VAR_FLOAT, SCF_VAR_FLOAT, scf_float_mul},
@@ -136,4 +168,3 @@ scf_calculate_t* scf_find_base_calculate(int op_type, int src0_type, int src1_ty
 
        return NULL;
 }
-
index 145e252bdef1513e5fa4dc7d2c5a9633499e21af..4d2b19ab904e974fae79b22b1ea5d0cdac020180 100644 (file)
@@ -19,4 +19,3 @@ typedef struct {
 scf_calculate_t* scf_find_base_calculate(int op_type, int src0_type, int src1_type);
 
 #endif
-
index 50fc79c38c73733c414e9704b2b6e1e9d0aa9aab..c01ad957fbd8287f30c87106f10c53942755bf62 100644 (file)
@@ -63,4 +63,3 @@ SCF_I32_BINARY_OP(eq, ==)
 SCF_I32_BINARY_OP(ne, !=)
 SCF_I32_BINARY_OP(ge, >=)
 SCF_I32_BINARY_OP(le, <=)
-
index 06aa716fe3e51e138af388c4d81c0903c7eefa69..ed2eee953f31f0dc00fd328c76a9651c7625dd09 100644 (file)
@@ -63,4 +63,3 @@ SCF_I64_BINARY_OP(eq, ==)
 SCF_I64_BINARY_OP(ne, !=)
 SCF_I64_BINARY_OP(ge, >=)
 SCF_I64_BINARY_OP(le, <=)
-
index 7ecb10f32bc87e0a5ca769a8a45a48e008bb6939..fa982d232222eb53177ddbc4a0d86683cafec802 100644 (file)
@@ -63,4 +63,3 @@ SCF_U32_BINARY_OP(eq, ==)
 SCF_U32_BINARY_OP(ne, !=)
 SCF_U32_BINARY_OP(ge, >=)
 SCF_U32_BINARY_OP(le, <=)
-
diff --git a/core/scf_calculate_u64.c b/core/scf_calculate_u64.c
new file mode 100644 (file)
index 0000000..36aaebd
--- /dev/null
@@ -0,0 +1,65 @@
+#include"scf_calculate.h"
+
+#define SCF_U64_BINARY_OP(name, op) \
+int scf_u64_##name(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src0, scf_variable_t* src1) \
+{ \
+       scf_type_t*     t = scf_block_find_type_type(ast->current_block, SCF_VAR_U64); \
+       scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 0, 0, NULL); \
+       if (!r) \
+               return -ENOMEM; \
+       r->data.u64 = src0->data.u64 op src1->data.u64; \
+       if (pret) \
+               *pret = r; \
+       return 0; \
+}
+
+#define SCF_U64_UNARY_OP(name, op) \
+int scf_u64_##name(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src0, scf_variable_t* src1) \
+{ \
+       scf_type_t*     t = scf_block_find_type_type(ast->current_block, SCF_VAR_U64); \
+       scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 0, 0, NULL); \
+       if (!r) \
+               return -ENOMEM; \
+       r->data.u64 = op src0->data.u64; \
+       if (pret) \
+               *pret = r; \
+       return 0; \
+}
+
+#define SCF_U64_UPDATE_OP(name, op) \
+int scf_u64_##name(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src0, scf_variable_t* src1) \
+{ \
+       op src0->data.u64; \
+       if (pret) \
+               *pret = scf_variable_ref(src0); \
+       return 0; \
+}
+
+SCF_U64_BINARY_OP(add, +)
+SCF_U64_BINARY_OP(sub, -)
+SCF_U64_BINARY_OP(mul, *)
+SCF_U64_BINARY_OP(div, /)
+SCF_U64_BINARY_OP(mod, %)
+
+SCF_U64_BINARY_OP(shl, <<)
+SCF_U64_BINARY_OP(shr, >>)
+
+SCF_U64_UPDATE_OP(inc, ++);
+SCF_U64_UPDATE_OP(dec, --);
+
+SCF_U64_UNARY_OP(neg, -)
+
+SCF_U64_BINARY_OP(bit_and, &)
+SCF_U64_BINARY_OP(bit_or,  |)
+SCF_U64_UNARY_OP(bit_not, ~)
+
+SCF_U64_BINARY_OP(logic_and, &&)
+SCF_U64_BINARY_OP(logic_or,  ||)
+SCF_U64_UNARY_OP(logic_not, !)
+
+SCF_U64_BINARY_OP(gt, >)
+SCF_U64_BINARY_OP(lt, <)
+SCF_U64_BINARY_OP(eq, ==)
+SCF_U64_BINARY_OP(ne, !=)
+SCF_U64_BINARY_OP(ge, >=)
+SCF_U64_BINARY_OP(le, <=)
diff --git a/examples/const_postfix.c b/examples/const_postfix.c
new file mode 100644 (file)
index 0000000..6103d2e
--- /dev/null
@@ -0,0 +1,11 @@
+int printf(const char* fmt, ...);
+
+int a = 0;
+
+int main()
+{
+       int* p = &a;
+
+       printf("%#lx\n", p & ~0x1ull);
+       return 0;
+}
index c22fe880c15373c81ed5137909b5552cf9e2e38c..8e22f6f650e8767f22e74265151efb4a2961fe16 100644 (file)
@@ -3,7 +3,7 @@ int printf(const char* fmt, ...);
 
 int main()
 {
-       double d;
+       double d = .5f;
        for (d = 0.1; d < 10.0; d++)
                printf("%lg\n", d);
        return 0;
index 28e8223fad0be4cfab1ac522ac162846fad1e9b0..a42dbb1d1b216df8bfbd0dd9c19d8598d6761cfa 100644 (file)
@@ -4,9 +4,7 @@ int main(int argc, char* argv[])
 {
        scf_lex_t*      lex = NULL;
 
-       scf_string_t* text = scf_string_cstr("document.write(\"hello js\n\")");
-
-       if (scf_lex_open(&lex, argv[1], text) < 0) {
+       if (scf_lex_open(&lex, argv[1], NULL) < 0) {
                scf_loge("\n");
                return -1;
        }
index f18756fbf12b30aaa1996364e56ffed386f84eda..2a09659d1790c7e7e76c30d51247b7d318df94cb 100644 (file)
@@ -41,25 +41,26 @@ scf_char_t* _lex_pop_char(scf_lex_t* lex)
                return c;
        }
 
+       int n = 0;
        if (0x6 == (ret >> 5)) {
-               c->c   = ret & 0x1f;
-               c->len = 2;
+               c->c = ret & 0x1f;
+               n = 2;
 
        } else if (0xe == (ret >> 4)) {
-               c->c   = ret & 0xf;
-               c->len = 3;
+               c->c = ret & 0xf;
+               n = 3;
 
        } else if (0x1e == (ret >> 3)) {
-               c->c   = ret & 0x7;
-               c->len = 4;
+               c->c = ret & 0x7;
+               n = 4;
 
        } else if (0x3e == (ret >> 2)) {
-               c->c   = ret & 0x3;
-               c->len = 5;
+               c->c = ret & 0x3;
+               n = 5;
 
        } else if (0x7e == (ret >> 1)) {
-               c->c   = ret & 0x1;
-               c->len = 6;
+               c->c = ret & 0x1;
+               n = 6;
        } else {
                scf_loge("utf8 first byte wrong %#x, file: %s, line: %d\n", ret, lex->file->data, lex->nb_lines);
                free(c);
@@ -69,7 +70,7 @@ scf_char_t* _lex_pop_char(scf_lex_t* lex)
        c->utf8[0] = ret;
 
        int i;
-       for (i = 1; i < c->len; i++) {
+       for (i = 1; i < n; i++) {
 
                ret = __lex_getc(lex);
 
@@ -79,12 +80,13 @@ scf_char_t* _lex_pop_char(scf_lex_t* lex)
 
                        c->utf8[i] = ret;
                } else {
-                       scf_loge("utf8 byte[%d] wrong %#x, file: %s, line: %d\n", i + 1, ret, lex->file->data, lex->nb_lines);
+                       scf_loge("utf8 byte[%d] wrong %#x, file: %s, line: %d\n", i, ret, lex->file->data, lex->nb_lines);
                        free(c);
                        return NULL;
                }
        }
 
+       c->len = n;
        return c;
 }
 
@@ -212,71 +214,123 @@ int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0,
        return 0;
 }
 
+static scf_key_word_t  number_postfix[] =
+{
+       {"l",   SCF_LEX_WORD_CONST_INT},
+       {"ll",  SCF_LEX_WORD_CONST_I64},
+
+       {"u",   SCF_LEX_WORD_CONST_U32},
+       {"ul",  SCF_LEX_WORD_CONST_U32},
+       {"ull", SCF_LEX_WORD_CONST_U64},
+
+       {"f",   SCF_LEX_WORD_CONST_FLOAT},
+       {"lf",  SCF_LEX_WORD_CONST_DOUBLE},
+};
+
+static int _lex_number_postfix(const char* postfix, int n)
+{
+       scf_key_word_t*  key;
+       int i;
+
+       for (i  = 0; i < sizeof(number_postfix) / sizeof(number_postfix[0]); i++) {
+               key =              &number_postfix[i];
+
+               if (!strncmp(key->text, postfix, n))
+                       return key->type;
+       }
+
+       return -EINVAL;
+}
+
 int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
 {
-       scf_char_t* c2;
-       scf_char_t* c3;
-       scf_lex_word_t* w;
+       scf_char_t*      c2;
+       scf_char_t*      c3;
+       scf_lex_word_t*  w;
 
+       int      type  = -1;
        int      dot   = 0;
        int      exp   = 0;
        int      neg   = 0;
        uint64_t value = 0;
        uint64_t num;
 
+       char postfix[8];
+       int  n = 0;
+
        while (1) {
                c2 = _lex_pop_char(lex);
 
-               if (c2->c >= '0' && c2->c <= '9') {
-                       num    =        c2->c -  '0';
-                       value *= 10;
-                       value += num;
+               int tmp =  c2->c;
+               if ('A' <= tmp && 'Z' >= tmp)
+                       tmp |= 0x20;
 
-               } else if ('.' == c2->c) {
+               if ('a' <= tmp && 'z' >= tmp) {
 
-                       c3 = _lex_pop_char(lex);
+                       if (n > 0 || 'e' != tmp) {
+                               if (n < sizeof(postfix) - 1)
+                                       postfix[n++] = tmp;
 
-                       _lex_push_char(lex, c3);
+                               goto next;
+                       }
+
+               } else if (n > 0) {
+                       _lex_push_char(lex, c2);
+                       c2 = NULL;
+
+                       postfix[n] = '\0';
+
+                       type = _lex_number_postfix(postfix, n);
+                       if (type < 0) {
+                               scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos);
+                               goto error;
+                       }
+
+                       break;
+               }
+
+               if (tmp >= '0' && tmp <= '9')
+                       value = value * 10 + tmp - '0';
+
+               else if ('.' == tmp) {
+                       c3  = _lex_pop_char(lex);
+                       tmp = c3->c;
 
-                       if ('.' == c3->c) {
-                               c3 = NULL;
+                       _lex_push_char(lex, c3);
+                       c3 = NULL;
 
+                       if ('.' == tmp) {
                                _lex_push_char(lex, c2);
                                c2 = NULL;
                                break;
                        }
 
-                       c3 = NULL;
-
                        if (++dot > 1) {
                                scf_loge("\n");
-                               return -EINVAL;
+                               goto error;
                        }
 
-               } else if ('e' == c2->c || 'E' == c2->c) {
-                       exp++;
-
-                       if (exp > 1) {
+               } else if ('e' == tmp) {
+                       if (++exp > 1) {
                                scf_loge("\n");
-                               return -EINVAL;
+                               goto error;
                        }
 
-               } else if ('-' == c2->c) {
-                       neg++;
-
-                       if (0 == exp || neg > 1) {
+               } else if ('-' == tmp) {
+                       if (0 == exp || ++neg > 1) {
                                scf_loge("\n");
-                               return -EINVAL;
+                               goto error;
                        }
 
                } else if ('_' == c2->c) {
-
+                       // only to split every 3-4 numbers, no other use.
                } else {
                        _lex_push_char(lex, c2);
                        c2 = NULL;
                        break;
                }
 
+next:
                assert(1 == c2->len);
                scf_string_cat_cstr_len(s, c2->utf8, 1);
                lex->pos++;
@@ -286,10 +340,18 @@ int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
        }
 
        if (exp > 0 || dot > 0) {
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
-               w->data.d = atof(s->data);
+               if (SCF_LEX_WORD_CONST_FLOAT == type) {
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_FLOAT);
+                       w->data.f = atof(s->data);
+               } else {
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
+                       w->data.d = atof(s->data);
+               }
        } else {
-               if (value & ~0xffffffffULL)
+               if (type > 0)
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+
+               else if (value & ~0xffffffffULL)
                        w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
                else
                        w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
@@ -302,57 +364,66 @@ int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
 
        *pword = w;
        return 0;
+
+error:
+       free(c2);
+       return -EINVAL;
 }
 
 int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
 {
-       scf_char_t* c2;
-       scf_lex_word_t* w;
+       scf_char_t*      c2;
+       scf_lex_word_t*  w;
 
+       int      type  = -1;
        uint64_t value = 0;
-       uint64_t value2;
+
+       char postfix[8];
+       int  n = 0;
 
        while (1) {
                c2 = _lex_pop_char(lex);
 
-               if (c2->c >= '0' && c2->c <= '9')
-                       value2 =        c2->c -  '0';
-
-               else if ('a' <= c2->c && 'f' >= c2->c)
-                       value2    = c2->c  - 'a' + 10;
+               int tmp =  c2->c;
+               if ('A' <= tmp && 'Z' >= tmp)
+                       tmp |= 0x20;
 
-               else if ('A' <= c2->c && 'F' >= c2->c)
-                       value2    = c2->c  - 'A' + 10;
+               if ('g' <= tmp && 'z' >= tmp) {
+                       if (n < sizeof(postfix) - 1)
+                               postfix[n++] = tmp;
 
-               else if ('_' == c2->c) {
-                       assert(1 == c2->len);
-                       scf_string_cat_cstr_len(s, c2->utf8, 1);
-                       lex->pos++;
-
-                       free(c2);
-                       c2 = NULL;
+                       goto next;
 
-               } else {
+               } else if (n > 0) {
                        _lex_push_char(lex, c2);
                        c2 = NULL;
 
-                       if (value & ~0xffffffffULL)
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
-                       else
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
-
-                       w->data.u64 = value;
+                       postfix[n] = '\0';
 
-                       w->text = s;
-                       s = NULL;
+                       type = _lex_number_postfix(postfix, n);
+                       if (type < 0) {
+                               scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos);
+                               goto error;
+                       }
 
-                       *pword = w;
-                       return 0;
+                       break;
                }
 
-               value <<= 4;
-               value  += value2;
+               if (tmp >= '0' && tmp <= '9')
+                       value = (value << 4) + tmp - '0';
+
+               else if ('a' <= tmp && 'f' >= tmp)
+                       value = (value << 4) + tmp  - 'a' + 10;
+
+               else if ('_' == tmp) {
+                       // only to split every 3-4 numbers, no other use.
+               } else {
+                       _lex_push_char(lex, c2);
+                       c2 = NULL;
+                       break;
+               }
 
+next:
                assert(1 == c2->len);
                scf_string_cat_cstr_len(s, c2->utf8, 1);
                lex->pos++;
@@ -360,149 +431,266 @@ int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
                free(c2);
                c2 = NULL;
        }
+
+       if (type > 0)
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+
+       else if (value & ~0xffffffffULL)
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+       else
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+
+       w->data.u64 = value;
+
+       w->text = s;
+       s = NULL;
+
+       *pword = w;
+       return 0;
+
+error:
+       free(c2);
+       return -EINVAL;
 }
 
 int _lex_number_base_8(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
 {
-       scf_char_t*     c2;
-       scf_lex_word_t* w;
+       scf_char_t*      c2;
+       scf_lex_word_t*  w;
 
+       int      type  = -1;
        uint64_t value = 0;
 
+       char postfix[8];
+       int  n = 0;
+
        while (1) {
                c2 = _lex_pop_char(lex);
 
-               if (c2->c >= '0' && c2->c <= '7') {
-                       scf_string_cat_cstr_len(s, c2->utf8, 1);
-                       lex->pos++;
+               int tmp =  c2->c;
+               if ('A' <= tmp && 'Z' >= tmp)
+                       tmp |= 0x20;
 
-                       value  = (value << 3) + c2->c - '0';
+               if ('a' <= tmp && 'z' >= tmp) {
+                       if (n < sizeof(postfix) - 1)
+                               postfix[n++] = tmp;
 
-                       free(c2);
+                       goto next;
+
+               } else if (n > 0) {
+                       _lex_push_char(lex, c2);
                        c2 = NULL;
 
-               } else if ('8' == c2->c || '9' == c2->c) {
-                       scf_loge("number must be 0-7 when base 8");
+                       postfix[n] = '\0';
 
-                       free(c2);
-                       c2 = NULL;
-                       return -1;
+                       type = _lex_number_postfix(postfix, n);
+                       if (type < 0) {
+                               scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos);
+                               goto error;
+                       }
 
-               } else if ('_' == c2->c) {
-                       scf_string_cat_cstr_len(s, c2->utf8, 1);
-                       lex->pos++;
+                       break;
+               }
 
-                       free(c2);
-                       c2 = NULL;
+               if (tmp >= '0' && tmp <= '7')
+                       value = (value << 3) + tmp - '0';
+
+               else if ('8' == tmp || '9' == tmp) {
+                       scf_loge("number must be 0-7 when base 8");
+                       goto error;
 
+               } else if ('_' == tmp) {
+                       // only to split every 3-4 numbers, no other use.
                } else {
                        _lex_push_char(lex, c2);
                        c2 = NULL;
+                       break;
+               }
 
-                       if (value & ~0xffffffffULL)
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
-                       else
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
-                       w->data.u64 = value;
-
-                       w->text = s;
-                       s = NULL;
+next:
+               assert(1 == c2->len);
+               scf_string_cat_cstr_len(s, c2->utf8, 1);
+               lex->pos++;
 
-                       *pword = w;
-                       return 0;
-               }
+               free(c2);
+               c2 = NULL;
        }
+
+       if (type > 0)
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+
+       else if (value & ~0xffffffffULL)
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+       else
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+       w->data.u64 = value;
+
+       w->text = s;
+       s = NULL;
+
+       *pword = w;
+       return 0;
+
+error:
+       free(c2);
+       return -EINVAL;
 }
 
 int _lex_number_base_2(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
 {
-       scf_char_t* c2;
-       scf_lex_word_t* w;
+       scf_char_t*      c2;
+       scf_lex_word_t*  w;
 
+       int      type  = -1;
        uint64_t value = 0;
 
+       char postfix[8];
+       int  n = 0;
+
        while (1) {
                c2 = _lex_pop_char(lex);
 
-               if (c2->c >= '0' && c2->c <= '1') {
-                       assert(1 == c2->len);
-                       scf_string_cat_cstr_len(s, c2->utf8, 1);
-                       lex->pos++;
+               int tmp =  c2->c;
+               if ('A' <= tmp && 'Z' >= tmp)
+                       tmp |= 0x20;
 
-                       value  = (value << 1) + c2->c - '0';
+               if ('a' <= tmp && 'z' >= tmp) {
+                       if (n < sizeof(postfix) - 1)
+                               postfix[n++] = tmp;
 
-                       free(c2);
+                       goto next;
+
+               } else if (n > 0) {
+                       _lex_push_char(lex, c2);
                        c2 = NULL;
 
-               } else if (c2->c >= '2' && c2->c <= '9') {
-                       scf_loge("number must be 0-1 when base 2");
+                       postfix[n] = '\0';
 
-                       free(c2);
-                       c2 = NULL;
-                       return -1;
+                       type = _lex_number_postfix(postfix, n);
+                       if (type < 0) {
+                               scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos);
+                               goto error;
+                       }
 
-               } else if ('_' == c2->c) {
-                       assert(1   == c2->len);
-                       scf_string_cat_cstr_len(s, c2->utf8, 1);
-                       lex->pos++;
+                       break;
+               }
 
-                       free(c2);
-                       c2 = NULL;
+               if (tmp >= '0' && tmp <= '1')
+                       value = (value << 1) + tmp - '0';
+
+               else if (tmp >= '2' && tmp <= '9') {
+                       scf_loge("number must be 0-1 when base 2");
+                       goto error;
 
+               } else if ('_' == tmp) {
+                       // only to split every 3-4 numbers, no other use.
                } else {
                        _lex_push_char(lex, c2);
                        c2 = NULL;
+                       break;
+               }
 
-                       if (value & ~0xffffffffULL)
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
-                       else
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
-                       w->data.u64 = value;
-
-                       w->text = s;
-                       s = NULL;
+next:
+               assert(1 == c2->len);
+               scf_string_cat_cstr_len(s, c2->utf8, 1);
+               lex->pos++;
 
-                       *pword = w;
-                       return 0;
-               }
+               free(c2);
+               c2 = NULL;
        }
+
+       if (type > 0)
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+
+       else if (value & ~0xffffffffULL)
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U64);
+       else
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_U32);
+       w->data.u64 = value;
+
+       w->text = s;
+       s = NULL;
+
+       *pword = w;
+       return 0;
+
+error:
+       free(c2);
+       return -EINVAL;
 }
 
 int _lex_double(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
 {
-       scf_lex_word_t* w;
-       scf_char_t*     c2;
+       scf_char_t*      c2;
+       scf_lex_word_t*  w;
+
+       int  type = -1;
+       char postfix[8];
+       int  n = 0;
 
        while (1) {
                c2 = _lex_pop_char(lex);
 
-               if (c2->c >= '0' && c2->c <= '9') {
-                       scf_string_cat_cstr_len(s, c2->utf8, 1);
-                       lex->pos++;
+               int tmp =  c2->c;
+               if ('A' <= tmp && 'Z' >= tmp)
+                       tmp |= 0x20;
 
-                       free(c2);
-                       c2 = NULL;
+               if ('a' <= tmp && 'z' >= tmp) {
+                       if (n < sizeof(postfix) - 1)
+                               postfix[n++] = tmp;
 
-               } else if ('.' == c2->c) {
-                       scf_loge("too many '.' for number in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
+                       goto next;
 
-                       free(c2);
+               } else if (n > 0) {
+                       _lex_push_char(lex, c2);
                        c2 = NULL;
-                       return -1;
 
+                       postfix[n] = '\0';
+
+                       type = _lex_number_postfix(postfix, n);
+                       if (type < 0) {
+                               scf_loge("postfix '%s' NOT found, file: %s, line: %d, pos: %d\n", postfix, lex->file->data, lex->nb_lines, lex->pos);
+                               goto error;
+                       }
+
+                       break;
+               }
+
+               if (tmp >= '0' && tmp <= '9') {
+
+               } else if ('.' == tmp) {
+                       scf_loge("too many '.' for number in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
+                       goto error;
                } else {
                        _lex_push_char(lex, c2);
                        c2 = NULL;
                        break;
                }
+
+next:
+               assert(1 == c2->len);
+               scf_string_cat_cstr_len(s, c2->utf8, 1);
+               lex->pos++;
+
+               free(c2);
+               c2 = NULL;
        }
 
-       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
-       w->data.d = atof(s->data);
+       if (SCF_LEX_WORD_CONST_FLOAT == type) {
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_FLOAT);
+               w->data.f = atof(s->data);
+       } else {
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_DOUBLE);
+               w->data.d = atof(s->data);
+       }
 
        w->text = s;
        *pword  = w;
        return 0;
+
+error:
+       free(c2);
+       return -EINVAL;
 }
 
 int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
@@ -510,8 +698,6 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        scf_char_t*     c1 = _lex_pop_char(lex);
        scf_char_t*     c2 = NULL;
        scf_lex_word_t* w  = NULL;
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
        scf_string_t*   s  = scf_string_cstr_len(c0->utf8, c0->len);
 
        lex->pos += c0->len;
@@ -547,90 +733,53 @@ int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
                        c2 = NULL;
                }
 
-       } else {
-               if (lex->asm_flag
-                               && 'a' <= (c1->c | 0x20)
-                               && 'z' >= (c1->c | 0x20)) {
-
-                       do {
-                               scf_string_cat_cstr_len(s, c1->utf8, 1);
-                               lex->pos++;
-
-                               free(c1);
-                               c1 = _lex_pop_char(lex);
-
-                               if (!c1) {
-                                       scf_string_free(s);
-                                       return -ENOMEM;
-                               }
-                       } while ('a' <= (c1->c | 0x20) && 'z' >= (c1->c | 0x20));
-
-                       _lex_push_char(lex, c1);
-                       c1 = NULL;
+       } else if (lex->asm_flag
+                       && 'a' <= (c1->c | 0x20)
+                       && 'z' >= (c1->c | 0x20)) {
+               do {
+                       scf_string_cat_cstr_len(s, c1->utf8, 1);
+                       lex->pos++;
 
-                       int type = _find_key_word(s->data);
-                       if (type < 0) {
-                               scf_loge("unknown asm key word '%s', file: %s, line: %d\n", s->data, lex->file->data, lex->nb_lines);
+                       free(c1);
+                       c1 = _lex_pop_char(lex);
 
-                               scf_string_free(s);
-                               return -EINVAL;
-                       }
-
-                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
-                       if (!w) {
+                       if (!c1) {
                                scf_string_free(s);
                                return -ENOMEM;
                        }
+               } while ('a' <= (c1->c | 0x20) && 'z' >= (c1->c | 0x20));
 
-                       w->text = s;
-                       s = NULL;
+               _lex_push_char(lex, c1);
+               c1 = NULL;
 
-                       *pword = w;
-                       return 0;
+               int type = _find_key_word(s->data);
+               if (type < 0) {
+                       scf_loge("unknown asm key word '%s', file: %s, line: %d\n", s->data, lex->file->data, lex->nb_lines);
+
+                       scf_string_free(s);
+                       return -EINVAL;
+               }
+
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type);
+               if (!w) {
+                       scf_string_free(s);
+                       return -ENOMEM;
                }
 
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT);
                w->text = s;
                s = NULL;
 
+       } else {
+               int tmp = c1->c;
                _lex_push_char(lex, c1);
                c1 = NULL;
 
-               int ret = __lex_pop_word(lex, &w1);
-               if (ret < 0) {
-                       scf_lex_word_free(w);
-                       return ret;
-               }
-
-               if (SCF_LEX_WORD_CONST_CHAR <= w1->type && w1->type <= SCF_LEX_WORD_CONST_U64) {
-
-                       ret = __lex_pop_word(lex, &w2);
-                       if (ret < 0) {
-                               scf_lex_word_free(w);
-                               scf_lex_word_free(w1);
-                               return ret;
-                       }
-
-                       scf_lex_push_word(lex, w2);
-
-                       if (w2->type != SCF_LEX_WORD_ASSIGN && w2->type != SCF_LEX_WORD_DOT) {
-                               w->type   = SCF_LEX_WORD_CONST_DOUBLE;
-
-                               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;
-                               }
+               if ('0' <= tmp && '9' >= tmp) // for double / float .5, .618, etc.
+                       return _lex_double(lex, pword, s);
 
-                               w->data.d = atof(w->text->data);
-                       }
-               }
-
-               if (w1)
-                       scf_lex_push_word(lex, w1);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT);
+               w->text = s;
+               s = NULL;
        }
 
        *pword = w;
index 787673cc7658ba67fc7c89e56feef02c891a6c53..594763de6010b3b6290bf98f6b7639749d2b5b87 100644 (file)
@@ -168,7 +168,7 @@ CFILES += scf_dfa_async.c
 
 CFILES += scf_dfa_block.c
 
-CFLAGS += -g
+CFLAGS += -g -O3
 #CFLAGS += -Wall 
 CFLAGS += -I../util
 CFLAGS += -I../core
index ac82cd5c2d958bff7b9429c64c54db98b220dd7c..c73f9a24471c81f3215cbb6c841e5c697353734f 100644 (file)
@@ -108,7 +108,7 @@ int scf_string_cmp(const scf_string_t* s0, const scf_string_t* s1)
 
        if (s0->len > s1->len)
                return 1;
-       return strncmp(s0->data, s1->data, s0->len);
+       return memcmp(s0->data, s1->data, s0->len);
 }
 
 int    scf_string_cmp_cstr(const scf_string_t* s0, const char* str)