move some code to ../lex/scf_lex_util.c
authoryu.dongliang <18588496441@163.com>
Sat, 27 May 2023 15:34:31 +0000 (23:34 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 27 May 2023 15:34:31 +0000 (23:34 +0800)
core/scf_lex_word.h
lex/Makefile
lex/scf_lex.c
lex/scf_lex.h
lex/scf_lex_util.c [new file with mode: 0644]
parse/Makefile

index 90f839180aecdcdd1e30cc30541bd9a5d493839c..076baadbe2b37912ec4516564694e032831dbe0f 100644 (file)
@@ -24,6 +24,7 @@ enum scf_lex_words {
        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,     // +=
@@ -53,8 +54,9 @@ enum scf_lex_words {
        SCF_LEX_WORD_LA,            // << left angle brackets
        SCF_LEX_WORD_RA,            // >> right angle brackets
 
-       SCF_LEX_WORD_ARROW,         // -> arrow
-       SCF_LEX_WORD_DOT,                       // . dot
+       SCF_LEX_WORD_ARROW,         // ->  arrow
+       SCF_LEX_WORD_DOT,           // .   dot
+       SCF_LEX_WORD_RANGE,         // ..  range
        SCF_LEX_WORD_VAR_ARGS,      // ... variable args
 
        SCF_LEX_WORD_LB,                        // { left brace
@@ -71,10 +73,16 @@ enum scf_lex_words {
        // key words
        SCF_LEX_WORD_KEY_IF,            // if
        SCF_LEX_WORD_KEY_ELSE,          // else
+       SCF_LEX_WORD_KEY_THEN,      // then
+       SCF_LEX_WORD_KEY_ELSIF,     // else if
+       SCF_LEX_WORD_KEY_END_IF,    // end if
 
        SCF_LEX_WORD_KEY_FOR,           // for
        SCF_LEX_WORD_KEY_WHILE,         // while
 
+       SCF_LEX_WORD_KEY_REPEAT,    // repeat
+       SCF_LEX_WORD_KEY_UNTIL,     // until
+
        SCF_LEX_WORD_KEY_BREAK,         // break
        SCF_LEX_WORD_KEY_CONTINUE,      // continue
 
@@ -101,6 +109,13 @@ enum scf_lex_words {
 
        // data types
        SCF_LEX_WORD_KEY_CHAR,          // char
+       SCF_LEX_WORD_KEY_BIT,       // bit
+
+       SCF_LEX_WORD_ST_TIME,          // time
+       SCF_LEX_WORD_ST_TIME_OF_DATE,  // time of date
+       SCF_LEX_WORD_ST_DATE,          // date
+       SCF_LEX_WORD_ST_DATE_AND_TIME, // date and time
+       SCF_LEX_WORD_ST_STRING,        // string
 
        SCF_LEX_WORD_KEY_INT,           // int
        SCF_LEX_WORD_KEY_FLOAT,     // float
@@ -138,7 +153,9 @@ enum scf_lex_words {
        SCF_LEX_WORD_KEY_AWAIT,     // await
 
        SCF_LEX_WORD_KEY_UNION,     // union
-       SCF_LEX_WORD_KEY_STRUCT,        // struct
+       SCF_LEX_WORD_KEY_STRUCT,    // struct
+       SCF_LEX_WORD_KEY_ARRAY,     // array
+       SCF_LEX_WORD_KEY_OF,        // of
 
        // const literal value
        SCF_LEX_WORD_CONST_CHAR,
index fbd6e9a6d2d1c9bd64a7a3c4549338f1ff6d6ad6..f9dcda9ecca7491c4527b19670198c36cd0b7ca2 100644 (file)
@@ -1,5 +1,6 @@
 CFILES += ../util/scf_string.c
 CFILES += scf_lex.c
+CFILES += scf_lex_util.c
 CFILES += ../core/scf_lex_word.c
 CFILES += scf_lex_test.c
 
index 7402ddf246620df29ddcc110ef24e412ef1e2415..6564abab5ceb9ee6bc2c4ef0417c0abc81aca541 100644 (file)
@@ -184,33 +184,6 @@ int scf_lex_push_word(scf_lex_t* lex, scf_lex_word_t* word)
        return 0;
 }
 
-static scf_lex_char_t* _lex_pop_char(scf_lex_t* lex)
-{
-       assert(lex);
-       assert(lex->fp);
-
-       if (!scf_list_empty(&lex->char_list_head)) {
-               scf_list_t* l = scf_list_head(&lex->char_list_head);
-               scf_lex_char_t* c = scf_list_data(l, scf_lex_char_t, list);
-               scf_list_del(&c->list);
-               return c;
-       }
-
-       scf_lex_char_t* c = malloc(sizeof(scf_lex_char_t));
-       assert(c);
-
-       c->c = fgetc(lex->fp);
-       return c;
-}
-
-static void _lex_push_char(scf_lex_t* lex, scf_lex_char_t* c)
-{
-       assert(lex);
-       assert(c);
-
-       scf_list_add_front(&lex->char_list_head, &c->list);
-}
-
 static void _lex_space(scf_lex_t* lex)
 {
        scf_lex_char_t* c = _lex_pop_char(lex);
@@ -355,97 +328,6 @@ static int _lex_minus(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0
        return 0;
 }
 
-static int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
-{
-       uint64_t value = 0;
-
-       while (1) {
-               uint64_t value2;
-
-               scf_lex_char_t* 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;
-
-               else if ('A' <= c2->c && 'F' >= c2->c)
-                       value2    = c2->c  - 'A' + 10;
-
-               else {
-                       _lex_push_char(lex, c2);
-                       c2 = NULL;
-
-                       scf_lex_word_t* w;
-
-                       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;
-               }
-
-               value <<= 4;
-               value  += value2;
-
-               scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
-               lex->pos++;
-
-               free(c2);
-               c2 = NULL;
-       }
-}
-
-static int _lex_number_base_8(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
-{
-       uint64_t value = 0;
-
-       while (1) {
-               scf_lex_char_t* c2 = _lex_pop_char(lex);
-
-               if (c2->c >= '0' && c2->c <= '7') {
-                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
-                       lex->pos++;
-
-                       value  = (value << 3) + c2->c - '0';
-
-                       free(c2);
-                       c2 = NULL;
-
-               } else if ('8' == c2->c || '9' == c2->c) {
-                       scf_loge("number must be 0-7 when base 8");
-                       free(c2);
-                       c2 = NULL;
-                       return -1;
-               } else {
-                       _lex_push_char(lex, c2);
-                       c2 = NULL;
-
-                       scf_lex_word_t* w;
-
-                       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;
-               }
-       }
-}
-
 static int _lex_number(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
 {
        lex->pos++;
@@ -647,113 +529,6 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t*
        return -1;
 }
 
-static int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
-{
-       scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
-       lex->pos++;
-       free(c0);
-       c0 = NULL;
-
-       int nb_numbers = 0;
-       int nb_dots    = 1;
-
-       while (1) {
-               scf_lex_char_t* c1 = _lex_pop_char(lex);
-
-               if ('0' <= c1->c && '9' >= c1->c) {
-                       nb_numbers++;
-               } else if ('.' == c1->c) {
-                       nb_dots++;
-               } else {
-                       _lex_push_char(lex, c1);
-                       c1 = NULL;
-
-                       scf_lex_word_t* w = NULL;
-
-                       if (nb_numbers  > 0) {
-                               if (nb_dots > 1) {
-                                       scf_loge("\n");
-                                       return -1;
-                               }
-
-                               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 (1 == nb_dots) { // dot .
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT);
-
-                       } else if (3 == nb_dots) { // variable args ...
-                               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_VAR_ARGS);
-
-                       } else if (nb_dots > 1) { // dot must be 1 or 3, others error
-                               scf_loge("\n");
-                               return -1;
-                       }
-                       w->text = s;
-                       s = NULL;
-
-                       *pword = w;
-                       return 0;
-               }
-
-               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
-               lex->pos++;
-               free(c1);
-               c1 = NULL;
-       }
-}
-
-static int _lex_op1_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0)
-{
-       scf_string_t*   s = scf_string_cstr_len((char*)&c0->c, 1);
-       scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
-
-       lex->pos++;
-       w->text = s;
-       s = NULL;
-       *pword = w;
-
-       free(c0);
-       c0 = NULL;
-       return 0;
-}
-
-static int _lex_op2_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0,
-               int type0, char* chs, int* types, int n)
-{
-       scf_string_t* s = scf_string_cstr_len((char*)&c0->c, 1);
-
-       scf_lex_word_t* w = NULL;
-       scf_lex_char_t* c1 = _lex_pop_char(lex);
-
-       int i;
-       for (i = 0; i < n; i++) {
-               if (chs[i] == c1->c)
-                       break;
-       }
-
-       if (i < n) {
-               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, types[i]);
-               lex->pos += 2;
-
-               free(c1);
-               c1 = NULL;
-       } else {
-               _lex_push_char(lex, c1);
-               c1 = NULL;
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
-               lex->pos++;
-       }
-       w->text = s;
-       s       = NULL;
-       *pword  = w;
-
-       free(c0);
-       c0 = NULL;
-       return 0;
-}
-
 static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
 {
        scf_lex_word_t* w = NULL;
@@ -882,67 +657,6 @@ static int _lex_string(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c
        }
 }
 
-static int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0,
-               char ch1_0, char ch1_1, char ch2, int type0, int type1, int type2, int type3)
-{
-       scf_lex_char_t* c1 = _lex_pop_char(lex);
-       scf_lex_word_t* w  = NULL;
-       scf_string_t*   s  = scf_string_cstr_len((char*)&c0->c, 1);
-
-       if (ch1_0 == c1->c) {
-               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
-
-               scf_lex_char_t* c2 = _lex_pop_char(lex);
-
-               if (ch2 == c2->c) {
-                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
-
-                       w         = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
-                       w->text   = s;
-                       s         = NULL;
-                       lex->pos += 3;
-
-                       free(c2);
-                       c2 = NULL;
-               } else {
-                       _lex_push_char(lex, c2);
-                       c2 = NULL;
-
-                       w         = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type1);
-                       w->text   = s;
-                       s         = NULL;
-                       lex->pos += 2;
-               }
-
-               free(c1);
-               c1 = NULL;
-
-       } else if (ch1_1 == c1->c) {
-               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
-
-               w         = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type2);
-               w->text   = s;
-               s         = NULL;
-               lex->pos += 2;
-
-               free(c1);
-               c1 = NULL;
-       } else {
-               _lex_push_char(lex, c1);
-               c1 = NULL;
-
-               w       = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type3);
-               w->text = s;
-               s       = NULL;
-               lex->pos++;
-       }
-
-       *pword = w;
-       free(c0);
-       c0 = NULL;
-       return 0;
-}
-
 int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
 {
        assert(lex);
index 7b4bbfce3143886666d31518fdd284979528f11e..6079b43183abfa14f9c36ff8ccbab73ed4bc1817 100644 (file)
@@ -47,11 +47,26 @@ typedef struct {
 scf_lex_error_t*       scf_lex_error_alloc(scf_string_t* file, int line, int pos);
 void                           scf_lex_error_free(scf_lex_error_t* e);
 
+scf_lex_char_t*    _lex_pop_char (scf_lex_t* lex);
+void               _lex_push_char(scf_lex_t* lex, scf_lex_char_t* c);
+
+
 int    scf_lex_open(scf_lex_t** plex, const char* path);
 int scf_lex_close(scf_lex_t* lex);
 
 int 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_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_dot           (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0);
+
+int _lex_op1_ll1       (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0);
+int _lex_op2_ll1       (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0, char* chs, int* types, int n);
+int _lex_op3_ll1       (scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, char ch1_0, char ch1_1, char ch2, int type0, int type1, int type2, int type3);
 #endif
 
diff --git a/lex/scf_lex_util.c b/lex/scf_lex_util.c
new file mode 100644 (file)
index 0000000..0cf3407
--- /dev/null
@@ -0,0 +1,496 @@
+#include"scf_lex.h"
+
+scf_lex_char_t* _lex_pop_char(scf_lex_t* lex)
+{
+       assert(lex);
+       assert(lex->fp);
+
+       if (!scf_list_empty(&lex->char_list_head)) {
+               scf_list_t* l = scf_list_head(&lex->char_list_head);
+               scf_lex_char_t* c = scf_list_data(l, scf_lex_char_t, list);
+               scf_list_del(&c->list);
+               return c;
+       }
+
+       scf_lex_char_t* c = malloc(sizeof(scf_lex_char_t));
+       assert(c);
+
+       c->c = fgetc(lex->fp);
+       return c;
+}
+
+void _lex_push_char(scf_lex_t* lex, scf_lex_char_t* c)
+{
+       assert(lex);
+       assert(c);
+
+       scf_list_add_front(&lex->char_list_head, &c->list);
+}
+
+int _lex_op1_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0, int type0)
+{
+       scf_string_t*   s = scf_string_cstr_len((char*)&c0->c, 1);
+       scf_lex_word_t* w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
+
+       lex->pos++;
+       w->text = s;
+       s = NULL;
+
+       free(c0);
+       c0 = NULL;
+
+       *pword = w;
+       return 0;
+}
+
+int _lex_op2_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0,
+               int type0, char* chs, int* types, int n)
+{
+       scf_string_t*   s  = scf_string_cstr_len((char*)&c0->c, 1);
+       scf_lex_word_t* w  = NULL;
+       scf_lex_char_t* c1 = _lex_pop_char(lex);
+
+       int i;
+       for (i = 0; i < n; i++) {
+               if (chs[i] == c1->c)
+                       break;
+       }
+
+       if (i < n) {
+               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, types[i]);
+               lex->pos += 2;
+
+               free(c1);
+               c1 = NULL;
+
+       } else {
+               _lex_push_char(lex, c1);
+               c1 = NULL;
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
+               lex->pos++;
+       }
+
+       w->text = s;
+       s = NULL;
+
+       free(c0);
+       c0 = NULL;
+
+       *pword = w;
+       return 0;
+}
+
+int _lex_op3_ll1(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0,
+               char ch1_0, char ch1_1, char ch2, int type0, int type1, int type2, int type3)
+{
+       scf_lex_char_t* c1 = _lex_pop_char(lex);
+       scf_lex_char_t* c2 = NULL;
+       scf_lex_word_t* w  = NULL;
+       scf_string_t*   s  = scf_string_cstr_len((char*)&c0->c, 1);
+
+       if (ch1_0 == c1->c) {
+               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+
+               c2 = _lex_pop_char(lex);
+
+               if (ch2 == c2->c) {
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+
+                       w         = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type0);
+                       w->text   = s;
+                       s         = NULL;
+                       lex->pos += 3;
+
+                       free(c2);
+                       c2 = NULL;
+               } else {
+                       _lex_push_char(lex, c2);
+                       c2 = NULL;
+
+                       w         = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type1);
+                       w->text   = s;
+                       s         = NULL;
+                       lex->pos += 2;
+               }
+
+               free(c1);
+               c1 = NULL;
+
+       } else if (ch1_1 == c1->c) {
+               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+
+               w         = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type2);
+               w->text   = s;
+               s         = NULL;
+               lex->pos += 2;
+
+               free(c1);
+               c1 = NULL;
+       } else {
+               _lex_push_char(lex, c1);
+               c1 = NULL;
+
+               w       = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, type3);
+               w->text = s;
+               s       = NULL;
+               lex->pos++;
+       }
+
+       free(c0);
+       c0 = NULL;
+
+       *pword = w;
+       return 0;
+}
+
+int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
+{
+       scf_lex_char_t* c2;
+       scf_lex_char_t* c3;
+       scf_lex_word_t* w;
+
+       int      dot   = 0;
+       int      exp   = 0;
+       int      neg   = 0;
+       uint64_t value = 0;
+       uint64_t num;
+
+       while (1) {
+               c2 = _lex_pop_char(lex);
+
+               if (c2->c >= '0' && c2->c <= '9') {
+                       num    =        c2->c -  '0';
+                       value *= 10;
+                       value += num;
+
+               } else if ('.' == c2->c) {
+
+                       c3 = _lex_pop_char(lex);
+
+                       _lex_push_char(lex, c3);
+
+                       if ('.' == c3->c) {
+                               c3 = NULL;
+
+                               _lex_push_char(lex, c2);
+                               c2 = NULL;
+                               break;
+                       }
+
+                       c3 = NULL;
+
+                       if (++dot > 1) {
+                               scf_loge("\n");
+                               return -EINVAL;
+                       }
+
+               } else if ('e' == c2->c || 'E' == c2->c) {
+                       exp++;
+
+                       if (exp > 1) {
+                               scf_loge("\n");
+                               return -EINVAL;
+                       }
+
+               } else if ('-' == c2->c) {
+                       neg++;
+
+                       if (0 == exp || neg > 1) {
+                               scf_loge("\n");
+                               return -EINVAL;
+                       }
+
+               } else if ('_' == c2->c) {
+
+               } else {
+                       _lex_push_char(lex, c2);
+                       c2 = NULL;
+                       break;
+               }
+
+               scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+               lex->pos++;
+
+               free(c2);
+               c2 = NULL;
+       }
+
+       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);
+       } 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;
+}
+
+int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
+{
+       scf_lex_char_t* c2;
+       scf_lex_word_t* w;
+
+       uint64_t value = 0;
+       uint64_t value2;
+
+       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;
+
+               else if ('A' <= c2->c && 'F' >= c2->c)
+                       value2    = c2->c  - 'A' + 10;
+
+               else if ('_' == c2->c) {
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+                       lex->pos++;
+
+                       free(c2);
+                       c2 = NULL;
+
+               } else {
+                       _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;
+
+                       w->text = s;
+                       s = NULL;
+
+                       *pword = w;
+                       return 0;
+               }
+
+               value <<= 4;
+               value  += value2;
+
+               scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+               lex->pos++;
+
+               free(c2);
+               c2 = NULL;
+       }
+}
+
+int _lex_number_base_8(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
+{
+       scf_lex_char_t* c2;
+       scf_lex_word_t* w;
+
+       uint64_t value = 0;
+
+       while (1) {
+               c2 = _lex_pop_char(lex);
+
+               if (c2->c >= '0' && c2->c <= '7') {
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+                       lex->pos++;
+
+                       value  = (value << 3) + c2->c - '0';
+
+                       free(c2);
+                       c2 = NULL;
+
+               } else if ('8' == c2->c || '9' == c2->c) {
+                       scf_loge("number must be 0-7 when base 8");
+
+                       free(c2);
+                       c2 = NULL;
+                       return -1;
+
+               } else if ('_' == c2->c) {
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+                       lex->pos++;
+
+                       free(c2);
+                       c2 = NULL;
+
+               } else {
+                       _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;
+
+                       w->text = s;
+                       s = NULL;
+
+                       *pword = w;
+                       return 0;
+               }
+       }
+}
+
+int _lex_number_base_2(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s)
+{
+       scf_lex_char_t* c2;
+       scf_lex_word_t* w;
+
+       uint64_t value = 0;
+
+       while (1) {
+               c2 = _lex_pop_char(lex);
+
+               if (c2->c >= '0' && c2->c <= '1') {
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+                       lex->pos++;
+
+                       value  = (value << 1) + c2->c - '0';
+
+                       free(c2);
+                       c2 = NULL;
+
+               } else if (c2->c >= '2' && c2->c <= '9') {
+                       scf_loge("number must be 0-1 when base 2");
+
+                       free(c2);
+                       c2 = NULL;
+                       return -1;
+
+               } else if ('_' == c2->c) {
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+                       lex->pos++;
+
+                       free(c2);
+                       c2 = NULL;
+
+               } else {
+                       _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;
+
+                       w->text = s;
+                       s = NULL;
+
+                       *pword = w;
+                       return 0;
+               }
+       }
+}
+
+int _lex_dot(scf_lex_t* lex, scf_lex_word_t** pword, scf_lex_char_t* c0)
+{
+       scf_lex_char_t* c1 = _lex_pop_char(lex);
+       scf_lex_char_t* c2 = NULL;
+       scf_lex_word_t* w  = NULL;
+       scf_string_t*   s  = scf_string_cstr_len((char*)&c0->c, 1);
+
+       lex->pos++;
+
+       free(c0);
+       c0 = NULL;
+
+       if ('.' == c1->c) {
+
+               c2 = _lex_pop_char(lex);
+
+               if ('.' == c2->c) {
+                       scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+                       scf_string_cat_cstr_len(s, (char*)&c2->c, 1);
+                       lex->pos += 2;
+
+                       free(c1);
+                       free(c2);
+                       c1 = NULL;
+                       c2 = NULL;
+
+                       w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_VAR_ARGS);
+
+                       w->text = s;
+                       *pword  = w;
+                       return 0;
+               }
+
+               _lex_push_char(lex, c2);
+               c2 = NULL;
+
+               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+               lex->pos++;
+
+               free(c1);
+               c1 = NULL;
+
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_RANGE);
+
+               w->text = s;
+               *pword  = w;
+               return 0;
+       }
+
+       _lex_push_char(lex, c1);
+       c1 = NULL;
+
+       int numbers = 0;
+       int dots    = 1;
+
+       while (1) {
+               c1 = _lex_pop_char(lex);
+
+               if ('0' <= c1->c && '9' >= c1->c)
+                       numbers++;
+
+               else if ('.' == c1->c)
+                       dots++;
+               else {
+                       _lex_push_char(lex, c1);
+                       c1 = NULL;
+                       break;
+               }
+
+               scf_string_cat_cstr_len(s, (char*)&c1->c, 1);
+               lex->pos++;
+
+               free(c1);
+               c1 = NULL;
+       }
+
+       if (numbers  > 0) {
+
+               if (dots > 1) {
+                       scf_loge("\n");
+                       return -1;
+               }
+
+               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 (1 == dots) // dot .
+               w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOT);
+       else {
+               scf_loge("\n");
+               return -1;
+       }
+
+       w->text = s;
+       s = NULL;
+
+       *pword = w;
+       return 0;
+}
index 1795ff2d9bb93bb5d0ead6c9bbf4223a03bc28d3..7d5c6aa9880e5682eb42f0bbd93715341b4060e7 100644 (file)
@@ -1,6 +1,7 @@
 CFILES += ../util/scf_string.c
 CFILES += ../util/scf_graph.c
 CFILES += ../lex/scf_lex.c
+CFILES += ../lex/scf_lex_util.c
 
 CFILES += scf_parse_util.c
 #CFILES += scf_parse.c