support char array[] inited by const string like "hello", support base 8/16 const...
authoryu.dongliang <18588496441@163.com>
Mon, 24 Aug 2026 07:47:03 +0000 (15:47 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 24 Aug 2026 07:47:03 +0000 (15:47 +0800)
core/scf_optimizer_basic_block.c
core/scf_variable.h
examples/char_array_cstr.c [new file with mode: 0644]
lex/scf_lex.c
native/x64/scf_x64_inst_common.c
parse/scf_dfa_var.c
parse/scf_operator_handler_semantic.c

index bf8ac6281f4b315253ce39787eead5dcc1797deb..7ede6e8a74855770e07b3c0a61d6855b3f21952b 100644 (file)
@@ -76,11 +76,10 @@ static void __optimize_dn_free(scf_dag_node_t* dn)
 
 static int _bb_dag_update(scf_basic_block_t* bb)
 {
-       scf_dag_node_t* dn;
-       scf_dag_node_t* dn_bb;
-       scf_dag_node_t* dn_func;
-       scf_dag_node_t* base;
-       scf_list_t*     l;
+       scf_dag_node_t*  dn;
+       scf_dag_node_t*  dn_bb;
+       scf_dag_node_t*  dn_func;
+       scf_list_t*      l;
 
        while (1) {
                int updated = 0;
@@ -102,6 +101,13 @@ static int _bb_dag_update(scf_basic_block_t* bb)
                        if (scf_type_is_assign_pointer(dn->type))
                                continue;
 
+                       if (SCF_OP_ASSIGN == dn->type && dn->childs && 2 == dn->childs->size) {
+                               dn_bb = dn->childs->data[0];
+
+                               if (scf_variable_char_array(dn_bb->var))
+                                       continue;
+                       }
+
                        if (scf_type_is_assign(dn->type)
                                        || SCF_OP_INC         == dn->type || SCF_OP_DEC       == dn->type
                                        || SCF_OP_3AC_INC     == dn->type || SCF_OP_3AC_DEC   == dn->type
index 4e3d2e96a5de386e1c620aebf02fc66e1dea9853..c908bac470370e9641934082ddec2f2542520e47 100644 (file)
@@ -190,6 +190,13 @@ static inline int scf_variable_is_array(scf_variable_t* v)
        return v->nb_dimentions > 0;
 }
 
+static inline int scf_variable_char_array(scf_variable_t* v)
+{
+       return 1 == v->nb_dimentions
+               && 0 == v->nb_pointers
+               && (SCF_VAR_CHAR == v->type || SCF_VAR_I8 == v->type || SCF_VAR_U8 == v->type);
+}
+
 static inline int scf_variable_may_malloced(scf_variable_t* v)
 {
        if (v->nb_dimentions > 0)
diff --git a/examples/char_array_cstr.c b/examples/char_array_cstr.c
new file mode 100644 (file)
index 0000000..b04de9d
--- /dev/null
@@ -0,0 +1,9 @@
+int printf(const char* fmt, ...);
+
+int main()
+{
+       char p[] = "hello\n";
+
+       printf(p);
+       return 0;
+}
index d42f565b56cc6818a0fb34341f17c31fd26863ab..2647478cc266b2ab0aa823e4dfd2cf611e38ec38 100644 (file)
@@ -502,114 +502,112 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
        return -1;
 }
 
-static int _lex_char_base8(scf_lex_t* lex, scf_string_t* s, int* num)
+static int _lex_number_char(scf_lex_t* lex, scf_string_t* s, int base, int* num)
 {
-       int tmp = -1;
        int n = 0;
        int v = 0;
 
+       if ('0' <= base && base <= '7')
+               v = base - '0';
+       else
+               assert('x' == base);
+
        while (1) {
                scf_char_t* c = _lex_pop_char(lex);
                if (!c)
                        return -ENOMEM;
 
-               tmp = c->c;
-
-               int ret = scf_string_cat_cstr_len(s, c->utf8, c->len);
-
-               lex->pos += c->len;
-               free(c);
-               c = NULL;
-
-               if (ret < 0)
-                       return ret;
-
-               if (tmp < '0' || tmp > '7')
-                       break;
+               int tmp = c->c;
 
-               v = (v << 3) + tmp - '0';
-               n++;
-       }
+               if ('x' == base) {
+                       if ('0' <= tmp && tmp <= '9')
+                               tmp -= '0';
 
-       if (tmp < 0) {
-               scf_loge("%s:%d:%d, un-expected char '%d' found\n", lex->file->data, lex->nb_lines, lex->pos, tmp);
-               return tmp;
-       }
+                       else if ('a' <= tmp && tmp <= 'f')
+                               tmp += 10 - 'a';
 
-       switch (tmp) {
-               case '8':
-               case '9':
-                       scf_loge("%s:%d:%d, un-expected char '%c' found\n", lex->file->data, lex->nb_lines, lex->pos, tmp);
-                       return -1;
-                       break;
+                       else if ('A' <= tmp && tmp <= 'F')
+                               tmp += 10 - 'A';
+                       else {
+                               if (n <= 0) {
+                                       scf_loge("%s:%d:%d, '%c:%d' NOT const char of base 16\n", lex->file->data, lex->nb_lines, lex->pos, tmp, tmp);
 
-               case '\'':
-                       if (n > 3) {
-                               scf_loge("%s:%d:%d, const base8 char should NOT more than 3 bits, real '%d bits'.\n",
-                                               lex->file->data, lex->nb_lines, lex->pos, n);
-                               return -1;
-                       }
-                       break;
+                                       free(c);
+                                       return -1;
+                               }
 
-               default:
-                       if (n > 1) {
-                               scf_loge("%s:%d:%d, un-expected char '%c' found\n", lex->file->data, lex->nb_lines, lex->pos, tmp);
-                               return -1;
+                               _lex_push_char(lex, c);
+                               break;
                        }
-                       break;
-       };
 
-       *num = v;
-       return tmp;
-}
+                       v = (v << 4) + tmp;
 
-static int _lex_char_base16(scf_lex_t* lex, scf_string_t* s, int* num)
-{
-       int tmp = -1;
-       int n = 0;
-       int v = 0;
+               } else if ('0' <= tmp && tmp <= '7') {
 
-       while (1) {
-               scf_char_t* c = _lex_pop_char(lex);
-               if (!c)
-                       return -ENOMEM;
-
-               tmp = c->c;
+                       v = (v << 3) + tmp - '0';
+               } else {
+                       _lex_push_char(lex, c);
+                       break;
+               }
 
-               int ret = scf_string_cat_cstr_len(s, c->utf8, c->len);
+               int ret = scf_string_cat_cstr_len(s, c->utf8, 1);
+               lex->pos++;
 
-               lex->pos += c->len;
                free(c);
                c = NULL;
                if (ret < 0)
                        return ret;
 
-               if (tmp >= '0' && tmp <= '9')
-                       tmp -= '0';
+               n++;
+       }
 
-               else if (tmp >= 'a' && tmp <= 'f')
-                       tmp += 10 - 'a';
+       *num = v;
+       return n;
+}
 
-               else if (tmp >= 'A' && tmp <= 'F')
-                       tmp += 10 - 'A';
-               else
+static int _lex_escape_char(scf_lex_t* lex, scf_string_t* s, int base, int* num)
+{
+       int ret;
+       int v;
+
+       switch (base) {
+               case 'x':
+                       return _lex_number_char(lex, s, base, num);
                        break;
 
-               v = (v << 4) + tmp;
-       }
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+                       v   = 0;
+                       ret = _lex_number_char(lex, s, base, &v);
+
+                       if (ret > 3) {
+                               scf_loge("%s:%d:%d, base 8 const char should NOT more than 3 bits (real %d bits)\n",
+                                               lex->file->data, lex->nb_lines, lex->pos, ret);
+                               return -1;
+                       }
 
-       if (tmp < 0) {
-               scf_loge("%s:%d:%d, un-expected char '%d' found\n", lex->file->data, lex->nb_lines, lex->pos, tmp);
-               return tmp;
-       }
+                       *num = v;
+                       return ret;
+                       break;
 
-       if ('\'' != tmp) {
-               scf_loge("%s:%d:%d, const char lost right '\n", lex->file->data, lex->nb_lines, lex->pos);
-               return -1;
-       }
+               case '8':
+               case '9':
+                       scf_loge("%s:%d:%d, un-expected char '%c' found\n", lex->file->data, lex->nb_lines, lex->pos, base);
+                       return -1;
+                       break;
 
-       *num = v;
-       return tmp;
+               default:
+                       *num = _find_escape_char(base);
+                       break;
+       };
+
+       return 0;
 }
 
 static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s, scf_char_t* c0)
@@ -643,6 +641,14 @@ static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s, sc
                return -ENOMEM;
        }
 
+       if ('\'' == c1->c) {
+               scf_loge("%s:%d:%d, const char should NOT empty\n", lex->file->data, lex->nb_lines, lex->pos);
+
+               scf_string_free(s);
+               free(c1);
+               return -EINVAL;
+       }
+
        int num = 0;
        int tmp = c1->c;
 
@@ -658,60 +664,57 @@ static int _lex_char(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s, sc
        }
 
        if ('\\' == tmp) {
-               ret = _lex_char_base8(lex, s, &num);
-               if (ret < 0) {
+               c1 = _lex_pop_char(lex);
+
+               if (!c1) {
                        scf_string_free(s);
-                       return ret;
+                       return -ENOMEM;
                }
 
-               switch (ret) {
-                       case 'x': // base 16 const char
-                               num = 0;
-                               ret = _lex_char_base16(lex, s, &num);
-                               if (ret < 0) {
-                                       scf_string_free(s);
-                                       return ret;
-                               }
-                               break;
+               tmp = c1->c;
 
-                       case '\'': // base 8 const char
-                               break;
+               ret = scf_string_cat_cstr_len(s, c1->utf8, c1->len);
 
-                       default: // other char
-                               num = _find_escape_char(ret);
-                               break;
-               };
-
-               tmp = ret;
-       } else
-               num = tmp;
+               lex->pos += c1->len;
+               free(c1);
+               c1 = NULL;
 
-       if ('\'' != tmp) {
-               c2 = _lex_pop_char(lex);
-               if (!c2) {
+               if (ret < 0) {
                        scf_string_free(s);
-                       return -ENOMEM;
+                       return ret;
                }
 
-               tmp = c2->c;
-
-               ret = scf_string_cat_cstr_len(s, c2->utf8, c2->len);
-
-               lex->pos += c2->len;
-               free(c2);
-               c2 = NULL;
-
+               ret = _lex_escape_char(lex, s, tmp, &num);
                if (ret < 0) {
                        scf_string_free(s);
                        return ret;
                }
+       } else
+               num = tmp;
+
+       c2 = _lex_pop_char(lex);
+       if (!c2) {
+               scf_string_free(s);
+               return -ENOMEM;
        }
 
-       if ('\'' == tmp)
-               w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_CHAR);
-       else
-               scf_loge("%s:%d:%d, const char lost right '\n", lex->file->data, lex->nb_lines, lex->pos);
+       if ('\'' == c2->c)
+               ret = scf_string_cat_cstr_len(s, c2->utf8, c2->len);
+       else {
+               scf_loge("%s:%d:%d, un-expected char '%c', ascii: %d\n", lex->file->data, lex->nb_lines, lex->pos, c2->c, c2->c);
+               ret = -EINVAL;
+       }
+
+       lex->pos += c2->len;
+       free(c2);
+       c2 = NULL;
+
+       if (ret < 0) {
+               scf_string_free(s);
+               return ret;
+       }
 
+       w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_CHAR);
        if (!w) {
                scf_string_free(s);
                return -1;
@@ -748,77 +751,123 @@ static int _lex_string(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0)
 {
        scf_lex_word_t* w = NULL;
        scf_string_t*   s = scf_string_cstr_len(c0->utf8, 1);
-       scf_string_t*   d = scf_string_alloc();
+       scf_string_t*   d = NULL;
 
-       int pos = lex->pos;
+       int pos = lex->pos++;
+
+       free(c0);
+       c0 = NULL;
+       if (!s)
+               return -ENOMEM;
+
+       d = scf_string_alloc();
+       if (!d) {
+               scf_string_free(s);
+               return -ENOMEM;
+       }
 
        while (1) {
                scf_char_t* c1 = _lex_pop_char(lex);
+               if (!c1) {
+                       scf_string_free(s);
+                       scf_string_free(d);
+                       return -ENOMEM;
+               }
+
+               if (EOF == c1->c || '\n' == c1->c) {
+                       scf_loge("%s:%d:%d, const string lost 2nd \"\n", lex->file->data, lex->nb_lines, lex->pos);
+
+                       free(c1);
+                       return -1;
+               }
+
+               int ret = scf_string_cat_cstr_len(s, c1->utf8, c1->len);
+               if (ret < 0) {
+                       scf_string_free(s);
+                       scf_string_free(d);
+                       free(c1);
+                       return ret;
+               }
+
+               lex->pos += c1->len;
 
                if ('\"' == c1->c) {
-                       scf_string_cat_cstr_len(s, c1->utf8, 1);
+                       free(c1);
+                       c1 = NULL;
 
                        w = scf_lex_word_alloc(lex->file, lex->nb_lines, pos, SCF_LEX_WORD_CONST_STRING);
+                       if (!w) {
+                               scf_string_free(s);
+                               scf_string_free(d);
+                               return -ENOMEM;
+                       }
+
                        w->data.s = d;
                        w->text   = s;
                        d = NULL;
                        s = NULL;
 
-                       lex->pos++;
                        *pword = w;
+                       return 0;
+
+               } else if ('\\' != c1->c) {
+
+                       ret = scf_string_cat_cstr_len(d, c1->utf8, c1->len);
 
                        free(c1);
                        c1 = NULL;
-                       return 0;
 
-               } else if ('\\' == c1->c) {
-                       scf_char_t* c2 = _lex_pop_char(lex);
+                       if (ret < 0) {
+                               scf_string_free(s);
+                               scf_string_free(d);
+                               return ret;
+                       }
 
-                       int ch2 = _find_escape_char(c2->c);
+                       continue;
+               }
 
-                       scf_string_cat_cstr_len(s, c1->utf8, 1);
-                       scf_string_cat_cstr_len(s, c2->utf8, c2->len);
-                       lex->pos += 1 + c2->len;
+               // for escape char
+               scf_char_t* c2 = _lex_pop_char(lex);
+               if (!c2) {
+                       scf_string_free(s);
+                       scf_string_free(d);
+                       return -ENOMEM;
+               }
 
-                       free(c2);
-                       free(c1);
-                       c2 = NULL;
-                       c1 = NULL;
+               int tmp = c2->c;
 
-                       if (0 == ch2) {
-                               while (1) {
-                                       c1 = _lex_pop_char(lex);
+               ret = scf_string_cat_cstr_len(s, c2->utf8, c2->len);
+               lex->pos += c2->len;
 
-                                       if ('0' <= c1->c && c1->c <= '7') {
-                                               ch2 <<= 3;
-                                               ch2  += c1->c - '0';
+               free(c2);
+               c2 = NULL;
 
-                                               scf_string_cat_cstr_len(s, c1->utf8, 1);
-                                               lex->pos++;
+               if (ret < 0) {
+                       scf_string_free(s);
+                       scf_string_free(d);
+                       return ret;
+               }
 
-                                               free(c1);
-                                               c1 = NULL;
-                                       } else {
-                                               _lex_push_char(lex, c1);
-                                               break;
-                                       }
-                               }
+               int num = 0;
 
-                               scf_string_cat_cstr_len(d, (char*)&ch2, 1);
-                       } else
-                               scf_string_cat_cstr_len(d, (char*)&ch2, 1);
+               ret = _lex_escape_char(lex, s, tmp, &num);
 
-               } else if (EOF == c1->c) {
-                       scf_loge("const string lost 2nd \" in file: %s, line: %d\n", lex->file->data, lex->nb_lines);
-                       return -1;
+               if (num > 255) {
+                       scf_loge("%s:%d:%d, char '%d' out of 0-255\n", lex->file->data, lex->nb_lines, lex->pos, num);
+                       ret = -1;
+               }
 
-               } else {
-                       scf_string_cat_cstr_len(s, c1->utf8, c1->len);
-                       scf_string_cat_cstr_len(d, c1->utf8, c1->len);
-                       lex->pos += c1->len;
+               if (ret < 0) {
+                       scf_string_free(s);
+                       scf_string_free(d);
+                       return ret;
+               }
 
-                       free(c1);
-                       c1 = NULL;
+               ret = scf_string_cat_cstr_len(d, (char*)&num, 1);
+               if (ret < 0) {
+                       scf_string_free(s);
+                       scf_string_free(d);
+                       return ret;
                }
        }
 }
index a4d573bd6a92ef1f312df5fdcee0d9089dfce43c..8740d2c4978b3376aac64e020a2bb9d83d044ff8 100644 (file)
@@ -155,6 +155,45 @@ static int _x64_inst_op2_imm(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_
        return 0;
 }
 
+int x64_init_char_array(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f)
+{
+       scf_instruction_t*  inst;
+       scf_x64_OpCode_t*   mov;
+       scf_variable_t*     v  = src->var;
+       scf_register_t*     rd = NULL;
+
+       X64_SELECT_REG_CHECK(&rd, dst, c, f, 1);
+
+       rd->used = 1;
+
+       int n = v->data.s->len + 1;
+       int i;
+
+       for (i = 0; i < (n & ~0x3); i += 4) {
+
+               mov  = x64_find_OpCode(SCF_X64_MOV, 4, 4, SCF_X64_I2E);
+               inst = x64_make_inst_I2P(mov, rd, i, v->data.s->data + i, 4);
+
+               X64_INST_ADD_CHECK(c, inst, NULL);
+       }
+
+       for (; i < (n & ~0x1); i += 2) {
+               mov  = x64_find_OpCode(SCF_X64_MOV, 2, 2, SCF_X64_I2E);
+               inst = x64_make_inst_I2P(mov, rd, i, v->data.s->data + i, 2);
+
+               X64_INST_ADD_CHECK(c, inst, NULL);
+       }
+
+       for (; i < n; i++) {
+               mov  = x64_find_OpCode(SCF_X64_MOV, 1, 1, SCF_X64_I2E);
+               inst = x64_make_inst_I2P(mov, rd, i, v->data.s->data + i, 1);
+
+               X64_INST_ADD_CHECK(c, inst, NULL);
+       }
+
+       return 0;
+}
+
 int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f)
 {
        assert(0 != dst->color);
@@ -166,9 +205,15 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_
        scf_rela_t*         rela   = NULL;
 
        if (0 == src->color) {
+
                if (scf_variable_const_string(src->var)) {
+
                        if (SCF_X64_MOV != OpCode_type)
                                return -EINVAL;
+
+                       if (scf_variable_char_array(dst->var))
+                               return x64_init_char_array(dst, src, c, f);
+
                        X64_SELECT_REG_CHECK(&rd, dst, c, f, 0);
 
                        return x64_load_const(rd, src, c, f);
index a93a3b9321f2f64f8ed9275e7f18b1c6a076a829..2ed0120e437baa3dd7853757d2c01813cf037316 100644 (file)
@@ -434,7 +434,20 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        if (d->current_var->nb_dimentions > 0) {
                scf_logi("var array '%s' init, nb_dimentions: %d\n", d->current_var->w->text->data, d->current_var->nb_dimentions);
-               return SCF_DFA_NEXT_WORD;
+
+               if (scf_variable_char_array(d->current_var)) {
+
+                       w = dfa->ops->pop_word(dfa);
+                       if (!w)
+                               return SCF_DFA_ERROR;
+                       dfa->ops->push_word(dfa, w);
+
+                       if (SCF_LEX_WORD_CONST_STRING == w->type)
+                               d->current_var->dimentions[0].num = w->data.s->len + 1;
+                       else
+                               return SCF_DFA_NEXT_WORD;
+               } else
+                       return SCF_DFA_NEXT_WORD;
        }
 
        scf_operator_t* op = scf_find_base_operator_by_type(SCF_OP_ASSIGN);
index d786287c82e6e91960dcbd6b34954b2a39efba6a..dcc43b976da5183d035983b63e34a8d59a353d8b 100644 (file)
@@ -77,27 +77,33 @@ static int _semantic_add_address_of(scf_ast_t* ast, scf_node_t** pp, scf_node_t*
 
 static int _semantic_add_type_cast(scf_ast_t* ast, scf_node_t** pp, scf_variable_t* v_dst, scf_node_t* src)
 {
-       scf_node_t* parent = src->parent;
-       scf_type_t* t      = v_dst->t;
-
-       assert(t);
-
        scf_operator_t* op = scf_find_base_operator_by_type(SCF_OP_TYPE_CAST);
        if (!op)
                return -EINVAL;
 
-       scf_variable_t* v_src = _scf_operand_get(src);
-       scf_variable_t* v     = SCF_VAR_ALLOC_BY_TYPE(NULL, t, v_src->const_flag, v_dst->nb_pointers, v_dst->func_ptr);
+       scf_node_t*      parent = src->parent;
+       scf_variable_t*  v_src  = _scf_operand_get(src);
+       scf_variable_t*  v;
+       scf_node_t*      dst;
+       scf_node_t*      cast;
+       scf_type_t*      t = v_dst->t;
+
+       assert(t);
+
+       int const_flag  = v_src->const_flag;
+       int nb_pointers = v_dst->nb_pointers + v_dst->nb_dimentions;
+
+       v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, const_flag, nb_pointers, v_dst->func_ptr);
        if (!v)
                return -ENOMEM;
 
-       scf_node_t* dst = scf_node_alloc(NULL, v->type, v);
+       dst = scf_node_alloc(NULL, v->type, v);
        scf_variable_free(v);
        v = NULL;
        if (!dst)
                return -ENOMEM;
 
-       scf_node_t* cast = scf_node_alloc(NULL, SCF_OP_TYPE_CAST, NULL);
+       cast = scf_node_alloc(NULL, SCF_OP_TYPE_CAST, NULL);
        if (!cast) {
                scf_node_free(dst);
                return -ENOMEM;
@@ -2621,8 +2627,11 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no
 
        if (v0->const_literal_flag || v0->nb_dimentions > 0) {
 
-               scf_loge("const var '%s' can't be assigned\n", v0->w->text->data);
-               return -1;
+               if (!scf_variable_char_array(v0) || !scf_variable_const_string(v1)) {
+
+                       scf_loge("const var '%s' can't be assigned\n", v0->w->text->data);
+                       return -1;
+               }
 
        } else if (v0->const_flag) {
                scf_logw("const var '%s' can't be assigned\n", v0->w->text->data);
@@ -2696,23 +2705,26 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                        }
                }
 
-               scf_logd("v0: v_%d_%d/%s\n", v0->w->line, v0->w->pos, v0->w->text->data);
+               if (!scf_variable_char_array(v0) || !scf_variable_const_string(v1)) {
 
-               if (scf_type_cast_check(ast, v0, v1) < 0) {
-                       scf_loge("\n");
-                       return -1;
-               }
+                       scf_logd("v0: v_%d_%d/%s\n", v0->w->line, v0->w->pos, v0->w->text->data);
 
-               int ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]);
-               if (ret < 0) {
-                       scf_loge("add type cast failed\n");
-                       return ret;
+                       if (scf_type_cast_check(ast, v0, v1) < 0) {
+                               scf_loge("\n");
+                               return -1;
+                       }
+
+                       int ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]);
+                       if (ret < 0) {
+                               scf_loge("add type cast failed\n");
+                               return ret;
+                       }
                }
        }
 
        scf_type_t*         t = v0->t;
        scf_lex_word_t* w = parent->w;
-       scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(w, t, v0->const_flag, v0->nb_pointers, v0->func_ptr);
+       scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(w, t, v0->const_flag, v0->nb_pointers + v0->nb_dimentions, v0->func_ptr);
        if (!r) {
                scf_loge("var alloc failed\n");
                return -1;