1, rename scf_parse_test.c to main.c,
authoryu.dongliang <maja_creater@qq.com>
Sat, 15 Oct 2022 07:21:59 +0000 (15:21 +0800)
committeryu.dongliang <maja_creater@qq.com>
Sat, 15 Oct 2022 07:46:53 +0000 (15:46 +0800)
2, optimize 3ac code for && and ||

core/scf_3ac.c
core/scf_3ac.h
parse/Makefile
parse/main.c [moved from parse/scf_parse_test.c with 100% similarity]
parse/scf_dfa_expr.c
parse/scf_dfa_function.c
parse/scf_dfa_var.c
parse/scf_parse.c [deleted file]
util/scf_rbtree.c

index b487f1b641c84fbbf88eefb1c807de3d57d318a1..fa057267ec3db8c68f065920636d23a0dbadff45 100644 (file)
@@ -911,21 +911,31 @@ static void _3ac_filter_dst_teq(scf_list_t* h, scf_3ac_code_t* c)
        scf_3ac_code_t*    teq   = dst0->code;
        scf_list_t*        l;
 
-       if (scf_list_prev(&c->list) == scf_list_sentinel(h))
-               return;
+       int jmp_op;
 
-       if (scf_list_next(&teq->list) == scf_list_sentinel(h))
+       if (scf_list_prev(&c->list) == scf_list_sentinel(h))
                return;
-
        setcc = scf_list_data(scf_list_prev(&c->list),   scf_3ac_code_t, list);
-       jcc   = scf_list_data(scf_list_next(&teq->list), scf_3ac_code_t, list);
 
        if ((SCF_OP_3AC_JNZ == c->op->type && SCF_OP_3AC_SETZ == setcc->op->type)
                        || (SCF_OP_3AC_JZ  == c->op->type && SCF_OP_3AC_SETNZ == setcc->op->type)
                        || (SCF_OP_3AC_JGT == c->op->type && SCF_OP_3AC_SETLE == setcc->op->type)
                        || (SCF_OP_3AC_JGE == c->op->type && SCF_OP_3AC_SETLT == setcc->op->type)
                        || (SCF_OP_3AC_JLT == c->op->type && SCF_OP_3AC_SETGE == setcc->op->type)
-                       || (SCF_OP_3AC_JLE == c->op->type && SCF_OP_3AC_SETGT == setcc->op->type)) {
+                       || (SCF_OP_3AC_JLE == c->op->type && SCF_OP_3AC_SETGT == setcc->op->type))
+               jmp_op = SCF_OP_3AC_JZ;
+
+       else if ((SCF_OP_3AC_JNZ == c->op->type && SCF_OP_3AC_SETNZ == setcc->op->type)
+                       || (SCF_OP_3AC_JZ  == c->op->type && SCF_OP_3AC_SETZ  == setcc->op->type)
+                       || (SCF_OP_3AC_JGT == c->op->type && SCF_OP_3AC_SETGT == setcc->op->type)
+                       || (SCF_OP_3AC_JGE == c->op->type && SCF_OP_3AC_SETGE == setcc->op->type)
+                       || (SCF_OP_3AC_JLT == c->op->type && SCF_OP_3AC_SETLT == setcc->op->type)
+                       || (SCF_OP_3AC_JLE == c->op->type && SCF_OP_3AC_SETLE == setcc->op->type))
+               jmp_op = SCF_OP_3AC_JNZ;
+       else
+               return;
+
+       while (teq && SCF_OP_3AC_TEQ == teq->op->type) {
 
                assert(setcc->dsts && 1 == setcc->dsts->size);
                assert(teq->srcs   && 1 == teq  ->srcs->size);
@@ -938,56 +948,72 @@ static void _3ac_filter_dst_teq(scf_list_t* h, scf_3ac_code_t* c)
                if (v_teq != v_set)
                        return;
 
-               if (SCF_OP_3AC_JZ == jcc->op ->type) {
+               for (l  = scf_list_next(&teq->list); l != scf_list_sentinel(h); l = scf_list_next(l)) {
+                       jcc = scf_list_data(l, scf_3ac_code_t, list);
 
-                       dst0 = c  ->dsts->data[0];
-                       dst1 = jcc->dsts->data[0];
+                       if (scf_type_is_jmp(jcc->op->type))
+                               break;
+               }
+               if (l == scf_list_sentinel(h))
+                       return;
 
-                       dst0->code = dst1->code;
+               if (SCF_OP_3AC_JZ == jmp_op) {
 
-               } else if (SCF_OP_3AC_JNZ == jcc->op->type) {
+                       if (SCF_OP_3AC_JZ == jcc->op ->type) {
 
-                       l = scf_list_next(&jcc->list);
-                       if (l == scf_list_sentinel(h))
-                               return;
+                               dst0 = c  ->dsts->data[0];
+                               dst1 = jcc->dsts->data[0];
 
-                       dst0       = c->dsts->data[0];
-                       dst0->code = scf_list_data(l, scf_3ac_code_t, list);
-               }
-       } else if ((SCF_OP_3AC_JNZ == c->op->type && SCF_OP_3AC_SETNZ == setcc->op->type)
-                       || (SCF_OP_3AC_JZ  == c->op->type && SCF_OP_3AC_SETZ  == setcc->op->type)
-                       || (SCF_OP_3AC_JGT == c->op->type && SCF_OP_3AC_SETGT == setcc->op->type)
-                       || (SCF_OP_3AC_JGE == c->op->type && SCF_OP_3AC_SETGE == setcc->op->type)
-                       || (SCF_OP_3AC_JLT == c->op->type && SCF_OP_3AC_SETLT == setcc->op->type)
-                       || (SCF_OP_3AC_JLE == c->op->type && SCF_OP_3AC_SETLE == setcc->op->type)) {
+                               dst0->code = dst1->code;
 
-               assert(setcc->dsts && 1 == setcc->dsts->size);
-               assert(teq->srcs   && 1 == teq  ->srcs->size);
+                       } else if (SCF_OP_3AC_JNZ == jcc->op->type) {
 
-               scf_3ac_operand_t* src   = teq  ->srcs->data[0];
-               scf_3ac_operand_t* dst   = setcc->dsts->data[0];
-               scf_variable_t*    v_teq = _scf_operand_get(src->node);
-               scf_variable_t*    v_set = _scf_operand_get(dst->node);
+                               l = scf_list_next(&jcc->list);
+                               if (l == scf_list_sentinel(h))
+                                       return;
 
-               if (v_teq != v_set)
-                       return;
+                               dst0       = c->dsts->data[0];
+                               dst0->code = scf_list_data(l, scf_3ac_code_t, list);
+                       } else
+                               return;
 
-               if (SCF_OP_3AC_JNZ == jcc-> op->type) {
+               } else if (SCF_OP_3AC_JNZ == jmp_op) {
 
-                       dst0 = c  ->dsts->data[0];
-                       dst1 = jcc->dsts->data[0];
+                       if (SCF_OP_3AC_JNZ == jcc-> op->type) {
 
-                       dst0->code = dst1->code;
+                               dst0 = c  ->dsts->data[0];
+                               dst1 = jcc->dsts->data[0];
 
-               } else if (SCF_OP_3AC_JZ == jcc->op->type) {
+                               dst0->code = dst1->code;
 
-                       l = scf_list_next(&jcc->list);
-                       if (l == scf_list_sentinel(h))
-                               return;
+                       } else if (SCF_OP_3AC_JZ == jcc->op->type) {
 
-                       dst0       = c->dsts->data[0];
-                       dst0->code = scf_list_data(l, scf_3ac_code_t, list);
+                               l = scf_list_next(&jcc->list);
+                               if (l == scf_list_sentinel(h))
+                                       return;
+
+                               dst0       = c->dsts->data[0];
+                               dst0->code = scf_list_data(l, scf_3ac_code_t, list);
+                       } else
+                               return;
                }
+               teq = dst0->code;
+
+               if (scf_list_prev(&jcc->list) == scf_list_sentinel(h))
+                       return;
+               setcc = scf_list_data(scf_list_prev(&jcc->list), scf_3ac_code_t, list);
+
+               if ((SCF_OP_3AC_JNZ == jcc->op->type && SCF_OP_3AC_SETZ  == setcc->op->type)
+                || (SCF_OP_3AC_JZ  == jcc->op->type && SCF_OP_3AC_SETNZ == setcc->op->type))
+
+                       jmp_op = SCF_OP_3AC_JZ;
+
+               else if ((SCF_OP_3AC_JNZ == jcc->op->type && SCF_OP_3AC_SETNZ == setcc->op->type)
+                         || (SCF_OP_3AC_JZ  == jcc->op->type && SCF_OP_3AC_SETZ  == setcc->op->type))
+
+                       jmp_op = SCF_OP_3AC_JNZ;
+               else
+                       return;
        }
 }
 
@@ -1160,6 +1186,19 @@ static int _3ac_filter_prev_teq(scf_list_t* h, scf_3ac_code_t* c, scf_3ac_code_t
        return 0;
 }
 
+void scf_3ac_list_print(scf_list_t* h)
+{
+       scf_3ac_code_t* c;
+       scf_list_t*         l;
+
+       for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
+
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+
+               scf_3ac_code_print(c, NULL);
+       }
+}
+
 static int _3ac_find_basic_block_start(scf_list_t* h)
 {
        int                       start = 0;
@@ -1247,10 +1286,13 @@ static int _3ac_find_basic_block_start(scf_list_t* h)
                        if (SCF_OP_3AC_TEQ == dst0->code->op->type)
                                _3ac_filter_dst_teq(h, c);
 
-                       l2 = scf_list_prev(&c->list);
-                       if (l2 != scf_list_sentinel(h)) {
+                       for (l2 = scf_list_prev(&c->list); l2 != scf_list_sentinel(h); l2 = scf_list_prev(l2)) {
+
                                c2  = scf_list_data(l2, scf_3ac_code_t, list);
 
+                               if (scf_type_is_setcc(c2->op->type))
+                                       continue;
+
                                // filter 2nd expr of logic op, such as '&&', '||'
                                if (SCF_OP_3AC_TEQ == c2->op->type) {
 
@@ -1258,6 +1300,7 @@ static int _3ac_find_basic_block_start(scf_list_t* h)
                                        if (ret < 0)
                                                return ret;
                                }
+                               break;
                        }
 
                        _3ac_filter_jmp(h, c);
index fd313faf474d0b6402aa52fba90afae562d5260b..bab4f8182045e85cec898cf50aff1a0f3aecb4b6 100644 (file)
@@ -60,6 +60,8 @@ scf_3ac_code_t*               scf_3ac_code_clone(scf_3ac_code_t* c);
 void                           scf_3ac_code_free(scf_3ac_code_t* code);
 void                           scf_3ac_code_print(scf_3ac_code_t* c, scf_list_t* sentinel);
 
+void                scf_3ac_list_print(scf_list_t* h);
+
 scf_3ac_code_t*     scf_branch_ops_code(int type, scf_label_t* l, scf_node_t* err);
 
 scf_3ac_operator_t*    scf_3ac_find_operator(const int type);
index 0cc1034c6237d3c7554e7a3753885eb0ae7ffe18..2967a02b9ccc40f464194314f9309a2fd972c0ea 100644 (file)
@@ -5,7 +5,7 @@ CFILES += ../lex/scf_lex.c
 CFILES += scf_parse_util.c
 #CFILES += scf_parse.c
 CFILES += scf_parse2.c
-CFILES += scf_parse_test.c
+CFILES += main.c
 CFILES += scf_operator_handler_semantic.c
 CFILES += scf_operator_handler_expr.c
 CFILES += scf_operator_handler_const.c
similarity index 100%
rename from parse/scf_parse_test.c
rename to parse/main.c
index 74208fa3e122b3251887e288e2bc13b9d1b7d9d2..c924860d296d511904b1fe67a458098d594acc40 100644 (file)
@@ -646,7 +646,7 @@ static int _expr_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _expr_multi_rets(scf_expr_t* e)
+int _expr_multi_rets(scf_expr_t* e)
 {
        if (SCF_OP_ASSIGN != e->nodes[0]->type)
                return 0;
@@ -753,6 +753,8 @@ static int _expr_fini_expr(scf_parse_t* parse, dfa_parse_data_t* d, int semi_fla
                        d->expr = d->expr->parent;
 
                if (0 == d->expr->nb_nodes) {
+                       scf_loge("d->expr: %p\n", d->expr);
+
                        scf_expr_free(d->expr);
                        d->expr = NULL;
 
@@ -777,6 +779,8 @@ static int _expr_fini_expr(scf_parse_t* parse, dfa_parse_data_t* d, int semi_fla
                        d->expr->semi_flag = semi_flag;
                        d->expr = NULL;
                }
+
+               scf_loge("d->expr: %p, d->expr_local_flag: %d\n", d->expr, d->expr_local_flag);
        }
 
        return SCF_DFA_OK;
index 032020ade169928796e99888747dce4ea1a40373..7485eea533465f2096b04cd76e2d32513103594a 100644 (file)
@@ -243,8 +243,24 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                assert(t->scope);
 
-               f = scf_scope_find_same_function(t->scope, d->current_function);
+               if (!strcmp(d->current_function->node.w->text->data, "__init")) {
 
+                       f = scf_scope_find_same_function(t->scope, d->current_function);
+
+               } else if (!strcmp(d->current_function->node.w->text->data, "__release")) {
+
+                       f = scf_scope_find_function(t->scope, d->current_function->node.w->text->data);
+
+                       if (f && !scf_function_same(f, d->current_function)) {
+
+                               scf_loge("function '%s' can't be overloaded, repeated declare first in line: %d, second in line: %d\n",
+                                               f->node.w->text->data, f->node.w->line, d->current_function->node.w->line);
+                               return SCF_DFA_ERROR;
+                       }
+               } else {
+                       scf_loge("class member function must be '__init()' or '__release()'\n");
+                       return SCF_DFA_ERROR;
+               }
        } else {
                scf_block_t* b = parse->ast->current_block;
 
index a2f54e3f11359a0a6e8861a6d73a989b247455a2..f979ed7cfa8de3c6d9950c104a0e19970d906eb6 100644 (file)
@@ -4,6 +4,8 @@
 
 extern scf_dfa_module_t dfa_module_var;
 
+int _expr_multi_rets(scf_expr_t* e);
+
 static int _var_is_assign(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
@@ -163,7 +165,7 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_parse_data_t* d)
        return 0;
 }
 
-static int _var_init_expr(scf_dfa_t* dfa, dfa_parse_data_t* d)
+static int _var_init_expr(scf_dfa_t* dfa, dfa_parse_data_t* d, int semi_flag)
 {
        scf_parse_t* parse = dfa->priv;
 
@@ -192,6 +194,15 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_parse_data_t* d)
                assert(d->expr->nb_nodes > 0);
 
                scf_node_add_child((scf_node_t*)parse->ast->current_block, (scf_node_t*)d->expr);
+
+               scf_loge("d->expr->parent->type: %d\n", d->expr->parent->type);
+
+               if (_expr_multi_rets(d->expr) < 0) {
+                       scf_loge("\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               d->expr->semi_flag = semi_flag;
        }
 
        d->expr = NULL;
@@ -214,7 +225,7 @@ static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (d->current_var)
                scf_variable_size(d->current_var);
 
-       if (d->expr_local_flag > 0 && _var_init_expr(dfa, d) < 0)
+       if (d->expr_local_flag > 0 && _var_init_expr(dfa, d, 0) < 0)
                return SCF_DFA_ERROR;
 
        return SCF_DFA_SWITCH_TO;
@@ -245,7 +256,7 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
 
        if (d->expr_local_flag > 0) {
 
-               if (_var_init_expr(dfa, d) < 0)
+               if (_var_init_expr(dfa, d, 1) < 0)
                        return SCF_DFA_ERROR;
 
        } else if (d->expr) {
diff --git a/parse/scf_parse.c b/parse/scf_parse.c
deleted file mode 100644 (file)
index 379d416..0000000
+++ /dev/null
@@ -1,1878 +0,0 @@
-#include"scf_parse.h"
-#include"scf_native_x64.h"
-#include"scf_operator_handler_semantic.h"
-
-scf_base_type_t        base_types[] = {
-       {SCF_VAR_CHAR,          "char",         1},
-       {SCF_VAR_INT,           "int",          4},
-       {SCF_VAR_DOUBLE,        "double",       8},
-       {SCF_VAR_STRING,        "string",       -1},
-};
-
-#define SCF_CHECK_LEX_POP_WORD(w) \
-       do {\
-               int ret = scf_lex_pop_word(parse->lex, &w);\
-               if (ret < 0) {\
-                       printf("%s(),%d, error: \n", __func__, __LINE__);\
-                       return -1;\
-               }\
-       } while (0)
-
-int _parse_struct_define(scf_parse_t* parse, scf_scope_t* current_scope);
-int _parse_var_declaration(scf_parse_t* parse, scf_type_t* t, scf_scope_t* current_scope);
-int _parse_expr(scf_parse_t* parse, scf_expr_t* expr);
-int _parse_operator(scf_parse_t* parse, scf_expr_t* expr, int nb_operands);
-int _parse_identity(scf_parse_t* parse, scf_lex_word_t* w0);
-int _parse_word(scf_parse_t* parse, scf_lex_word_t* w);
-
-int    scf_parse_open(scf_parse_t** pparse, const char* path)
-{
-       assert(pparse);
-       assert(path);
-
-       scf_parse_t* parse = calloc(1, sizeof(scf_parse_t));
-       assert(parse);
-
-       scf_list_init(&parse->word_list_head);
-       scf_list_init(&parse->error_list_head);
-
-       scf_list_init(&parse->code_list_head);
-
-       if (scf_lex_open(&parse->lex, path) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       if (scf_ast_open(&parse->ast) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       int i;
-       for (i = 0; i < sizeof(base_types) / sizeof(base_types[0]); i++) {
-               scf_ast_add_base_type(parse->ast, &base_types[i]);
-       }
-
-       scf_ast_add_file_block(parse->ast, path);
-
-       *pparse = parse;
-       return 0;
-}
-
-int scf_parse_close(scf_parse_t* parse)
-{
-       assert(parse);
-
-       free(parse);
-       parse = NULL;
-       return 0;
-}
-
-int _parse_operator_parentheses(scf_parse_t* parse, scf_expr_t* expr, int nb_operands)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-       assert(SCF_LEX_WORD_LP == w1->type);
-
-       scf_expr_t* e1 = scf_expr_alloc();
-       if (_parse_expr(parse, e1) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       SCF_CHECK_LEX_POP_WORD(w2);
-       if (SCF_LEX_WORD_RP != w2->type) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_operator_t* op = scf_find_base_operator("()", 1);
-       if (!op) {
-               printf("%s(),%d, error: operator not support, w1: %s, line: %d, pos: %d\n",
-                               __func__, __LINE__,
-                               w1->text->data, w1->line, w1->pos);
-               return -1;
-       }
-       scf_lex_word_free(w1);
-       w1 = NULL;
-
-       e1->type = op->type;
-       e1->op = op;
-       e1->w = w2;
-       e1->nb_nodes = 1;
-       w2 = NULL;
-
-       if (scf_expr_add_node(expr, e1) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-       printf("%s(),%d, () ok\n", __func__, __LINE__);
-       return _parse_operator(parse, expr, 2);
-}
-
-int _parse_operator_array_index(scf_parse_t* parse, scf_expr_t* expr, int nb_operands)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-       assert(SCF_LEX_WORD_LS == w1->type);
-       printf("%s(),%d\n", __func__, __LINE__);
-
-       scf_expr_t* e1 = scf_expr_alloc();
-       if (_parse_expr(parse, e1) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-       printf("%s(),%d\n", __func__, __LINE__);
-
-       SCF_CHECK_LEX_POP_WORD(w2);
-       if (SCF_LEX_WORD_RS != w2->type) {
-               printf("%s(),%d, error: w: %s\n", __func__, __LINE__, w2->text->data);
-               return -1;
-       }
-       printf("%s(),%d\n", __func__, __LINE__);
-
-       scf_operator_t* op = scf_find_base_operator("[]", 2);
-       if (!op) {
-               printf("%s(),%d, error: operator not support, w1: %s, line: %d, pos: %d\n",
-                               __func__, __LINE__,
-                               w1->text->data, w1->line, w1->pos);
-               return -1;
-       }
-       scf_lex_word_free(w1);
-       w1 = NULL;
-       printf("%s(),%d\n", __func__, __LINE__);
-
-       scf_node_t* n0 = scf_node_alloc(w2, op->type, NULL);
-       w2 = NULL;
-       n0->op = op;
-       if (scf_expr_add_node(expr, n0) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_node_t* n1 = e1->nodes[0];
-       e1->nodes[0] = NULL;
-       scf_expr_free(e1);
-       e1 = NULL;
-
-       scf_node_add_child(n0, n1);
-
-       printf("%s(),%d, [] ok\n", __func__, __LINE__);
-       return _parse_operator(parse, expr, 2);
-}
-
-int _parse_operator(scf_parse_t* parse, scf_expr_t* expr, int nb_operands)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-
-       if (!scf_lex_is_operator(w1)) {
-               printf("%s(),%d, w1: %s\n", __func__, __LINE__, w1->text->data);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       }
-
-       if (SCF_LEX_WORD_LP == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return _parse_operator_parentheses(parse, expr, 1);
-
-       } else if (SCF_LEX_WORD_RP == w1->type) {
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-
-       } else if (SCF_LEX_WORD_LS == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return _parse_operator_array_index(parse, expr, 2);
-
-       } else if (SCF_LEX_WORD_RS == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_LB == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_RB == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       }
-
-       scf_operator_t* op = scf_find_base_operator(w1->text->data, nb_operands);
-       if (!op) {
-               printf("%s(),%d, error: operator not support, w1: %s, line: %d, pos: %d\n",
-                               __func__, __LINE__,
-                               w1->text->data, w1->line, w1->pos);
-               return -1;
-       }
-       printf("%s(),%d, w1: %s, type: %d\n", __func__, __LINE__, w1->text->data, op->type);
-
-       scf_node_t* node = scf_node_alloc(w1, op->type, NULL);
-       node->op = op;
-       w1 = NULL;
-
-       if (scf_expr_add_node(expr, node) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       return _parse_expr(parse, expr);
-}
-
-int _parse_function_call_args(scf_parse_t* parse, scf_node_t* call)
-{
-       printf("%s(),%d\n", __func__, __LINE__);
-       scf_expr_t* e = scf_expr_alloc();
-       if (_parse_expr(parse, e) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       printf("%s(),%d\n", __func__, __LINE__);
-
-       scf_node_t* n = e->nodes[0];
-       e->nodes[0] = NULL;
-       scf_expr_free(e);
-       e = NULL;
-
-       if (n) {
-               scf_node_add_child(call, n);
-       }
-
-       scf_lex_word_t* w1 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-
-       if (SCF_LEX_WORD_RP == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w1);
-               w1 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_COMMA == w1->type) {
-               scf_lex_word_free(w1);
-               w1 = NULL;
-               return _parse_function_call_args(parse, call);
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_function_call(scf_parse_t* parse, scf_expr_t* expr, scf_lex_word_t* w0)
-{
-       scf_function_t* f = scf_ast_find_function(parse->ast, w0->text->data);
-       if (!f) {
-               printf("%s(),%d, error: %s()\n", __func__, __LINE__, w0->text->data);
-               printf("%s(),%d, ### call: current_block: %p\n", __func__, __LINE__, parse->ast->current_block);
-               return -1;
-       }
-
-       scf_node_t* call = scf_node_alloc(w0, SCF_OP_CALL, NULL);
-
-       scf_lex_word_t* w1 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-       assert(SCF_LEX_WORD_LP == w1->type);
-
-       if (_parse_function_call_args(parse, call) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       if (call->nb_nodes != f->argv->size) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_label_t* l = scf_label_alloc(NULL);
-       l->node = (scf_node_t*)f;
-
-       scf_node_t* n = scf_node_alloc_label(l);
-       scf_node_add_child(call, n);
-
-       scf_operator_t* op = scf_find_base_operator_by_type(SCF_OP_CALL);
-       call->op = op;
-       scf_expr_add_node(expr, call);
-
-       return _parse_operator(parse, expr, 2);
-}
-
-int _parse_expr(scf_parse_t* parse, scf_expr_t* expr)
-{
-       scf_lex_word_t* w1 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-       //printf("%s(),%d, w1->text->data: %s\n", __func__, __LINE__, w1->text->data);
-
-       if (SCF_LEX_WORD_NUMBER_CHAR == w1->type
-                       || SCF_LEX_WORD_NUMBER_INT == w1->type) {
-
-               scf_type_t* t = NULL;
-
-               if (SCF_LEX_WORD_NUMBER_CHAR == w1->type) {
-                       // const char 
-                       t       = scf_ast_find_type(parse->ast, "char");
-
-               } else if (SCF_LEX_WORD_NUMBER_INT == w1->type) {
-                       // const int
-                       t = scf_ast_find_type(parse->ast, "int");
-               }
-
-               scf_variable_t* var = scf_variable_alloc(w1, t);
-               var->const_flag                 = 1;
-               var->const_literal_flag = 1;
-               var->data.i                             = w1->data.i;
-
-               printf("%s(),%d, w1->text->data: %s\n", __func__, __LINE__, w1->text->data);
-               w1 = NULL;
-
-               scf_node_t* node = scf_node_alloc(NULL, var->type, var);
-
-               if (scf_expr_add_node(expr, node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               return _parse_operator(parse, expr, 2); // parse binary operator
-
-       } else if (SCF_LEX_WORD_NUMBER_DOUBLE == w1->type) {
-               // const double 
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_type_t*                     t       = scf_ast_find_type(parse->ast, "double");
-               scf_variable_t*         var = scf_variable_alloc(w1, t);
-               var->const_literal_flag = 1;
-               var->const_flag                 = 1;
-               var->data.d                             = w1->data.d;
-
-               scf_lex_word_free(w1);
-               w1 = NULL;
-
-               scf_node_t* node = scf_node_alloc(NULL, var->type, var);
-
-               if (scf_expr_add_node(expr, node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               return _parse_operator(parse, expr, 2); // parse binary operator
-
-       } else if (SCF_LEX_WORD_STRING == w1->type) {
-               // const string
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_type_t*                     t       = scf_ast_find_type(parse->ast, "char");
-
-               int nb_pointers                 = t->nb_pointers;
-               t->nb_pointers                  = 1;
-               scf_variable_t*         var = scf_variable_alloc(w1, t);
-               t->nb_pointers                  = nb_pointers;
-
-               var->const_literal_flag = 1;
-               var->const_flag                 = 1;
-               var->data.s                             = scf_string_clone(w1->data.s);
-
-               printf("%s(),%d, w1: %p, var->data.s: %s\n", __func__, __LINE__, w1, var->data.s->data);
-//             scf_lex_word_free(w1);
-               w1 = NULL;
-
-               printf("%s(),%d, var->data.s: %s\n", __func__, __LINE__, var->data.s->data);
-               scf_node_t* node = scf_node_alloc(NULL, var->type, var);
-
-               if (scf_expr_add_node(expr, node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               return _parse_operator(parse, expr, 2); // parse binary operator
-
-       } else if (scf_lex_is_identity(w1)) {
-               printf("%s(),%d, w1->text->data: %s\n", __func__, __LINE__, w1->text->data);
-
-               scf_lex_word_t* w2 = NULL;
-               SCF_CHECK_LEX_POP_WORD(w2);
-               if (SCF_LEX_WORD_LP == w2->type) {
-                       // function call
-                       scf_lex_push_word(parse->lex, w2);
-                       w2 = NULL;
-                       return _parse_function_call(parse, expr, w1);
-               } else {
-                       scf_lex_push_word(parse->lex, w2);
-                       w2 = NULL;
-               }
-
-               // variable, should be declared before
-               scf_variable_t* var = scf_ast_find_variable(parse->ast, w1->text->data);
-               if (!var) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               // w1 is not used now
-               scf_lex_word_free(w1);
-               w1 = NULL;
-
-               // alloc a new node to add to the expr
-               scf_node_t* node = scf_node_alloc(NULL, var->type, var);
-               if (scf_expr_add_node(expr, node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               return _parse_operator(parse, expr, 2); // parse binary operator
-
-       } else if (SCF_LEX_WORD_SEMICOLON == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w1);
-               w1 = NULL;
-               return 0;
-
-       } else if (SCF_LEX_WORD_RS == w1->type) {
-               // ']'
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_RP == w1->type) {
-               // ')'
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_COMMA == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               return 0;
-       }
-
-       // from here, should be unary operator
-       printf("%s(),%d, w1->text->data: %s\n", __func__, __LINE__, w1->text->data);
-       scf_lex_push_word(parse->lex, w1);
-       w1 = NULL;
-
-       int ret = _parse_operator(parse, expr, 1);
-       if (ret < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-       }
-       return ret;
-}
-
-int _parse_var_array_init(scf_parse_t* parse, scf_variable_t* var, scf_type_t* t, scf_scope_t* current_scope)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-       if (SCF_LEX_WORD_LB != w1->type) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_vector_t* vec = scf_vector_alloc();
-
-       while (1) {
-               SCF_CHECK_LEX_POP_WORD(w2);
-
-               if (SCF_LEX_WORD_RB == w2->type) {
-                       printf("%s(),%d\n", __func__, __LINE__);
-                       break;
-               }
-
-               if (SCF_LEX_WORD_COMMA == w2->type) {
-                       scf_lex_word_free(w2);
-                       w2 = NULL;
-                       continue;
-               } else if (SCF_LEX_WORD_SEMICOLON == w2->type) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-
-               scf_expr_t* expr = scf_expr_alloc();
-               if (_parse_expr(parse, expr) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               scf_variable_t* result = NULL;
-               scf_expr_calculate(parse->ast, expr, &result);
-               scf_variable_print(result);
-               scf_vector_add(vec, result);
-               result = NULL;
-
-               scf_expr_free(expr);
-               expr = NULL;
-       }
-
-       int i;
-       int n = 0;
-       int j = -1;
-       int k = 1;
-       for (i = 0; i < var->nb_dimentions; i++) {
-               if (var->dimentions[i] < 0) {
-                       n++;
-                       j = i;
-               } else if (0 == var->dimentions[i]) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               } else {
-                       k *= var->dimentions[i];
-               }
-       }
-       if (n > 1) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-       if (1 == n) {
-               assert(j >= 0);
-               if (vec->size % k != 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               var->dimentions[j] = vec->size / k;
-       }
-
-       scf_variable_alloc_space(var);
-
-       for (i = 0; i < vec->size; i++) {
-               printf("%s(),%d, i: %d\n", __func__, __LINE__, i);
-               scf_variable_set_array_member(var, i, vec->data[i]);
-       }
-
-       return 0;
-}
-
-int _parse_var_array(scf_parse_t* parse, scf_variable_t* var, scf_type_t* t, scf_scope_t* current_scope)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-       assert(SCF_LEX_WORD_LS == w1->type);
-
-       SCF_CHECK_LEX_POP_WORD(w2);
-
-       if (SCF_LEX_WORD_RS == w2->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w2);
-               w2 = NULL;
-
-               // set this dimention -1, then determine it when init array
-               scf_variable_add_array_dimention(var, -1);
-       } else {
-               // it should be an expr for the array dimention size
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-
-               scf_expr_t* expr = scf_expr_alloc();
-
-               printf("%s(),%d\n", __func__, __LINE__);
-               int ret = _parse_expr(parse, expr);
-               printf("%s(),%d\n", __func__, __LINE__);
-               if (ret < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               scf_lex_word_t* w4 = NULL;
-               SCF_CHECK_LEX_POP_WORD(w4);
-               printf("%s(),%d, w4: %s\n", __func__, __LINE__, w4->text->data);
-
-               assert(0 == ret);
-               printf("%s(),%d\n", __func__, __LINE__);
-
-               scf_variable_t* result = NULL;
-               scf_expr_calculate(parse->ast, expr, &result);
-               assert(result);
-               assert(SCF_VAR_INT == result->type);
-
-               scf_variable_add_array_dimention(var, result->data.i);
-
-               printf("%s(),%d, result: %p\n", __func__, __LINE__, result);
-               printf("%s(),%d, var: %p\n", __func__, __LINE__, var);
-               scf_variable_print(result);
-               printf("%s(),%d\n", __func__, __LINE__);
-
-               scf_variable_free(result);
-               result = NULL;
-
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_variable_print(var);
-               printf("%s(),%d\n", __func__, __LINE__);
-       }
-
-       scf_lex_word_t* w3 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w3);
-       if (SCF_LEX_WORD_COMMA == w3->type) {
-               scf_lex_word_free(w3);
-               w3 = NULL;
-               return _parse_var_declaration(parse, t, current_scope);
-
-       } else if (SCF_LEX_WORD_ASSIGN == w3->type) {
-               // array init
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w3);
-               w3 = NULL;
-
-               return _parse_var_array_init(parse, var, t, current_scope);
-
-       } else if (SCF_LEX_WORD_SEMICOLON == w3->type) {
-               scf_lex_word_free(w3);
-               w3 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_LS == w3->type) {
-               // multi-dimention array
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w3);
-               w3 = NULL;
-               return _parse_var_array(parse, var, t, current_scope);
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_var_declaration(scf_parse_t* parse, scf_type_t* t, scf_scope_t* current_scope)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-
-       if (SCF_LEX_WORD_STAR == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               // pointer var of type t, code like: t *
-               scf_lex_word_free(w1);
-               w1 = NULL;
-
-               t->nb_pointers++;
-               int ret = _parse_var_declaration(parse, t, current_scope);
-               t->nb_pointers--;
-
-               if (ret < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-               }
-               return ret;
-
-       } else if (SCF_LEX_WORD_SEMICOLON == w1->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w1);
-               w1 = NULL;
-               return 0;
-       }
-
-       if (!scf_lex_is_identity(w1)) {
-               printf("%s(),%d, error: w1->text->data: %s\n", __func__, __LINE__, w1->text->data);
-               return -1;
-       }
-
-       scf_variable_t* var = scf_scope_find_variable(current_scope, w1->text->data);
-       if (var) {
-               printf("%s(),%d, error: var '%s' already exist, line: %d\n", __func__, __LINE__, w1->text->data, var->w->line);
-               return -1;
-       }
-
-       var = scf_variable_alloc(w1, t);
-       w1 = NULL;
-       scf_scope_push_var(current_scope, var);
-#if 1
-       printf("%s(),%d, var: name: %s, type name: %s, type: %d, size: %d, offset: %d, nb_pointers: %d\n",
-                       __func__, __LINE__,
-                       var->w->text->data, t->name->data, var->type, var->size, var->offset, var->nb_pointers
-                       );
-#endif
-       SCF_CHECK_LEX_POP_WORD(w2);
-       if (SCF_LEX_WORD_COMMA == w2->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w2);
-               w2 = NULL;
-
-               int nb_pointers = t->nb_pointers;
-               t->nb_pointers = 0;
-               int ret = _parse_var_declaration(parse, t, current_scope);
-               t->nb_pointers = nb_pointers;
-               return ret;
-
-       } else if (SCF_LEX_WORD_ASSIGN == w2->type) {
-               scf_expr_t* expr = scf_expr_alloc();
-
-               scf_node_t* var_node = scf_node_alloc(NULL, var->type, var);
-               scf_node_t* assign_node = scf_node_alloc(w2, SCF_OP_ASSIGN, NULL);
-               w2 = NULL;
-
-               if (scf_expr_add_node(expr, var_node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               if (scf_expr_add_node(expr, assign_node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               printf("%s(),%d\n", __func__, __LINE__);
-               int ret = _parse_expr(parse, expr);
-               if (ret < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-               } else if (0 == ret) {
-                       scf_block_t* b = parse->ast->current_block;
-                       scf_node_add_child((scf_node_t*)b, expr);
-                       printf("%s(),%d, b: %p, expr: %p\n", __func__, __LINE__, b, expr);
-#if 0
-                       scf_variable_t* result = NULL;
-
-                       scf_expr_calculate(parse, expr, &result);
-                       assert(result);
-                       scf_variable_print(result);
-                       scf_variable_free(result);
-                       result = NULL;
-
-                       printf("%s(),%d\n", __func__, __LINE__);
-                       scf_variable_print(var);
-#endif
-               }
-               return ret;
-
-       } else if (SCF_LEX_WORD_SEMICOLON == w2->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_word_free(w2);
-               w2 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_LS == w2->type) {
-               printf("%s(),%d\n", __func__, __LINE__);
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-               return _parse_var_array(parse, var, t, current_scope);
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_struct_members(scf_parse_t* parse, scf_type_t* t, scf_scope_t* current_scope)
-{
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-       if (SCF_LEX_WORD_KEY_STRUCT == w1->type) {
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               int ret = _parse_struct_define(parse, current_scope);
-               if (ret < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-               }
-               return _parse_struct_members(parse, t, current_scope);
-
-       } else if (SCF_LEX_WORD_RB == w1->type) {
-               // current struct definition ended 
-               scf_lex_word_free(w1);
-               w1 = NULL;
-
-               int size = 0;
-               scf_list_t* l;
-               for (l = scf_list_tail(&current_scope->var_list_head);
-                               l != scf_list_sentinel(&current_scope->var_list_head);
-                               l = scf_list_prev(l)) {
-
-                       scf_variable_t* v = scf_list_data(l, scf_variable_t, list);
-
-                       assert(v->size > 0);
-                       v->offset = (size + v->size - 1) / v->size * v->size;
-                       size = v->offset + v->size;
-#if 1
-                       printf("%s(),%d, var: type: %d, name: %s, size: %d, offset: %d, nb_pointers: %d\n",
-                                       __func__, __LINE__,
-                                       v->type, v->w->text->data, v->size, v->offset, v->nb_pointers);
-#endif
-               }
-               t->size = size;
-#if 1
-               printf("%s(),%d, t: %d, name: %s, size: %d\n", __func__, __LINE__,
-                               t->type, t->name->data, t->size);
-#endif
-               return 0;
-       }
-
-       scf_type_t*     t1 = scf_scope_find_type(t->scope, w1->text->data);
-       if (!t1) {
-               t1 = scf_ast_find_type(parse->ast, w1->text->data);
-               if (!t1) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-       }
-       scf_lex_word_free(w1);
-       w1 = NULL;
-
-       if (_parse_var_declaration(parse, t1, current_scope) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       return _parse_struct_members(parse, t, current_scope);
-}
-
-int _parse_struct_define(scf_parse_t* parse, scf_scope_t* current_scope)
-{
-       scf_lex_word_t* w0 = NULL;
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w0);
-       assert(SCF_LEX_WORD_KEY_STRUCT == w0->type);
-       scf_lex_word_free(w0);
-       w0 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w1);
-       if (!scf_lex_is_identity(w1)) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_type_t*             t               = scf_scope_find_type(current_scope, w1->text->data);
-
-       SCF_CHECK_LEX_POP_WORD(w2);
-       if (SCF_LEX_WORD_SEMICOLON == w2->type) {
-               // only declare a new struct
-
-               if (!t) {
-                       // if not exist this type in current scope, add it
-                       t = scf_type_alloc(w1, w1->text->data, SCF_STRUCT + parse->ast->nb_structs, 0);
-                       w1 = NULL;
-                       scf_scope_push_type(current_scope, t);
-                       parse->ast->nb_structs++;
-               } else {
-                       scf_lex_word_free(w1);
-                       w1 = NULL;
-               }
-
-               scf_lex_word_free(w2);
-               w2 = NULL;
-               return 0;
-       } else if (SCF_LEX_WORD_STAR == w2->type) {
-               // define a struct pointer
-               if (!t) {
-                       t = scf_ast_find_type(parse->ast, w1->text->data);
-                       if (!t) {
-                               printf("%s(),%d, error: \n", __func__, __LINE__);
-                               return -1;
-                       }
-               }
-
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-
-               scf_lex_word_free(w1);
-               w1 = NULL;
-               return _parse_var_declaration(parse, t, current_scope);
-
-       } else if (SCF_LEX_WORD_LB == w2->type) {
-               // define a struct type
-
-               if (!t) {
-                       // if not exist this type in current scope, add it
-                       t = scf_type_alloc(w1, w1->text->data, SCF_STRUCT + parse->ast->nb_structs, 0);
-                       w1 = NULL;
-                       scf_scope_push_type(current_scope, t);
-                       parse->ast->nb_structs++;
-               } else {
-                       scf_lex_word_free(w1);
-                       w1 = NULL;
-               }
-
-               scf_scope_t* struct_scope = scf_scope_alloc(w2, t->name->data);
-               w2 = NULL;
-
-               //add struct scope to type's scope_list
-               t->scope = struct_scope;
-               if (_parse_struct_members(parse, t, struct_scope) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               return _parse_var_declaration(parse, t, current_scope);
-
-       } else if (scf_lex_is_identity(w2)) {
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-               return _parse_var_declaration(parse, t, current_scope);
-
-       } else if (SCF_LEX_WORD_RB == w2->type) {
-               scf_lex_word_free(w2);
-               w2 = NULL;
-               return _parse_var_declaration(parse, t, current_scope);
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_block(scf_parse_t* parse)
-{
-       scf_lex_word_t* w0 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w0);
-       assert(SCF_LEX_WORD_LB == w0->type);
-
-       scf_block_t* b = scf_block_alloc(w0);
-       scf_ast_push_block(parse->ast, b);
-       printf("%s(),%d, b: %p, b->node.parent: %p\n", __func__, __LINE__, b, b->node.parent);
-
-       while (1) {
-               scf_lex_word_t* w1 = NULL;
-               SCF_CHECK_LEX_POP_WORD(w1);
-
-               if (SCF_LEX_WORD_RB == w1->type) {
-                       b->w_end = w1;
-                       w1 = NULL;
-                       break;
-               }
-
-               if (_parse_word(parse, w1) < 0) {
-                       printf("%s(),%d, error: w: %d, '%s', w->line: %d, w->pos: %d\n", __func__, __LINE__, w1->type, w1->text->data, w1->line, w1->pos);
-                       return -1;
-               }
-       }
-
-       scf_ast_pop_block(parse->ast);
-       printf("%s(),%d\n", __func__, __LINE__);
-       return 0;
-}
-
-int _parse_while_body(scf_parse_t* parse)
-{
-       scf_lex_word_t* w1 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-       if (SCF_LEX_WORD_LB == w1->type) {
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-
-               if (_parse_block(parse) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               return 0;
-       } else {
-               // parse single statement, can't define variable here
-               if ((SCF_LEX_WORD_KEY_CHAR <= w1->type && SCF_LEX_WORD_KEY_DOUBLE >= w1->type)
-                               || SCF_LEX_WORD_KEY_STRUCT == w1->type) {
-
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               } else if (scf_lex_is_identity(w1)) {
-                       // identity can't be a defined type
-                       scf_type_t* t = scf_ast_find_type(parse->ast, w1->text->data);
-                       if (t) {
-                               printf("%s(),%d, error: \n", __func__, __LINE__);
-                               return -1;
-                       }
-
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-}
-
-int _parse_while(scf_parse_t* parse, scf_node_t** pnode)
-{
-       scf_lex_word_t* w0 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w0);
-       printf("\n%s(),%d, ## start: %s, line: %d\n", __func__, __LINE__, w0->text->data, w0->line);
-       assert(SCF_LEX_WORD_KEY_WHILE == w0->type);
-
-       scf_expr_t* e = scf_expr_alloc();
-       if (_parse_expr(parse, e) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_node_t* n = scf_node_alloc(w0, SCF_OP_WHILE, NULL);
-       printf("%s(),%d ## n: %p, %s, e: %p\n", __func__, __LINE__, n, n->w->text->data, e);
-       scf_node_add_child(n, e);
-       scf_ast_push_block(parse->ast, (scf_block_t*)n);
-
-       if (_parse_while_body(parse) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_ast_pop_block(parse->ast);
-       w0 = NULL;
-       *pnode = n;
-       printf("%s(),%d ## n: %p, %s\n", __func__, __LINE__, n, n->w->text->data);
-       return 0;
-}
-
-int _parse_if_body(scf_parse_t* parse)
-{
-       scf_lex_word_t* w1 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-       if (SCF_LEX_WORD_LB == w1->type) {
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-
-               if (_parse_block(parse) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               return 0;
-       } else {
-               // parse single statement, can't define variable here
-               if ((SCF_LEX_WORD_KEY_CHAR <= w1->type && SCF_LEX_WORD_KEY_DOUBLE >= w1->type)
-                               || SCF_LEX_WORD_KEY_STRUCT == w1->type) {
-
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               } else if (scf_lex_is_identity(w1)) {
-                       // identity can't be a defined type
-                       scf_type_t* t = scf_ast_find_type(parse->ast, w1->text->data);
-                       if (t) {
-                               printf("%s(),%d, error: \n", __func__, __LINE__);
-                               return -1;
-                       }
-
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-}
-
-int _parse_if(scf_parse_t* parse, scf_node_t** pnode)
-{
-       scf_lex_word_t* w0 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w0);
-       printf("\n%s(),%d, ## start: %s, line: %d\n", __func__, __LINE__, w0->text->data, w0->line);
-       assert(SCF_LEX_WORD_KEY_IF == w0->type);
-
-       scf_expr_t* e = scf_expr_alloc();
-       if (_parse_expr(parse, e) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_node_t* n = scf_node_alloc(w0, SCF_OP_IF, NULL);
-       printf("%s(),%d ## n: %p, %s, e: %p\n", __func__, __LINE__, n, n->w->text->data, e);
-       scf_node_add_child(n, e);
-       scf_ast_push_block(parse->ast, (scf_block_t*)n);
-
-       if (_parse_if_body(parse) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       //parse 'else' statement when exist
-       scf_lex_word_t* w2 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w2);
-       if (SCF_LEX_WORD_KEY_ELSE != w2->type) {
-               // end to parse 'if'
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-
-               scf_ast_pop_block(parse->ast); // return to the parent block of 'if'
-               w0 = NULL;
-               *pnode = n;
-               printf("%s(),%d ## n: %p, %s\n", __func__, __LINE__, n, n->w->text->data);
-               return 0;
-       }
-       scf_lex_word_free(w2);
-       w2 = NULL;
-
-       scf_lex_word_t* w3 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w3);
-
-       if (SCF_LEX_WORD_KEY_IF == w3->type) {
-               scf_lex_push_word(parse->lex, w3);
-               w3 = NULL;
-
-               // recursive parse 'if'
-               if (_parse_if(parse, pnode) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               *pnode = n;
-               printf("%s(),%d ## n: %p, %s\n", __func__, __LINE__, n, n->w->text->data);
-               return 0;
-       }
-
-       scf_lex_push_word(parse->lex, w3);
-       w3 = NULL;
-       if (_parse_if_body(parse) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_ast_pop_block(parse->ast); // return to the parent block of 'if'
-       printf("\n%s(),%d, ## end: %s, line: %d\n", __func__, __LINE__, w0->text->data, w0->line);
-       w0 = NULL;
-       *pnode = n;
-       return 0;
-}
-
-int _parse_identity(scf_parse_t* parse, scf_lex_word_t* w0)
-{
-       scf_lex_word_t* w1 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-
-       if (scf_lex_is_identity(w1)) {
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-
-               scf_type_t* t = scf_ast_find_type(parse->ast, w0->text->data);
-               if (t) {
-                       printf("%s(),%d\n", __func__, __LINE__);
-                       scf_lex_word_free(w0);
-                       w0 = NULL;
-                       scf_scope_t* current_scope = scf_ast_current_scope(parse->ast);
-                       return _parse_var_declaration(parse, t, current_scope);
-               } else {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-       } else if (scf_lex_is_operator(w1)) {
-
-               scf_lex_push_word(parse->lex, w1);
-               w1 = NULL;
-               scf_lex_push_word(parse->lex, w0);
-               w0 = NULL;
-
-               scf_expr_t* e = scf_expr_alloc();
-               if (_parse_expr(parse, e) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               scf_block_t* b = parse->ast->current_block;
-               scf_node_add_child((scf_node_t*)b, e);
-               printf("%s(),%d, b: %p, e: %p\n", __func__, __LINE__, b, e);
-#if 0
-               scf_variable_t* result = NULL;
-               scf_expr_calculate(parse, e, &result);
-               scf_variable_print(result);
-#endif
-               return 0;
-
-       } else if (SCF_LEX_WORD_COLON == w1->type) {
-               printf("%s(),%d, parse label: '%s', line: %d, pos: %d\n", __func__, __LINE__, w0->text->data, w0->line, w0->pos);
-
-               scf_lex_word_free(w1);
-               w1 = NULL;
-
-               scf_scope_t* current_scope = scf_ast_current_scope(parse->ast);
-               scf_label_t* l = scf_scope_find_label(current_scope, w0->text->data);
-               if (l) {
-                       printf("%s(),%d, error: label '%s' already exist in current scope\n",
-                                       __func__, __LINE__, w0->text->data);
-                       return -1;
-               }
-
-               l = scf_label_alloc(w0);
-               w0 = NULL;
-
-               scf_node_t* n = scf_node_alloc_label(l);
-               l->node = n;
-
-               scf_node_add_child((scf_node_t*)parse->ast->current_block, n);
-               scf_scope_push_label(current_scope, l);
-               return 0;
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_function_body(scf_parse_t* parse, scf_function_t* f)
-{
-       scf_lex_word_t* w0 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w0);
-
-       if (SCF_LEX_WORD_SEMICOLON == w0->type) {
-               if (f->node.nb_nodes > 0) {
-                       f->w_end = w0;
-                       w0 = NULL;
-
-                       printf("%s(),%d, ### end function: %s, %s\n", __func__, __LINE__,
-                                       f->node.w->text->data,
-                                       f->w_end->text->data
-                                       );
-               } else {
-                       scf_lex_word_free(w0);
-                       w0 = NULL;
-               }
-               return 0;
-       } else if (SCF_LEX_WORD_LB == w0->type) {
-               scf_lex_push_word(parse->lex, w0);
-               w0 = NULL;
-
-               printf("%s(),%d, ### start, current_block: %p, f: %p\n", __func__, __LINE__, parse->ast->current_block, f);
-               return _parse_block(parse);
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_function_args(scf_parse_t* parse, scf_function_t* f)
-{
-       printf("%s(),%d, ### start, current_block: %p, f: %p\n", __func__, __LINE__, parse->ast->current_block, f);
-       scf_type_t* t = NULL;
-       scf_lex_word_t* w0 = NULL;
-       scf_lex_word_t* w1 = NULL;
-
-       SCF_CHECK_LEX_POP_WORD(w0);
-
-       if ((SCF_LEX_WORD_KEY_CHAR <= w0->type &&
-                       SCF_LEX_WORD_KEY_DOUBLE >= w0->type)
-               || scf_lex_is_identity(w0)) {
-
-               t = scf_ast_find_type(parse->ast, w0->text->data);
-
-       } else if (SCF_LEX_WORD_KEY_STRUCT == w0->type) {
-               SCF_CHECK_LEX_POP_WORD(w1);
-
-               t = scf_ast_find_type(parse->ast, w1->text->data);
-
-       } else if (SCF_LEX_WORD_RP == w0->type) {
-               // end arg list
-               scf_lex_word_free(w0);
-               w0 = NULL;
-               if (f->arg_index != f->argv->size) {
-                       printf("%s(),%d, error: arg numbers not same: %d, %d\n", __func__, __LINE__,
-                                       f->arg_index, f->argv->size);
-                       return -1;
-               }
-               return 0;
-
-       } else {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       if (!t) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       assert(0 == t->nb_pointers);
-       scf_vector_t* vec = scf_vector_alloc();
-       scf_lex_word_t* w2 = NULL;
-
-       while (1) {
-               SCF_CHECK_LEX_POP_WORD(w2);
-               if (SCF_LEX_WORD_STAR == w2->type) {
-                       scf_vector_add(vec, w2);
-                       w2 = NULL;
-               } else {
-                       break;
-               }
-       }
-       assert(w2);
-
-       scf_variable_t* arg = NULL;
-
-       if (scf_lex_is_identity(w2)) {
-
-               scf_variable_t* v = scf_ast_find_variable(parse->ast, w2->text->data);
-               if (v) {
-                       printf("%s(),%d, error: arg '%s' already exist at line: %d, pos: %d\n", __func__, __LINE__,
-                                       w2->text->data, v->w->line, v->w->pos);
-                       return -1;
-               }
-
-               t->nb_pointers = vec->size;
-               arg     = scf_variable_alloc(w2, t);
-               w2 = NULL;
-               t->nb_pointers = 0;
-
-               SCF_CHECK_LEX_POP_WORD(w2); // read next word, should be ',' or ')'
-       } else {
-               t->nb_pointers = vec->size;
-               arg     = scf_variable_alloc(NULL, t);
-               t->nb_pointers = 0;
-       }
-
-       if (f->arg_index == f->argv->size) {
-               // first parse this arg
-               scf_vector_add(f->argv, arg);
-               scf_scope_push_var(f->scope, arg);
-
-       } else if (f->arg_index < f->argv->size) {
-               // check if same type
-               scf_variable_t* v = f->argv->data[f->arg_index];
-               if (v->type != arg->type || v->nb_pointers != arg->nb_pointers) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               // update the arg name
-               if (v->w) {
-                       scf_lex_word_free(v->w);
-                       v->w = NULL;
-               }
-               v->w = arg->w;
-               arg->w = NULL;
-       } else {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       if (SCF_LEX_WORD_COMMA == w2->type) {
-               scf_lex_word_free(w2);
-               w2 = NULL;
-               f->arg_index++;
-               return _parse_function_args(parse, f);
-
-       } else if (SCF_LEX_WORD_RP == w2->type) {
-               // end the argment list
-               scf_lex_word_free(w2);
-               w2 = NULL;
-               f->arg_index++;
-               if (f->arg_index != f->argv->size) {
-                       printf("%s(),%d, error: arg numbers not same: %d, %d\n", __func__, __LINE__,
-                                       f->arg_index, f->argv->size);
-                       return -1;
-               }
-               return 0;
-       }
-
-       printf("%s(),%d, error: \n", __func__, __LINE__);
-       return -1;
-}
-
-int _parse_function(scf_parse_t* parse, scf_lex_word_t* w0)
-{
-       printf("%s(),%d, ### start, current_block: %p\n", __func__, __LINE__, parse->ast->current_block);
-       scf_type_t* t = NULL;
-       scf_lex_word_t* w1 = NULL;
-
-       if (SCF_LEX_WORD_KEY_CHAR <= w0->type &&
-                       SCF_LEX_WORD_KEY_DOUBLE >= w0->type) {
-
-               t = scf_ast_find_type(parse->ast, w0->text->data);
-
-       } else if (SCF_LEX_WORD_KEY_STRUCT == w0->type) {
-               SCF_CHECK_LEX_POP_WORD(w1);
-
-               t = scf_ast_find_type(parse->ast, w1->text->data);
-               if (!t) {
-                       scf_lex_push_word(parse->lex, w1);
-                       w1 = NULL;
-                       return 0;
-               }
-       } else if (scf_lex_is_identity(w0)) {
-               t = scf_ast_find_type(parse->ast, w0->text->data);
-               if (!t) {
-                       scf_variable_t* v = scf_ast_find_variable(parse->ast, w0->text->data);
-                       if (!v) {
-                               scf_function_t* f = scf_ast_find_function(parse->ast, w0->text->data);
-                               if (!f) {
-                                       SCF_CHECK_LEX_POP_WORD(w1);
-                                       if (SCF_LEX_WORD_COLON != w1->type) {
-                                               printf("%s(),%d, error: \n", __func__, __LINE__);
-                                               return -1;
-                                       }
-
-                                       scf_lex_push_word(parse->lex, w1);
-                                       w1 = NULL;
-                               }
-                       }
-
-                       return 0;
-               }
-       } else {
-               return 0;
-       }
-
-       if (!t) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       assert(0 == t->nb_pointers);
-       scf_vector_t* vec = scf_vector_alloc();
-       scf_lex_word_t* w2 = NULL;
-
-       while (1) {
-               SCF_CHECK_LEX_POP_WORD(w2);
-               if (SCF_LEX_WORD_STAR == w2->type) {
-                       scf_vector_add(vec, w2);
-                       w2 = NULL;
-               } else {
-                       break;
-               }
-       }
-
-       assert(w2);
-
-       scf_lex_word_t* w3 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w3);
-
-       if (!scf_lex_is_identity(w2) || SCF_LEX_WORD_LP != w3->type) {
-               // push word back to lex, for other parse
-               scf_lex_push_word(parse->lex, w3);
-               w3 = NULL;
-
-               scf_lex_push_word(parse->lex, w2);
-               w2 = NULL;
-
-               int i;
-               for (i = 0; i < vec->size; i++) {
-                       scf_lex_word_t* w = vec->data[i];
-                       scf_lex_push_word(parse->lex, vec->data[i]);
-                       vec->data[i] = NULL;
-               }
-               scf_vector_free(vec);
-               vec = NULL;
-
-               if (w1) {
-                       scf_lex_push_word(parse->lex, w1);
-                       w1 = NULL;
-               }
-               return 0;
-       }
-
-       if (SCF_LEX_WORD_LP != w3->type) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_scope_t* current_scope = scf_ast_current_scope(parse->ast);
-       scf_function_t* f = scf_scope_find_function(current_scope, w2->text->data);
-       if (!f) {
-               printf("%s(),%d, ######## start, current_block: %p, f: %p, %s\n", __func__, __LINE__, parse->ast->current_block, f, w2->text->data);
-               f = scf_function_alloc(w2);
-               w2 = NULL;
-
-               t->nb_pointers = vec->size;
-               f->ret = scf_variable_alloc(w0, t);
-               w0 = NULL;
-               t->nb_pointers = 0;
-
-               scf_scope_push_function(current_scope, f);
-               printf("%s(),%d, ######## start, current_block: %p, f: %p\n", __func__, __LINE__, parse->ast->current_block, f);
-               scf_ast_push_block(parse->ast, (scf_block_t*)f);
-               printf("%s(),%d, ######## start, current_block: %p, f: %p\n", __func__, __LINE__, parse->ast->current_block, f);
-       } else {
-               assert(f->scope);
-               assert(!f->w_end);
-
-               if (f->ret->type != t->type || f->ret->nb_pointers != t->nb_pointers) {
-                       printf("%s(),%d, error: return value type not same: %s:%d, %s:%d\n",
-                                       __func__, __LINE__,
-                                       f->ret->w->text->data, f->ret->w->line,
-                                       t->w->text->data, t->w->line
-                                       );
-                       return -1;
-               }
-
-               parse->ast->current_block = (scf_block_t*)f;
-               printf("%s(),%d, ### start, current_block: %p, f: %p\n", __func__, __LINE__, parse->ast->current_block, f);
-       }
-
-       f->arg_index = 0;
-       if (_parse_function_args(parse, f) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       if (w1) {
-               scf_lex_word_free(w1);
-               w1 = NULL;
-       }
-
-       int i;
-       for (i = 0; i < vec->size; i++) {
-               scf_lex_word_free(vec->data[i]);
-               vec->data[i] = NULL;
-       }
-       scf_vector_free(vec);
-       vec = NULL;
-
-       if (_parse_function_body(parse, f) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       // return to the parent block of this function
-       scf_ast_pop_block(parse->ast);
-       return 1;
-}
-
-int _parse_return(scf_parse_t* parse, scf_lex_word_t* w0)
-{
-       assert(SCF_LEX_WORD_KEY_RETURN == w0->type);
-
-       scf_block_t* b = parse->ast->current_block;
-       while (b && SCF_FUNCTION != b->node.type) {
-               b = (scf_block_t*)b->node.parent;
-       }
-
-       if (!b) {
-               printf("%s(),%d, error: 'return' must be in a function, line: %d\n",
-                               __func__, __LINE__, w0->line);
-               return -1;
-       }
-       assert(SCF_FUNCTION == b->node.type);
-
-       scf_node_t* n = scf_node_alloc(w0, SCF_OP_RETURN, NULL);
-
-       scf_expr_t* e = scf_expr_alloc();
-       if (_parse_expr(parse, e) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       scf_node_add_child(n, e);
-
-       scf_node_add_child((scf_node_t*)parse->ast->current_block, n);
-       return 0;
-}
-
-int _parse_break(scf_parse_t* parse, scf_lex_word_t* w0)
-{
-       assert(SCF_LEX_WORD_KEY_BREAK == w0->type);
-
-       scf_block_t* b = parse->ast->current_block;
-
-       scf_node_t* _break = scf_node_alloc(w0, SCF_OP_BREAK, NULL);
-
-       printf("%s(),%d, b: %p, _break: %p\n", __func__, __LINE__, b, _break);
-
-       scf_node_add_child((scf_node_t*)b, _break);
-       return 0;
-}
-
-int _parse_continue(scf_parse_t* parse, scf_lex_word_t* w0)
-{
-       assert(SCF_LEX_WORD_KEY_CONTINUE == w0->type);
-
-       scf_node_t* _continue = scf_node_alloc(w0, SCF_OP_CONTINUE, NULL);
-
-       scf_node_add_child((scf_node_t*)parse->ast->current_block, _continue);
-       return 0;
-}
-
-int _parse_goto(scf_parse_t* parse, scf_lex_word_t* w0)
-{
-       assert(SCF_LEX_WORD_KEY_GOTO == w0->type);
-
-       printf("%s(),%d\n", __func__, __LINE__);
-
-       scf_block_t* b = parse->ast->current_block;
-       while (b && SCF_FUNCTION != b->node.type) {
-               b = (scf_block_t*)b->node.parent;
-       }
-
-       if (!b) {
-               printf("%s(),%d, error: '%s' must be in a function, line: %d\n",
-                               __func__, __LINE__, w0->text->data, w0->line);
-               return -1;
-       }
-       assert(SCF_FUNCTION == b->node.type);
-
-       scf_lex_word_t* w1 = NULL;
-       scf_lex_word_t* w2 = NULL;
-       SCF_CHECK_LEX_POP_WORD(w1);
-       SCF_CHECK_LEX_POP_WORD(w2);
-
-       if (!scf_lex_is_identity(w1)) {
-               printf("%s(),%d, error: '%s' is not a label\n", __func__, __LINE__, w1->text->data);
-               return -1;
-       }
-
-       if (w2->type != SCF_LEX_WORD_SEMICOLON) {
-               printf("%s(),%d, error: '%s' should be ';'\n", __func__, __LINE__, w2->text->data);
-               return -1;
-       }
-       scf_lex_word_free(w2);
-       w2 = NULL;
-
-       scf_label_t* l = scf_label_alloc(w1);
-       w1 = NULL;
-       scf_node_t* nl = scf_node_alloc_label(l);
-
-       scf_node_t* n = scf_node_alloc(w0, SCF_OP_GOTO, NULL);
-
-       scf_node_add_child(n, nl);
-
-       scf_node_add_child((scf_node_t*)parse->ast->current_block, n);
-       return 0;
-}
-
-int _parse_word(scf_parse_t* parse, scf_lex_word_t* w)
-{
-       if (SCF_LEX_WORD_SEMICOLON == w->type) {
-               scf_lex_word_free(w);
-               w = NULL;
-               return 0;
-       }
-
-       if ((SCF_LEX_WORD_KEY_CHAR <= w->type &&
-                       SCF_LEX_WORD_KEY_DOUBLE >= w->type)
-               || SCF_LEX_WORD_KEY_STRUCT == w->type
-               || scf_lex_is_identity(w)) {
-
-               int ret = _parse_function(parse, w);
-               if (ret < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               } else if (1 == ret) {
-                       printf("%s(),%d, ### parse function ok\n\n", __func__, __LINE__);
-                       return 0;
-               }
-               assert(0 == ret);
-       }
-
-       if (SCF_LEX_WORD_KEY_CHAR <= w->type &&
-                       SCF_LEX_WORD_KEY_DOUBLE >= w->type) {
-
-               scf_type_t* t = scf_ast_find_type(parse->ast, w->text->data);
-               if (!t) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               printf("%s(),%d, w: %s\n", __func__, __LINE__, w->text->data);
-
-               scf_lex_word_free(w);
-               w = NULL;
-
-               scf_scope_t* current_scope = scf_ast_current_scope(parse->ast);
-
-               if (_parse_var_declaration(parse, t, current_scope) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               return 0;
-       }
-
-       if (SCF_LEX_WORD_KEY_STRUCT == w->type) {
-               scf_lex_push_word(parse->lex, w);
-               w = NULL;
-
-               scf_scope_t* current_scope = scf_ast_current_scope(parse->ast);
-
-               if (_parse_struct_define(parse, current_scope) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               return 0;
-       }
-
-       if (SCF_LEX_WORD_KEY_IF == w->type) {
-               printf("%s(),%d, start '%s', line: %d\n", __func__, __LINE__, w->text->data, w->line);
-               scf_lex_push_word(parse->lex, w);
-               w = NULL;
-
-               scf_node_t* node = NULL;
-               if (_parse_if(parse, &node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               printf("%s(),%d, end n: %p\n", __func__, __LINE__, node);
-               printf("%s(),%d, end '%s', line: %d\n", __func__, __LINE__, node->w->text->data, node->w->line);
-               return 0;
-       }
-       if (SCF_LEX_WORD_KEY_WHILE == w->type) {
-               printf("%s(),%d, start '%s', line: %d\n", __func__, __LINE__, w->text->data, w->line);
-               scf_lex_push_word(parse->lex, w);
-               w = NULL;
-
-               scf_node_t* node = NULL;
-               if (_parse_while(parse, &node) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               printf("%s(),%d, end n: %p\n", __func__, __LINE__, node);
-               printf("%s(),%d, end '%s', line: %d\n", __func__, __LINE__, node->w->text->data, node->w->line);
-               return 0;
-       }
-
-       if (SCF_LEX_WORD_KEY_RETURN == w->type) {
-               printf("%s(),%d, start '%s', line: %d\n", __func__, __LINE__, w->text->data, w->line);
-               return _parse_return(parse, w);
-       }
-       if (SCF_LEX_WORD_KEY_BREAK == w->type) {
-               printf("%s(),%d, start '%s', line: %d\n", __func__, __LINE__, w->text->data, w->line);
-               return _parse_break(parse, w);
-       }
-       if (SCF_LEX_WORD_KEY_CONTINUE == w->type) {
-               printf("%s(),%d, start '%s', line: %d\n", __func__, __LINE__, w->text->data, w->line);
-               return _parse_continue(parse, w);
-       }
-       if (SCF_LEX_WORD_KEY_GOTO == w->type) {
-               printf("%s(),%d, start '%s', line: %d\n", __func__, __LINE__, w->text->data, w->line);
-               return _parse_goto(parse, w);
-       }
-
-       if (SCF_LEX_WORD_LB == w->type) {
-               scf_lex_push_word(parse->lex, w);
-               w = NULL;
-
-               return _parse_block(parse);
-       }
-
-       if (scf_lex_is_identity(w)) {
-               if (_parse_identity(parse, w) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-               return 0;
-       }
-
-       printf("%s(),%d, error: w: %d, '%s', w->line: %d, w->pos: %d\n", __func__, __LINE__, w->type, w->text->data, w->line, w->pos);
-       return -1;
-}
-
-int scf_parse_parse(scf_parse_t* parse)
-{
-       assert(parse);
-       assert(parse->lex);
-
-       while (1) {
-               scf_lex_word_t* w = NULL;
-
-               int ret = scf_lex_pop_word(parse->lex, &w);
-               if (ret < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-
-               if (SCF_LEX_WORD_EOF == w->type) {
-                       printf("%s(),%d, eof\n", __func__, __LINE__);
-                       scf_lex_push_word(parse->lex, w);
-                       w = NULL;
-                       break;
-               }
-
-               if (SCF_LEX_WORD_SPACE == w->type) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       assert(0); // it must not come here, already drop the SPACE in lex
-                       return -1;
-               }
-
-               if (_parse_word(parse, w) < 0) {
-                       printf("%s(),%d, error: \n", __func__, __LINE__);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-typedef struct {
-       char*                    fname;
-       int                              argc;
-       scf_variable_t** argv;
-} _find_function_arg_t;
-
-static void* _find_function(scf_node_t* node, void* arg, scf_vector_t* vec)
-{
-       _find_function_arg_t* farg = arg;
-
-       scf_block_t* b = (scf_block_t*)node;
-
-       if (SCF_OP_BLOCK == b->node.type) {
-               assert(b->scope);
-
-               scf_function_t* f = scf_scope_find_function(b->scope, farg->fname);
-
-               //printf("%s(),%d, fname: %s, f: %p\n", __func__, __LINE__,
-               //              fname, f);
-
-               if (f && farg->argc == f->argv->size) {
-
-               //      printf("%s(),%d, fname: %s, f: %p, argc: %d, f->argv->size: %d\n", __func__, __LINE__,
-               //                      fname, f, argc, f->argv->size);
-
-                       int i;
-                       for (i = 0; i < farg->argc; i++) {
-                               scf_variable_t* v = f->argv->data[i];
-                               if (farg->argv[i]->type != v->type) {
-                                       break;
-                               }
-                       }
-
-                       if (farg->argc == i) {
-                               return (void*)f;
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-int scf_parse_run(scf_parse_t* parse, const char* fname, const int argc, const scf_variable_t** argv, scf_variable_t** pret)
-{
-       scf_block_t* b = parse->ast->root_block;
-       if (!b) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-       printf("%s(),%d, fname: %s\n", __func__, __LINE__, fname);
-
-       _find_function_arg_t arg;
-       arg.fname       = (char*)fname;
-       arg.argc        = argc;
-       arg.argv        = (scf_variable_t**)argv;
-
-       scf_function_t* f = (scf_function_t*) scf_node_search_bfs((scf_node_t*)b, _find_function, &arg, NULL);
-       if (!f) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-       printf("%s(),%d, \n\n", __func__, __LINE__);
-
-       if (scf_function_semantic_analysis(parse->ast, f) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       printf("%s(),%d, \n\n", __func__, __LINE__);
-       if (scf_function_to_3ac(parse->ast, f, &parse->code_list_head) < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       printf("%s(),%d, run function ok: f: %p, fname: %s\n\n", __func__, __LINE__, f, fname);
-
-#if 1
-       scf_3ac_context_t* _3ac_ctx = scf_3ac_context_alloc();
-       scf_3ac_filter(_3ac_ctx, NULL, &parse->code_list_head);
-#endif
-
-       printf("%s(),%d, \n\n", __func__, __LINE__);
-#if 1
-       scf_native_context_t* native_ctx = NULL;
-       if (scf_native_open(&native_ctx, "x64") < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-
-       int ret = scf_native_select_instruction(native_ctx, &parse->code_list_head, f);
-       if (ret < 0) {
-               printf("%s(),%d, error: \n", __func__, __LINE__);
-               return -1;
-       }
-#endif
-       printf("%s(),%d, \n\n", __func__, __LINE__);
-       return 0;
-}
-
index 9243057c3e78d43b838643751d562c194f3525b2..d4dd534e0ee5057b6dd3a736516edd18de54bb0d 100644 (file)
@@ -618,7 +618,7 @@ int scf_rbtree_depth(scf_rbtree_t* tree, scf_rbtree_node_t* root)
        return 0;
 }
 
-#if 1
+#if 0
 typedef struct {
        scf_rbtree_node_t  node;
        int d;