support 'switch-case' & delete some unused code
authoryu.dongliang <18588496441@163.com>
Fri, 12 Apr 2024 12:08:30 +0000 (20:08 +0800)
committeryu.dongliang <18588496441@163.com>
Fri, 12 Apr 2024 12:08:30 +0000 (20:08 +0800)
38 files changed:
core/scf_3ac.c
core/scf_3ac.h
core/scf_core_types.h
core/scf_lex_word.h
core/scf_operator.c
core/scf_operator_handler.h
core/scf_operator_handler_3ac.c
core/scf_optimizer_loop.c
docs/Naja_float.txt [new file with mode: 0644]
docs/Naja_int.txt [new file with mode: 0644]
examples/switch_case.c [new file with mode: 0644]
lex/scf_lex.c
parse/Makefile
parse/scf_dfa.c
parse/scf_dfa_block.c
parse/scf_dfa_class.c
parse/scf_dfa_do.c [new file with mode: 0644]
parse/scf_dfa_error.c [deleted file]
parse/scf_dfa_for.c
parse/scf_dfa_function.c
parse/scf_dfa_goto.c
parse/scf_dfa_if.c
parse/scf_dfa_include.c
parse/scf_dfa_label.c
parse/scf_dfa_operator.c
parse/scf_dfa_parse.c
parse/scf_dfa_repeat.c [deleted file]
parse/scf_dfa_return.c
parse/scf_dfa_struct.c [deleted file]
parse/scf_dfa_switch.c [new file with mode: 0644]
parse/scf_dfa_util.h
parse/scf_dfa_var.c
parse/scf_dfa_while.c
parse/scf_operator_handler_const.c
parse/scf_operator_handler_expr.c
parse/scf_operator_handler_semantic.c
parse/scf_parse.c
parse/scf_rbtree.c [deleted file]

index e15270cea4f9409788c09fc48069636e5f08404e..f7f993fcbee9e59f42c0a372067cc83685dd7294 100644 (file)
@@ -414,7 +414,7 @@ scf_3ac_code_t* scf_3ac_alloc_by_dst(int op_type, scf_dag_node_t* dst)
        return c;
 }
 
-scf_3ac_code_t* scf_branch_ops_code(int type, scf_label_t* l, scf_node_t* err)
+scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err)
 {
        scf_3ac_operand_t* dst;
        scf_3ac_code_t*    c;
index a1c0b09e7c7b6c05fdf90f2d16cadc88090aa49a..406eacc51d07e5990dd552631bcea702b2630b60 100644 (file)
@@ -61,7 +61,7 @@ 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_code_t*     scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err);
 
 scf_3ac_operator_t*    scf_3ac_find_operator(const int type);
 
@@ -76,4 +76,3 @@ int                                   scf_3ac_split_basic_blocks(scf_list_t* list_head_3ac, scf_function_t* f)
 int                 scf_3ac_code_same(scf_3ac_code_t* c0, scf_3ac_code_t* c1);
 
 #endif
-
index 100bbc6ad1f3e67a9c5261499844ce703c12fe1f..7326090d99807afadbc9dbd28f9b86359d46c4a9 100644 (file)
@@ -104,12 +104,16 @@ enum scf_core_types {
        SCF_OP_IF,                      // if statement
        SCF_OP_FOR,                     // for statement
        SCF_OP_WHILE,           // while statement
-       SCF_OP_REPEAT,      // repeat statement
+       SCF_OP_DO,          // do statement
+
+       SCF_OP_SWITCH,      // switch-case statement
+       SCF_OP_CASE,
+       SCF_OP_DEFAULT,
+
        SCF_OP_RETURN,          // return statement
        SCF_OP_BREAK,           // break statement
        SCF_OP_CONTINUE,        // continue statement
        SCF_OP_ASYNC,       // async statement
-       SCF_OP_ERROR,       // error statement
        SCF_OP_INCLUDE,     // include statement
 
        // 58
index c25212b4c2e9c502f6f245e1d9c2ee8dd1e491d3..44061f7273b27eaac70231ccba22b1d0224b790a 100644 (file)
@@ -102,7 +102,6 @@ enum scf_lex_words {
        SCF_LEX_WORD_KEY_RETURN,        // return
 
        SCF_LEX_WORD_KEY_GOTO,          // goto
-       SCF_LEX_WORD_KEY_ERROR,     // error
 
        SCF_LEX_WORD_KEY_SIZEOF,    // sizeof
 
index 68412dcec2f0bd94685e7e34d0a565bf6595a38d..f94eb875a8a5fc450eb82794ddcaa0a5066202d2 100644 (file)
@@ -70,12 +70,15 @@ static scf_operator_t       base_operators[] = {
        {SCF_OP_CONTINUE,       "continue",  15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
        {SCF_OP_GOTO,           "goto",      15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
        {SCF_LABEL,             "label",     15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
-       {SCF_OP_ERROR,          "error",     15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
 
        {SCF_OP_IF,             "if",        15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
        {SCF_OP_WHILE,          "while",     15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
-       {SCF_OP_REPEAT,         "repeat",    15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
+       {SCF_OP_DO,             "do",        15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
        {SCF_OP_FOR,            "for",       15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
+
+       {SCF_OP_SWITCH,         "switch",    15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
+       {SCF_OP_CASE,           "case",      15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
+       {SCF_OP_DEFAULT,        "default",   15, -1,  SCF_OP_ASSOCIATIVITY_LEFT},
 };
 
 scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands)
index acca5109a1e184d8e0bca089a94bd66a0cd628d1..a545e41d73ad2de7a5ebaf377c4f988bc984691e 100644 (file)
@@ -7,22 +7,14 @@ typedef struct scf_operator_handler_s scf_operator_handler_t;
 
 typedef int    (*scf_operator_handler_pt)(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data);
 
-struct scf_operator_handler_s {
-
-       scf_list_t                              list;
-
+struct scf_operator_handler_s
+{
        int                                             type;
-
        scf_operator_handler_pt func;
 };
 
-scf_operator_handler_t* scf_operator_handler_alloc(int type, scf_operator_handler_pt func);
-
-void scf_operator_handler_free(scf_operator_handler_t* h);
-
 scf_operator_handler_t* scf_find_3ac_operator_handler(const int type);
 
 int scf_function_to_3ac(scf_ast_t* ast, scf_function_t* f, scf_list_t* _3ac_list_head);
 
 #endif
-
index bcc4c7dd8534310d09d03d3d5f680f68e36d0ae8..822265fade16feb1dab8ed692f649a63a4ad86f0 100644 (file)
@@ -7,7 +7,6 @@ typedef struct {
        scf_vector_t*   _continues;
        scf_vector_t*   _gotos;
        scf_vector_t*   _labels;
-       scf_vector_t*   _errors;
        scf_vector_t*   _ends;
 } scf_branch_ops_t;
 
@@ -20,14 +19,14 @@ typedef struct {
 scf_branch_ops_t* scf_branch_ops_alloc()
 {
        scf_branch_ops_t* branch_ops = calloc(1, sizeof(scf_branch_ops_t));
-       assert(branch_ops);
 
-       branch_ops->_breaks             = scf_vector_alloc();
-       branch_ops->_continues  = scf_vector_alloc();
-       branch_ops->_gotos              = scf_vector_alloc();
-       branch_ops->_labels     = scf_vector_alloc();
-       branch_ops->_errors     = scf_vector_alloc();
-       branch_ops->_ends       = scf_vector_alloc();
+       if (branch_ops) {
+               branch_ops->_breaks             = scf_vector_alloc();
+               branch_ops->_continues  = scf_vector_alloc();
+               branch_ops->_gotos              = scf_vector_alloc();
+               branch_ops->_labels     = scf_vector_alloc();
+               branch_ops->_ends       = scf_vector_alloc();
+       }
 
        return branch_ops;
 }
@@ -39,7 +38,6 @@ void scf_branch_ops_free(scf_branch_ops_t* branch_ops)
                scf_vector_free(branch_ops->_continues);
                scf_vector_free(branch_ops->_gotos);
                scf_vector_free(branch_ops->_labels);
-               scf_vector_free(branch_ops->_errors);
                scf_vector_free(branch_ops->_ends);
 
                free(branch_ops);
@@ -49,20 +47,19 @@ void scf_branch_ops_free(scf_branch_ops_t* branch_ops)
 
 static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void* data)
 {
-       if (!node) {
+       if (!node)
                return 0;
-       }
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t*     d = data;
+       scf_operator_handler_t* h;
+
+       int i;
 
        if (0 == node->nb_nodes) {
-               if (scf_type_is_var(node->type) && node->var->w) {
+               if (scf_type_is_var(node->type) && node->var->w)
                        scf_logd("node->var->w->text->data: %s\n", node->var->w->text->data);
-               }
 
-               assert(scf_type_is_var(node->type)
-                               || SCF_LABEL == node->type
-                               || node->split_flag);
+               assert(scf_type_is_var(node->type) || SCF_LABEL == node->type || node->split_flag);
                return 0;
        }
 
@@ -78,15 +75,10 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void*
                return 0;
        node->_3ac_done = 1;
 
-       if (node->w)
-               scf_logd("node: %p, node->w->text->data: %s\n", node, node->w->text->data);
-
        if (SCF_OP_ASSOCIATIVITY_LEFT == node->op->associativity) {
-               // left associativity
-               scf_logd("left associativity\n");
 
                if (SCF_OP_LOGIC_AND != node->op->type && SCF_OP_LOGIC_OR != node->op->type) {
-                       int i;
+
                        for (i = 0; i < node->nb_nodes; i++) {
                                if (_scf_expr_calculate_internal(ast, node->nodes[i], d) < 0) {
                                        scf_loge("\n");
@@ -95,26 +87,17 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void*
                        }
                }
 
-               scf_operator_handler_t* h = scf_find_3ac_operator_handler(node->op->type);
+               h = scf_find_3ac_operator_handler(node->op->type);
                if (!h) {
                        scf_loge("\n");
                        return -1;
                }
 
-               int ret = h->func(ast, node->nodes, node->nb_nodes, d);
+               return h->func(ast, node->nodes, node->nb_nodes, d);
 
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return -1;
-               }
-               return 0;
        } else {
-               // right associativity
-               scf_logd("right associativity\n");
+               if (!scf_type_is_assign(node->op->type) && SCF_OP_ADDRESS_OF != node->op->type) {
 
-               if (!scf_type_is_assign(node->op->type)
-                               && SCF_OP_ADDRESS_OF != node->op->type) {
-                       int i;
                        for (i = node->nb_nodes - 1; i >= 0; i--) {
                                if (_scf_expr_calculate_internal(ast, node->nodes[i], d) < 0) {
                                        scf_loge("\n");
@@ -123,19 +106,13 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void*
                        }
                }
 
-               scf_operator_handler_t* h = scf_find_3ac_operator_handler(node->op->type);
+               h = scf_find_3ac_operator_handler(node->op->type);
                if (!h) {
                        scf_loge("op->type: %d, name: '%s'\n", node->op->type, node->op->name);
                        return -1;
                }
 
-               int ret = h->func(ast, node->nodes, node->nb_nodes, d);
-
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return -1;
-               }
-               return 0;
+               return h->func(ast, node->nodes, node->nb_nodes, d);
        }
 
        scf_loge("\n");
@@ -151,9 +128,8 @@ static int _scf_expr_calculate(scf_ast_t* ast, scf_expr_t* e, void* data)
 
        scf_node_t* root = e->nodes[0];
 
-       if (scf_type_is_var(root->type)) {
+       if (scf_type_is_var(root->type))
                return 0;
-       }
 
        if (_scf_expr_calculate_internal(ast, root, d) < 0) {
                scf_loge("\n");
@@ -395,29 +371,25 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
        if (0 == nb_nodes)
                return 0;
 
-       scf_handler_data_t* d = data;
-
-       scf_block_t* b = (scf_block_t*)(nodes[0]->parent);
+       scf_operator_handler_t* h;
+       scf_operator_t*         op;
+       scf_handler_data_t*     d  = data;
+       scf_block_t*            b  = (scf_block_t*)(nodes[0]->parent);
+       scf_block_t*            up = ast->current_block;
+       scf_node_t*             node;
 
        if (b->node._3ac_done)
                return 0;
 
-       scf_block_t* prev_block = ast->current_block;
        ast->current_block = b;
 
-       int i = 0;
-       while (i < nb_nodes) {
-               scf_node_t* node = nodes[i];
-               scf_operator_t* op = node->op;
-               scf_logd("node: %p, type: %d, i: %d, nb_nodes: %d\n", node, node->type, i, nb_nodes);
+       int i;
+       int j;
 
-               if (SCF_LABEL == node->type) {
-                       scf_logd("node: %p, w: %s, line:%d\n", node, node->label->w->text->data, node->label->w->line);
-               } else if (scf_type_is_var(node->type)) {
-                       scf_logd("node: %p, w: %s, line:%d\n", node, node->var->w->text->data, node->var->w->line);
-               } else if (node->w) {
-                       scf_logd("node: %p, w: %s, line:%d\n", node, node->w->text->data, node->w->line);
-               }
+       for (i = 0; i < nb_nodes; i++) {
+
+               node = nodes[i];
+               op   = node->op;
 
                if (!op) {
                        op = scf_find_base_operator_by_type(node->type);
@@ -427,7 +399,7 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
                        }
                }
 
-               scf_operator_handler_t* h = scf_find_3ac_operator_handler(op->type);
+               h = scf_find_3ac_operator_handler(op->type);
                if (!h) {
                        scf_loge("\n");
                        return -1;
@@ -435,16 +407,18 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
 
                if (h->func(ast, node->nodes, node->nb_nodes, d) < 0) {
                        scf_loge("\n");
-                       ast->current_block = prev_block;
+                       ast->current_block = up;
                        return -1;
                }
 
                // for goto
                if (SCF_LABEL == node->type) {
-                       scf_label_t* l = node->label;
 
-                       scf_list_t*     tail = scf_list_tail(d->_3ac_list_head);
-                       scf_3ac_code_t* end  = scf_list_data(tail, scf_3ac_code_t, list);
+                       scf_label_t*       l    = node->label;
+                       scf_list_t*        tail = scf_list_tail(d->_3ac_list_head);
+                       scf_3ac_code_t*    end  = scf_list_data(tail, scf_3ac_code_t, list);
+                       scf_3ac_code_t*    c;
+                       scf_3ac_operand_t* dst;
 
                        if (scf_vector_add(d->branch_ops->_labels, end) < 0) {
                                scf_loge("\n");
@@ -454,28 +428,23 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
 
                        int j;
                        for (j = 0; j < d->branch_ops->_gotos->size; j++) {
+                               c  =        d->branch_ops->_gotos->data[j];
 
-                               scf_3ac_code_t* c = d->branch_ops->_gotos->data[j];
                                if (!c)
                                        continue;
 
                                assert(l->w);
                                assert(c->label->w);
 
-                               scf_logi("l: %s, c->label: %s\n", l->w->text->data, c->label->w->text->data);
-
                                if (!strcmp(l->w->text->data, c->label->w->text->data)) {
-                                       scf_logi("j: %d\n", j);
-                                       scf_3ac_operand_t* dst = c->dsts->data[0];
+                                       dst       = c->dsts->data[0];
                                        dst->code = end;
                                }
                        }
                }
-
-               i++;
        }
 
-       ast->current_block = prev_block;
+       ast->current_block = up;
        return 0;
 }
 
@@ -518,7 +487,7 @@ static int _scf_op_return(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
                        return -1;
        }
 
-       scf_3ac_code_t* end = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL);
+       scf_3ac_code_t* end = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
 
        scf_list_add_tail(d->_3ac_list_head, &end->list);
 
@@ -527,56 +496,51 @@ static int _scf_op_return(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
 
 static int _scf_op_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
-       scf_handler_data_t* d = data;
-
-       scf_node_t* n = (scf_node_t*)ast->current_block;
+       scf_handler_data_t* d  = data;
+       scf_node_t*         up = (scf_node_t*)ast->current_block;
 
-       while (n
-                       && SCF_OP_WHILE  != n->type
-                       && SCF_OP_REPEAT != n->type
-                       && SCF_OP_FOR    != n->type)
-               n = n->parent;
+       while (up
+                       && SCF_OP_WHILE  != up->type
+                       && SCF_OP_DO     != up->type
+                       && SCF_OP_FOR    != up->type
+                       && SCF_OP_SWITCH != up->type)
+               up = up->parent;
 
-       if (!n) {
+       if (!up) {
                scf_loge("\n");
                return -1;
        }
-       assert(SCF_OP_WHILE == n->type || SCF_OP_FOR == n->type || SCF_OP_REPEAT == n->type);
 
-       scf_node_t* parent = n->parent;
-       assert(parent);
+       scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
 
-       scf_3ac_code_t* branch = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL);
-
-       scf_list_add_tail(d->_3ac_list_head, &branch->list);
+       scf_list_add_tail(d->_3ac_list_head, &jmp->list);
 
-       scf_vector_add(d->branch_ops->_breaks, branch);
+       scf_vector_add(d->branch_ops->_breaks, jmp);
        return 0;
 }
 
 static int _scf_op_continue(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
-       scf_handler_data_t* d = data;
-
-       scf_node_t* n = (scf_node_t*)ast->current_block;
+       scf_handler_data_t* d  = data;
+       scf_node_t*         up = (scf_node_t*)ast->current_block;
 
-       while (n
-                       && SCF_OP_WHILE  != n->type
-                       && SCF_OP_REPEAT != n->type
-                       && SCF_OP_FOR    != n->type)
-               n = n->parent;
+       while (up
+                       && SCF_OP_WHILE  != up->type
+                       && SCF_OP_DO     != up->type
+                       && SCF_OP_FOR    != up->type
+                       && SCF_OP_SWITCH != up->type)
+               up = up->parent;
 
-       if (!n) {
+       if (!up) {
                scf_loge("\n");
                return -1;
        }
-       assert(SCF_OP_WHILE == n->type || SCF_OP_FOR == n->type || SCF_OP_REPEAT == n->type);
 
-       scf_3ac_code_t* branch = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL);
+       scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
 
-       scf_list_add_tail(d->_3ac_list_head, &branch->list);
+       scf_list_add_tail(d->_3ac_list_head, &jmp->list);
 
-       scf_vector_add(d->branch_ops->_continues, branch);
+       scf_vector_add(d->branch_ops->_continues, jmp);
        return 0;
 }
 
@@ -589,95 +553,31 @@ static int _scf_op_goto(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d  = data;
+       scf_node_t*         nl = nodes[0];
+       scf_label_t*        l  = nl->label;
 
-       scf_node_t* nl = nodes[0];
        assert(SCF_LABEL == nl->type);
-
-       scf_label_t* l = nl->label;
        assert(l->w);
 
        scf_3ac_operand_t* dst;
-       scf_3ac_code_t*    branch = scf_branch_ops_code(SCF_OP_GOTO, l, NULL);
-       scf_list_add_tail(d->_3ac_list_head, &branch->list);
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    jmp = scf_3ac_jmp_code(SCF_OP_GOTO, l, NULL);
+
+       scf_list_add_tail(d->_3ac_list_head, &jmp->list);
 
        int i;
        for (i = 0; i < d->branch_ops->_labels->size; i++) {
-               scf_3ac_code_t* c = d->branch_ops->_labels->data[i];
+               c  =        d->branch_ops->_labels->data[i];
 
                if (!strcmp(l->w->text->data, c->label->w->text->data)) {
-                       dst = branch->dsts->data[0];
+                       dst = jmp->dsts->data[0];
                        dst->code = c;
                        break;
                }
        }
 
-       scf_vector_add(d->branch_ops->_gotos, branch);
-       return 0;
-}
-
-static int _scf_op_error(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
-{
-       assert(nb_nodes >= 3);
-
-       scf_handler_data_t* d = data;
-
-       scf_expr_t* e      = nodes[0];
-       scf_node_t* parent = e->parent;
-       int ret;
-       int i;
-
-       if (_scf_expr_calculate(ast, e, d) < 0) {
-               scf_loge("\n");
-               return -1;
-       }
-
-       if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_TEQ, e->nodes[0]) < 0) {
-               scf_loge("\n");
-               return -1;
-       }
-
-       scf_3ac_operand_t* dst;
-       scf_3ac_code_t*    je   = scf_branch_ops_code(SCF_OP_3AC_JZ,  NULL, parent);
-       scf_3ac_code_t*    jmp  = scf_branch_ops_code(SCF_OP_GOTO,    NULL, parent);
-       scf_list_add_tail(d->_3ac_list_head, &je->list);
-
-       // print log if needs
-       if (nb_nodes > 3) {
-               scf_vector_t* argv = scf_vector_alloc();
-
-               for (i = 3; i < nb_nodes; i++) {
-
-                       e   = nodes[i];
-                       ret = _scf_expr_calculate(ast, e, d);
-                       SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n");
-
-                       scf_vector_add(argv, e->nodes[0]);
-               }
-
-               //ret = _scf_3ac_call_extern(d->_3ac_list_head, "printf", parent, (scf_node_t**)argv->data, argv->size);
-               scf_vector_free(argv);
-               argv = NULL;
-               SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n");
-       }
-
-       // calculate error code to return
-       e   = nodes[2];
-       ret = _scf_expr_calculate(ast, e, d);
-       SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n");
-
-       // push error code to stack, and we will pop & return it when exit this function
-       _scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_PUSH, e->nodes[0]);
-
-       // set the 'je' destination (code when no error happens)
-       dst = je->dsts->data[0];
-       dst->code = jmp;
-
-       // add 'jmp' to code list & error branches, it will be re-filled when this function end
-       scf_list_add_tail(d->_3ac_list_head, &jmp->list);
-       scf_vector_add(d->branch_ops->_errors, jmp);
-       scf_vector_add(d->branch_ops->_errors, je); // 'je' will re-fill too.
-
+       scf_vector_add(d->branch_ops->_gotos, jmp);
        return 0;
 }
 
@@ -836,7 +736,7 @@ static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da
        }
 
        scf_3ac_operand_t* dst;
-       scf_3ac_code_t*    jmp_else  = scf_branch_ops_code(jmp_op, NULL, NULL);
+       scf_3ac_code_t*    jmp_else  = scf_3ac_jmp_code(jmp_op, NULL, NULL);
        scf_3ac_code_t*    jmp_endif = NULL;
        scf_list_t*        l;
 
@@ -853,7 +753,7 @@ static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da
 
                if (1 == i) {
                        if (3 == nb_nodes) {
-                               jmp_endif = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL);
+                               jmp_endif = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
                                scf_list_add_tail(d->_3ac_list_head, &jmp_endif->list);
                        }
 
@@ -890,15 +790,18 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
        // for optimizer
 
        // copy cond expr
-       scf_list_t* l;
-       scf_list_t* l2;
-       scf_list_t* cond_prev = scf_list_tail(d->_3ac_list_head);
+       scf_3ac_operand_t* dst;
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    c2;
 
-       for (l = scf_list_next(start_prev); l != &jmp_end->list; l = scf_list_next(l)) {
+       scf_list_t*        l;
+       scf_list_t*        l2;
+       scf_list_t*        cond_prev = scf_list_tail(d->_3ac_list_head);
 
-               scf_3ac_code_t* c  = scf_list_data(l, scf_3ac_code_t, list);
+       for (l = scf_list_next(start_prev); l != &jmp_end->list; l = scf_list_next(l)) {
+               c  = scf_list_data(l, scf_3ac_code_t, list);
 
-               scf_3ac_code_t* c2 = scf_3ac_code_clone(c);
+               c2 = scf_3ac_code_clone(c);
                if (!c2)
                        return -ENOMEM;
 
@@ -906,16 +809,15 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
        }
 
        for (l = scf_list_next(cond_prev); l != scf_list_sentinel(d->_3ac_list_head); l = scf_list_next(l)) {
-
-               scf_3ac_code_t* c  = scf_list_data(l, scf_3ac_code_t, list);
+               c  = scf_list_data(l, scf_3ac_code_t, list);
 
                if (!scf_type_is_jmp(c->op->type))
                        continue;
 
                for (l2 = scf_list_next(cond_prev); l2 != scf_list_sentinel(d->_3ac_list_head); l2 = scf_list_next(l2)) {
+                       c2  = scf_list_data(l2, scf_3ac_code_t, list);
 
-                       scf_3ac_code_t*    c2  = scf_list_data(l2, scf_3ac_code_t, list);
-                       scf_3ac_operand_t* dst = c->dsts->data[0];
+                       dst = c->dsts->data[0];
 
                        if (dst->code == c2->origin) {
                                dst->code =  c2;
@@ -970,25 +872,25 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
        };
 
        // add loop when true
-       scf_3ac_code_t* loop = scf_branch_ops_code(jmp_op, NULL, NULL);
+       scf_3ac_code_t* loop = scf_3ac_jmp_code(jmp_op, NULL, NULL);
        scf_list_add_tail(d->_3ac_list_head, &loop->list);
 
        // should get the real start here,
-       scf_3ac_code_t*    start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list);
-       scf_3ac_operand_t* dst   = loop->dsts->data[0];
+       scf_3ac_code_t* start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list);
+
+       dst       = loop->dsts->data[0];
        dst->code = start;
 
        // set jmp destination for 'continue',
        // it's the 'real' dst & needs not to re-fill
-       scf_3ac_code_t*    branch = NULL;
 
        int i;
        for (i = 0; i < d->branch_ops->_continues->size; i++) {
-               branch    = d->branch_ops->_continues->data[i];
+               c  =        d->branch_ops->_continues->data[i];
 
-               assert(branch->dsts);
+               assert(c->dsts);
 
-               dst = branch->dsts->data[0];
+               dst = c->dsts->data[0];
                assert(!dst->code);
 
                /* 'continue' will goto 'while' and re-check the condition.
@@ -1012,11 +914,11 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
        scf_3ac_code_t* end_prev  = scf_list_data(scf_list_tail(d->_3ac_list_head), scf_3ac_code_t, list);
 
        for (i = 0; i < d->branch_ops->_breaks->size; i++) {
-               branch    = d->branch_ops->_breaks->data[i];
+               c  =        d->branch_ops->_breaks->data[i];
 
-               assert(branch->dsts);
+               assert(c->dsts);
 
-               dst = branch->dsts->data[0];
+               dst = c->dsts->data[0];
 
                if (!dst->code)
                        dst->code = end_prev;
@@ -1029,10 +931,9 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
 
        if (up_branch_ops) {
                for (i = 0; i < d->branch_ops->_breaks->size; i++) {
-                       branch    = d->branch_ops->_breaks->data[i];
-                       assert(branch);
+                       c  =        d->branch_ops->_breaks->data[i];
 
-                       if (scf_vector_add(up_branch_ops->_breaks, branch) < 0)
+                       if (scf_vector_add(up_branch_ops->_breaks, c) < 0)
                                return -1;
                }
 
@@ -1042,26 +943,16 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
                }
 
                for (i = 0; i < d->branch_ops->_gotos->size; i++) {
-                       branch    = d->branch_ops->_gotos->data[i];
-                       assert(branch);
+                       c  =        d->branch_ops->_gotos->data[i];
 
-                       if (scf_vector_add(up_branch_ops->_gotos, branch) < 0)
-                               return -1;
-               }
-
-               for (i = 0; i < d->branch_ops->_errors->size; i++) {
-                       branch    = d->branch_ops->_errors->data[i];
-                       assert(branch);
-
-                       if (scf_vector_add(up_branch_ops->_errors, branch) < 0)
+                       if (scf_vector_add(up_branch_ops->_gotos, c) < 0)
                                return -1;
                }
 
                for (i = 0; i < d->branch_ops->_ends->size; i++) {
-                       branch    = d->branch_ops->_ends->data[i];
-                       assert(branch);
+                       c  =        d->branch_ops->_ends->data[i];
 
-                       if (scf_vector_add(up_branch_ops->_ends, branch) < 0)
+                       if (scf_vector_add(up_branch_ops->_ends, c) < 0)
                                return -1;
                }
        }
@@ -1069,7 +960,7 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s
        return 0;
 }
 
-static int _scf_op_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+static int _scf_op_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(2 == nb_nodes);
 
@@ -1088,7 +979,7 @@ static int _scf_op_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
 
        scf_list_t*     l;
        scf_3ac_code_t* c;
-       scf_3ac_code_t* jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL);
+       scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL);
 
        scf_list_add_tail(d->_3ac_list_head, &jmp_end->list);
 
@@ -1134,8 +1025,8 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
        assert(2 == nb_nodes || 1 == nb_nodes);
 
        scf_handler_data_t* d = data;
+       scf_expr_t*         e = nodes[0];
 
-       scf_expr_t* e = nodes[0];
        assert(SCF_OP_EXPR == e->type);
 
        // we don't know the real start of the while loop here,
@@ -1148,7 +1039,7 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
                return -1;
        }
 
-       scf_3ac_code_t* jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL);
+       scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL);
        scf_list_add_tail(d->_3ac_list_head, &jmp_end->list);
 
        scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc();
@@ -1174,6 +1065,141 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
        return 0;
 }
 
+static int _scf_op_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       return 0;
+}
+
+static int _scf_op_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       return 0;
+}
+
+static int _scf_op_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       assert(2 == nb_nodes);
+
+       scf_handler_data_t* d = data;
+       scf_expr_t*         e = nodes[0];
+       scf_node_t*         b = nodes[1];
+
+       assert(SCF_OP_EXPR == e->type);
+
+       while (e && SCF_OP_EXPR == e->type)
+               e = e->nodes[0];
+
+       if (_scf_expr_calculate_internal(ast, e, d) < 0) {
+               scf_loge("\n");
+               return -1;
+       }
+
+       scf_branch_ops_t* up_branch_ops = d->branch_ops;
+       scf_block_t*      up            = ast->current_block;
+
+       d->branch_ops      = scf_branch_ops_alloc();
+       ast->current_block = (scf_block_t*)b;
+
+       scf_3ac_operand_t* dst;
+       scf_3ac_code_t*    cmp;
+       scf_3ac_code_t*    end;
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    jnot  = NULL;
+       scf_3ac_code_t*    jnext = NULL;
+
+       scf_node_t*        child;
+       scf_expr_t*        e2;
+       scf_list_t*        l;
+
+       int i;
+       for (i = 0; i < b->nb_nodes; i++) {
+               child     = b->nodes[i];
+
+               if (SCF_OP_CASE == child->type || SCF_OP_DEFAULT == child->type) {
+
+                       if (jnot) {
+                               jnext = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
+
+                               scf_list_add_tail(d->_3ac_list_head, &jnext->list);
+                               scf_vector_add(up_branch_ops->_breaks, jnext);
+
+                               dst       = jnot->dsts->data[0];
+                               dst->code = jnext;
+                               jnot      = NULL;
+                       }
+
+                       if (SCF_OP_CASE == child->type) {
+
+                               e2 = child->nodes[0];
+                               assert(SCF_OP_EXPR == e2->type);
+
+                               while (e2 && SCF_OP_EXPR == e2->type)
+                                       e2 = e2->nodes[0];
+
+                               if (_scf_expr_calculate_internal(ast, e2, d) < 0) {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
+
+                               scf_node_t* srcs[2] = {e, e2};
+
+                               cmp  = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
+                               jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL);
+
+                               scf_list_add_tail(d->_3ac_list_head, &cmp->list);
+                               scf_list_add_tail(d->_3ac_list_head, &jnot->list);
+
+                               scf_vector_add(up_branch_ops->_breaks, jnot);
+                       }
+
+                       if (jnext) {
+                               l         = scf_list_tail(d->_3ac_list_head);
+                               dst       = jnext->dsts->data[0];
+                               dst->code = scf_list_data(l, scf_3ac_code_t, list);
+                               jnext     = NULL;
+                       }
+
+               } else {
+                       if (_scf_op_node(ast, child, d) < 0) {
+                               scf_loge("\n");
+                               return -1;
+                       }
+               }
+       }
+
+       l   = scf_list_tail(d->_3ac_list_head);
+       end = scf_list_data(l, scf_3ac_code_t, list);
+
+       for (i = 0; i < d->branch_ops->_breaks->size; i++) {
+               c  =        d->branch_ops->_breaks->data[i];
+
+               dst = c->dsts->data[0];
+               if (!dst->code)
+                       dst->code = end;
+
+               if (scf_vector_add(up_branch_ops->_breaks, c) < 0)
+                       return -1;
+       }
+
+       for (i = 0; i < d->branch_ops->_gotos->size; i++) {
+               c  =        d->branch_ops->_gotos->data[i];
+
+               if (scf_vector_add(up_branch_ops->_gotos, c) < 0)
+                       return -1;
+       }
+
+       for (i = 0; i < d->branch_ops->_ends->size; i++) {
+               c         = d->branch_ops->_ends->data[i];
+
+               if (scf_vector_add(up_branch_ops->_ends, c) < 0)
+                       return -1;
+       }
+
+       scf_branch_ops_free(d->branch_ops);
+       d->branch_ops      = up_branch_ops;
+       ast->current_block = up;
+       return 0;
+}
+
 static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(4 == nb_nodes);
@@ -1199,7 +1225,7 @@ static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d
                        return -1;
                }
 
-               jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL);
+               jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL);
                scf_list_add_tail(d->_3ac_list_head, &jmp_end->list);
        }
 
@@ -1234,81 +1260,38 @@ static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d
        return 0;
 }
 
-static int _scf_do_error(scf_ast_t* ast, scf_node_t* err, scf_handler_data_t* d)
-{
-       assert(err->nb_nodes >= 3);
-
-       scf_expr_t* e = err->nodes[1];
-
-       int i;
-       int ret = _scf_expr_calculate(ast, e, d);
-       SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n");
-
-       scf_variable_t* r = e->result;
-       assert(r);
-
-       scf_function_t* f = NULL;
-       scf_type_t*     t = NULL;
-
-       if (r->type >= SCF_STRUCT && 1 == r->nb_pointers) {
-
-               ret = scf_ast_find_type_type(&t, ast, r->type);
-               assert(0 == ret);
-               assert(t);
-
-               f = scf_scope_find_function(t->scope, "release");
-               scf_logw("type '%s' has no release() function, use default\n", t->name->data);
-       }
-
-       scf_vector_t* argv = scf_vector_alloc();
-       scf_vector_add(argv, f);
-       scf_vector_add(argv, e->nodes[0]);
-
-//     ret = _scf_3ac_call_extern(d->_3ac_list_head, "scf_delete", NULL, (scf_node_t**)argv->data, argv->size);
-       scf_vector_free(argv);
-       argv = NULL;
-       SCF_CHECK_ERROR(ret < 0, ret, "call scf_delete failed\n");
-
-       return 0;
-}
-
 static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data)
 {
        scf_logd("f: %p, f->node->w: %s\n", f, f->node.w->text->data);
 
        scf_handler_data_t* d = data;
 
-       // save & change the current block
-       scf_block_t* prev_block = ast->current_block;
-       ast->current_block = (scf_block_t*)f;
+       scf_block_t*       up               = ast->current_block;
+       scf_branch_ops_t*  local_branch_ops = scf_branch_ops_alloc();
+       scf_branch_ops_t*  tmp_branch_ops   = d->branch_ops;
 
-       scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc();
-       scf_branch_ops_t* tmp_branch_ops   = d->branch_ops;
-       d->branch_ops                                      = local_branch_ops;
+       ast->current_block = (scf_block_t*)f;
+       d->branch_ops      = local_branch_ops; // use local_branch_ops, because branch code should NOT jmp over the function block
 
-       // use local_branch_ops, because branch code should NOT jmp over the function block
        if (_scf_op_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) {
                scf_loge("\n");
                return -1;
        }
 
-       if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_END, NULL) < 0) {
-               scf_loge("\n");
-               return -1;
-       }
+       scf_list_t*        next;
+       scf_3ac_operand_t* dst;
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    end = scf_3ac_code_NN(SCF_OP_3AC_END, NULL, 0, NULL, 0);
 
-       scf_3ac_code_t* err;
-       scf_node_t*     node;
-       scf_list_t*     tail;
-       scf_list_t*     next;
-       int i;
-       int ret;
+       scf_list_add_tail(d->_3ac_list_head, &end->list);
 
        // re-fill 'break'
+
+       int i;
        for (i = 0; i < local_branch_ops->_breaks->size; i++) {
+               c  =        local_branch_ops->_breaks->data[i];
 
-               scf_3ac_code_t*    c   = local_branch_ops->_breaks->data[i];
-               scf_3ac_operand_t* dst = c->dsts->data[0];
+               dst = c->dsts->data[0];
 
                if (dst->code) {
                        next      = scf_list_next(&dst->code->list);
@@ -1321,9 +1304,9 @@ static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data)
 
        // re-fill 'goto'
        for (i = 0; i < local_branch_ops->_gotos->size; i++) {
+               c  =        local_branch_ops->_gotos->data[i];
 
-               scf_3ac_code_t*    c    = local_branch_ops->_gotos->data[i];
-               scf_3ac_operand_t* dst  = c->dsts->data[0];
+               dst = c->dsts->data[0];
 
                if (dst->code) {
                        next      = scf_list_next(&dst->code->list);
@@ -1336,76 +1319,23 @@ static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data)
 
        // re-fill 'end'
        for (i = 0; i < local_branch_ops->_ends->size; i++) {
+               c  =        local_branch_ops->_ends->data[i];
 
-               scf_3ac_code_t*    c    = local_branch_ops->_ends->data[i];
-               scf_list_t*        l    = scf_list_tail(d->_3ac_list_head);
-               scf_3ac_code_t*    end  = scf_list_data(l, scf_3ac_code_t, list);
-               scf_3ac_operand_t* dst  = c->dsts->data[0];
+               dst = c->dsts->data[0];
 
                assert(!dst->code);
 
-               if (&c->list == scf_list_prev(l))
+               if (&c->list == scf_list_prev(&end->list))
                        c->op = scf_3ac_find_operator(SCF_OP_3AC_NOP);
                else
                        dst->code = end;
        }
 
-       if (0 == local_branch_ops->_errors->size)
-               goto end;
-
-       // do all the 'error'.
-       for (i = local_branch_ops->_errors->size - 1; i >= 0; i--) {
-
-               err = local_branch_ops->_errors->data[i];
-               assert(err);
-
-               scf_3ac_operand_t* dst = err->dsts->data[0];
-
-               if (!dst->code) {
-                       assert(err->error);
-
-                       node = err->error;
-                       err->error = NULL;
-
-                       tail = scf_list_tail(d->_3ac_list_head);
-                       dst->code = scf_list_data(tail, scf_3ac_code_t, list);
-
-                       ret = _scf_do_error(ast, node, d);
-                       SCF_CHECK_ERROR(ret < 0, ret, "do error failed\n");
-               } else {
-                       // it is the 'je' when error don't happen, do nothing.
-               }
-       }
-
-       // pop & return error code
-       _scf_3ac_code_dst(d->_3ac_list_head, SCF_OP_3AC_POP, NULL);
-
-       if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_END, NULL) < 0) {
-               scf_loge("\n");
-               return -1;
-       }
-
-       // re-fill 'error'
-       for (i = 0; i < local_branch_ops->_errors->size; i++) {
-
-               scf_3ac_code_t*    c   = local_branch_ops->_errors->data[i];
-               scf_3ac_operand_t* dst = c->dsts->data[0];
-
-               if (dst->code) {
-                       next      = scf_list_next(&dst->code->list);
-                       dst->code = scf_list_data(next, scf_3ac_code_t, list);
-               } else {
-                       scf_loge("'error' has a bug!\n");
-                       return -1;
-               }
-       }
-
-end:
        scf_branch_ops_free(local_branch_ops);
-       local_branch_ops = NULL;
-       d->branch_ops    = tmp_branch_ops;
+       local_branch_ops   = NULL;
 
-       ast->current_block = prev_block;
+       d->branch_ops      = tmp_branch_ops;
+       ast->current_block = up;
        return 0;
 }
 
@@ -1504,7 +1434,7 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
                return ret;
        }
 
-       jz  = scf_branch_ops_code(SCF_OP_3AC_JZ, NULL, NULL);
+       jz  = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL, NULL);
        scf_list_add_tail(d->_3ac_list_head, &jz->list);
 
        ret = _scf_3ac_code_N(d->_3ac_list_head, SCF_OP_CALL, nerr, nerr->nodes, nerr->nb_nodes);
@@ -1513,7 +1443,7 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
                return ret;
        }
 
-       jmp = scf_branch_ops_code(SCF_OP_GOTO,   NULL, NULL);
+       jmp = scf_3ac_jmp_code(SCF_OP_GOTO,   NULL, NULL);
        scf_list_add_tail(d->_3ac_list_head, &jmp->list);
 
        scf_vector_add(d->branch_ops->_breaks, jz);
@@ -1664,8 +1594,7 @@ static int _scf_op_expr(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
 
        scf_handler_data_t* d = data;
 
-       scf_node_t* n = nodes[0];
-       int ret = _scf_expr_calculate_internal(ast, n, d);
+       int ret = _scf_expr_calculate_internal(ast, nodes[0], d);
        if (ret < 0) {
                scf_loge("\n");
                return -1;
@@ -2400,7 +2329,7 @@ static int _scf_op_logic_##name(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
        if (jmp_op < 0) \
                return -1; \
        \
-       scf_3ac_code_t* jmp = scf_branch_ops_code(jmp_op, NULL, NULL); \
+       scf_3ac_code_t* jmp = scf_3ac_jmp_code(jmp_op, NULL, NULL); \
        if (!jmp) \
                return -ENOMEM; \
        \
@@ -2429,79 +2358,82 @@ SCF_OP_LOGIC(and)
 SCF_OP_LOGIC(or)
 
 scf_operator_handler_t _3ac_operator_handlers[] = {
-       {{NULL, NULL}, SCF_OP_EXPR,           _scf_op_expr},
-       {{NULL, NULL}, SCF_OP_CALL,           _scf_op_call},
-       {{NULL, NULL}, SCF_OP_CREATE,         _scf_op_create},
-
-       {{NULL, NULL}, SCF_OP_ARRAY_INDEX,    _scf_op_array_index},
-       {{NULL, NULL}, SCF_OP_POINTER,        _scf_op_pointer},
-
-       {{NULL, NULL}, SCF_OP_VA_START,       _scf_op_va_start},
-       {{NULL, NULL}, SCF_OP_VA_ARG,         _scf_op_va_arg},
-       {{NULL, NULL}, SCF_OP_VA_END,         _scf_op_va_end},
-
-       {{NULL, NULL}, SCF_OP_TYPE_CAST,      _scf_op_type_cast},
-       {{NULL, NULL}, SCF_OP_LOGIC_NOT,      _scf_op_logic_not},
-       {{NULL, NULL}, SCF_OP_BIT_NOT,        _scf_op_bit_not},
-       {{NULL, NULL}, SCF_OP_NEG,            _scf_op_neg},
-       {{NULL, NULL}, SCF_OP_POSITIVE,       _scf_op_positive},
-
-       {{NULL, NULL}, SCF_OP_INC,            _scf_op_inc},
-       {{NULL, NULL}, SCF_OP_DEC,            _scf_op_dec},
-
-       {{NULL, NULL}, SCF_OP_INC_POST,       _scf_op_inc_post},
-       {{NULL, NULL}, SCF_OP_DEC_POST,       _scf_op_dec_post},
-
-       {{NULL, NULL}, SCF_OP_DEREFERENCE,    _scf_op_dereference},
-       {{NULL, NULL}, SCF_OP_ADDRESS_OF,     _scf_op_address_of},
-
-       {{NULL, NULL}, SCF_OP_MUL,            _scf_op_mul},
-       {{NULL, NULL}, SCF_OP_DIV,            _scf_op_div},
-       {{NULL, NULL}, SCF_OP_MOD,            _scf_op_mod},
-
-       {{NULL, NULL}, SCF_OP_ADD,            _scf_op_add},
-       {{NULL, NULL}, SCF_OP_SUB,            _scf_op_sub},
-
-       {{NULL, NULL}, SCF_OP_SHL,            _scf_op_shl},
-       {{NULL, NULL}, SCF_OP_SHR,            _scf_op_shr},
-
-       {{NULL, NULL}, SCF_OP_BIT_AND,        _scf_op_bit_and},
-       {{NULL, NULL}, SCF_OP_BIT_OR,         _scf_op_bit_or},
-
-       {{NULL, NULL}, SCF_OP_EQ,             _scf_op_eq},
-       {{NULL, NULL}, SCF_OP_NE,             _scf_op_ne},
-       {{NULL, NULL}, SCF_OP_GT,             _scf_op_gt},
-       {{NULL, NULL}, SCF_OP_LT,             _scf_op_lt},
-       {{NULL, NULL}, SCF_OP_GE,             _scf_op_ge},
-       {{NULL, NULL}, SCF_OP_LE,             _scf_op_le},
-
-       {{NULL, NULL}, SCF_OP_LOGIC_AND,      _scf_op_logic_and},
-       {{NULL, NULL}, SCF_OP_LOGIC_OR,       _scf_op_logic_or},
-
-       {{NULL, NULL}, SCF_OP_ASSIGN,         _scf_op_assign},
-       {{NULL, NULL}, SCF_OP_ADD_ASSIGN,     _scf_op_add_assign},
-       {{NULL, NULL}, SCF_OP_SUB_ASSIGN,     _scf_op_sub_assign},
-       {{NULL, NULL}, SCF_OP_MUL_ASSIGN,     _scf_op_mul_assign},
-       {{NULL, NULL}, SCF_OP_DIV_ASSIGN,     _scf_op_div_assign},
-       {{NULL, NULL}, SCF_OP_MOD_ASSIGN,     _scf_op_mod_assign},
-       {{NULL, NULL}, SCF_OP_SHL_ASSIGN,     _scf_op_shl_assign},
-       {{NULL, NULL}, SCF_OP_SHR_ASSIGN,     _scf_op_shr_assign},
-       {{NULL, NULL}, SCF_OP_AND_ASSIGN,     _scf_op_and_assign},
-       {{NULL, NULL}, SCF_OP_OR_ASSIGN,      _scf_op_or_assign},
-
-
-       {{NULL, NULL}, SCF_OP_BLOCK,          _scf_op_block},
-       {{NULL, NULL}, SCF_OP_RETURN,         _scf_op_return},
-       {{NULL, NULL}, SCF_OP_BREAK,          _scf_op_break},
-       {{NULL, NULL}, SCF_OP_CONTINUE,       _scf_op_continue},
-       {{NULL, NULL}, SCF_OP_GOTO,           _scf_op_goto},
-       {{NULL, NULL}, SCF_LABEL,             _scf_op_label},
-       {{NULL, NULL}, SCF_OP_ERROR,          _scf_op_error},
-
-       {{NULL, NULL}, SCF_OP_IF,             _scf_op_if},
-       {{NULL, NULL}, SCF_OP_WHILE,          _scf_op_while},
-       {{NULL, NULL}, SCF_OP_REPEAT,         _scf_op_repeat},
-       {{NULL, NULL}, SCF_OP_FOR,            _scf_op_for},
+       {SCF_OP_EXPR,           _scf_op_expr},
+       {SCF_OP_CALL,           _scf_op_call},
+       {SCF_OP_CREATE,         _scf_op_create},
+
+       {SCF_OP_ARRAY_INDEX,    _scf_op_array_index},
+       {SCF_OP_POINTER,        _scf_op_pointer},
+
+       {SCF_OP_VA_START,       _scf_op_va_start},
+       {SCF_OP_VA_ARG,         _scf_op_va_arg},
+       {SCF_OP_VA_END,         _scf_op_va_end},
+
+       {SCF_OP_TYPE_CAST,      _scf_op_type_cast},
+       {SCF_OP_LOGIC_NOT,      _scf_op_logic_not},
+       {SCF_OP_BIT_NOT,        _scf_op_bit_not},
+       {SCF_OP_NEG,            _scf_op_neg},
+       {SCF_OP_POSITIVE,       _scf_op_positive},
+
+       {SCF_OP_INC,            _scf_op_inc},
+       {SCF_OP_DEC,            _scf_op_dec},
+
+       {SCF_OP_INC_POST,       _scf_op_inc_post},
+       {SCF_OP_DEC_POST,       _scf_op_dec_post},
+
+       {SCF_OP_DEREFERENCE,    _scf_op_dereference},
+       {SCF_OP_ADDRESS_OF,     _scf_op_address_of},
+
+       {SCF_OP_MUL,            _scf_op_mul},
+       {SCF_OP_DIV,            _scf_op_div},
+       {SCF_OP_MOD,            _scf_op_mod},
+
+       {SCF_OP_ADD,            _scf_op_add},
+       {SCF_OP_SUB,            _scf_op_sub},
+
+       {SCF_OP_SHL,            _scf_op_shl},
+       {SCF_OP_SHR,            _scf_op_shr},
+
+       {SCF_OP_BIT_AND,        _scf_op_bit_and},
+       {SCF_OP_BIT_OR,         _scf_op_bit_or},
+
+       {SCF_OP_EQ,             _scf_op_eq},
+       {SCF_OP_NE,             _scf_op_ne},
+       {SCF_OP_GT,             _scf_op_gt},
+       {SCF_OP_LT,             _scf_op_lt},
+       {SCF_OP_GE,             _scf_op_ge},
+       {SCF_OP_LE,             _scf_op_le},
+
+       {SCF_OP_LOGIC_AND,      _scf_op_logic_and},
+       {SCF_OP_LOGIC_OR,       _scf_op_logic_or},
+
+       {SCF_OP_ASSIGN,         _scf_op_assign},
+       {SCF_OP_ADD_ASSIGN,     _scf_op_add_assign},
+       {SCF_OP_SUB_ASSIGN,     _scf_op_sub_assign},
+       {SCF_OP_MUL_ASSIGN,     _scf_op_mul_assign},
+       {SCF_OP_DIV_ASSIGN,     _scf_op_div_assign},
+       {SCF_OP_MOD_ASSIGN,     _scf_op_mod_assign},
+       {SCF_OP_SHL_ASSIGN,     _scf_op_shl_assign},
+       {SCF_OP_SHR_ASSIGN,     _scf_op_shr_assign},
+       {SCF_OP_AND_ASSIGN,     _scf_op_and_assign},
+       {SCF_OP_OR_ASSIGN,      _scf_op_or_assign},
+
+
+       {SCF_OP_BLOCK,          _scf_op_block},
+       {SCF_OP_RETURN,         _scf_op_return},
+       {SCF_OP_BREAK,          _scf_op_break},
+       {SCF_OP_CONTINUE,       _scf_op_continue},
+       {SCF_OP_GOTO,           _scf_op_goto},
+       {SCF_LABEL,             _scf_op_label},
+
+       {SCF_OP_IF,             _scf_op_if},
+       {SCF_OP_WHILE,          _scf_op_while},
+       {SCF_OP_DO,             _scf_op_do},
+       {SCF_OP_FOR,            _scf_op_for},
+
+       {SCF_OP_SWITCH,         _scf_op_switch},
+       {SCF_OP_CASE,           _scf_op_case},
+       {SCF_OP_DEFAULT,        _scf_op_default},
 };
 
 scf_operator_handler_t* scf_find_3ac_operator_handler(const int type)
@@ -2517,4 +2449,3 @@ scf_operator_handler_t* scf_find_3ac_operator_handler(const int type)
 
        return NULL;
 }
-
index 387ce87c36ca2cc482e95f3197bc3da1ccf5c3a3..8481a03a8958a07bae9748b9c3ac93ba7d0ab404 100644 (file)
@@ -500,7 +500,7 @@ static int _bb_loop_add_pre_post(scf_function_t* f)
                                if (!jmp)
                                        return -ENOMEM;
 
-                               c = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL);
+                               c = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
                                if (!c) {
                                        scf_basic_block_free(jmp);
                                        return -ENOMEM;
@@ -682,10 +682,8 @@ static int _optimize_loop_loads_saves(scf_function_t* f)
                        for (k = 0; k < bb->dn_loads->size; k++) {
                                dn =        bb->dn_loads->data[k];
 
-                               if (dn->var->tmp_flag) {
-                                       k++;
+                               if (dn->var->tmp_flag)
                                        continue;
-                               }
 
                                if (scf_vector_add_unique(pre->dn_loads, dn) < 0)
                                        return -1;
diff --git a/docs/Naja_float.txt b/docs/Naja_float.txt
new file mode 100644 (file)
index 0000000..0d92c36
--- /dev/null
@@ -0,0 +1,122 @@
+                                Naja float instructions
+
+
+16, fadd, +, +=,                  opcode = 16
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  0  0  0  0|<--- rd  ---->|0 | 0  0| 0  0  0  0  0  0  0  0|<--- rs1 ---->|<--- rs0 ---->|
+
+rd = rs0 + rs1;
+
+
+17, fsub, -, -=,                  opcode = 17
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  0  0  0  1|<--- rd  ---->|0 | 0  0| 0  0  0  0  0  0  0  0|<--- rs1 ---->|<--- rs0 ---->|
+
+rd = rs0 - rs1;
+------------------------------------------------------------------------------------------------
+
+
+18, fmul, *, *=,                  opcode = 18
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  0  0  1  0|<--- rd  ---->| s| opt | 0  0  0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->|
+
+s = 1,   signed mul.
+
+rd = rs2 + rs0 * rs1; // opt = 0
+rd = rs2 - rs0 * rs1; // opt = 1
+rd =       rs0 * rs1; // opt = 2
+------------------------------------------------------------------------------------------------
+
+
+19, fdiv, *, *=,                  opcode = 19
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  0  0  1  1|<--- rd  ---->| s| opt | 0  0  0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->|
+
+s = 1,   signed div.
+
+rd = rs2 + rs0 / rs1; // opt = 0
+rd = rs2 - rs0 / rs1; // opt = 1
+rd =       rs0 / rs1; // opt = 2
+------------------------------------------------------------------------------------------------
+
+
+20, fldr, b[i]                    opcode = 20
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  0  1  0  0|<--- rd  ---->| A|  ext   |<--------- simm12 ---------------->|<---- rb ---->|
+
+rd = *(double*)(rb + ((int64_t)simm12 << 3));  // ext = 3,
+rd = *(float *)(rb + ((int64_t)simm12 << 2));  // ext = 6, SS2SD
+
+rb += simm12 << sh, if A = 1
+------------------------------------------------------------------------------------------------
+
+21, fstr, b[i]                    opcode = 21
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  0  1  0  1|<--- rd  ---->| A|  ext   |<--------- simm12 ---------------->|<---- rb ---->|
+
+*(double*)(rb + ((int64_t)simm15 << 3) = rd;  // ext = 3,
+*(float *)(rb + ((int64_t)simm15 << 2) = rd;  // ext = 6, SD2SS
+
+rb += simm12 << sh, if A = 1
+------------------------------------------------------------------------------------------------
+
+
+25, fcmp, >, >=, <, <=, ==, !=,   opcode = 25
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  1  0  0  1| 0  0  0  0  0|0   0  0| 0  0  0  0  0  0  0  0|<--- rs1 ---->|<--- rs0 ---->|
+
+flags = rs0 - rs1;
+------------------------------------------------------------------------------------------------
+
+
+28, fldr, b[i << s]              opcode = 28
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  1  1  0  0|<--- rd  ---->|PA|  ext   |<-------- uimm7  -->|<---- ri ---->|<---- rb ---->|
+
+rd = *(double*)(rb + (ri << uimm8));  // ext = 3,
+rd = *(float* )(rb + (ri << uimm8));  // ext = 6, SS2SD
+
+rb += ri << uimm7, if PA = 1
+------------------------------------------------------------------------------------------------
+
+29, fstr, b[i << s]              opcode = 29
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  1  1  0  1|<--- rd  ---->|PA|  ext   |<-------- uimm7  -->|<---- ri ---->|<---- rb ---->|
+
+rd = *(double*)(rb + (ri << uimm8));  // ext = 3
+rd = *(float *)(rb + (ri << uimm8));  // ext = 6, SD2SS
+
+rb += ri << uimm7, if PA = 1
+------------------------------------------------------------------------------------------------
+
+31, fmov, =, ~, -,               opcode = 31
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  1  1  1  1|<--- rd  ---->| 0|    opt    | 0  0  0  0  0  0  0  0  0  0  0|<---- rs ---->|
+
+rd =  rs;           // opt = 0
+rd =  rs;           // opt = 1 SS2SD,
+rd =  rs;           // opt = 2 SD2SS,
+rd = -rs;           // opt = 3 NEG,
+
+rd =  rs;           // opt = 4 CVTSS2SI,
+rd =  rs;           // opt = 5 CVTSD2SI,
+rd =  rs;           // opt = 6 CVTSS2UI,
+rd =  rs;           // opt = 7 CVTSD2UI,
+
+rd =  rs;           // opt = c CVTSI2SS,
+rd =  rs;           // opt = d CVTSI2SD,
+rd =  rs;           // opt = e CVTUI2SS,
+rd =  rs;           // opt = f CVTUI2SD,
+------------------------------------------------------------------------------------------------
+
+
diff --git a/docs/Naja_int.txt b/docs/Naja_int.txt
new file mode 100644 (file)
index 0000000..caf43fd
--- /dev/null
@@ -0,0 +1,314 @@
+                                Naja interger instructions
+
+
+0, add, +, +=,                  opcode = 0
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  0  0  0|<--- rd  ---->|0 | sh  |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->|
+
+rd = rs0 + (rs1 << IMM);  // SH = 0, LSL
+rd = rs0 + (rs1 >> IMM);  // SH = 1, LSR
+rd = rs0 + (rs1 >> IMM);  // SH = 2, ASR
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  0  0  0|<--- rd  ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->|
+
+rd = rs0 + (uint64_t)uimm15;
+------------------------------------------------------------------------------------------------
+
+1, sub, -, -=,                  opcode = 1
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  0  0  1|<--- rd  ---->|0 | sh  |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->|
+
+rd = rs0 - (rs1 << IMM);  // SH = 0, LSL
+rd = rs0 - (rs1 >> IMM);  // SH = 1, LSR
+rd = rs0 - (rs1 >> IMM);  // SH = 2, ASR
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  0  0  1|<--- rd  ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->|
+
+rd = rs0 - (uint64_t)uimm15;
+------------------------------------------------------------------------------------------------
+
+
+2, mul, *, *=,                  opcode = 2
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  0  1  0|<--- rd  ---->| s| opt | 0  0  0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->|
+
+s = 0, unsigned mul.
+s = 1,   signed mul.
+
+rd = rs2 + rs0 * rs1; // opt = 0
+rd = rs2 - rs0 * rs1; // opt = 1
+rd =       rs0 * rs1; // opt = 2
+------------------------------------------------------------------------------------------------
+
+3, div, *, *=,                  opcode = 3
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  0  1  1|<--- rd  ---->| s| opt | 0  0  0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->|
+
+s = 0, unsigned div.
+s = 1,   signed div.
+
+rd = rs2 + rs0 / rs1; // opt = 0
+rd = rs2 - rs0 / rs1; // opt = 1
+rd =       rs0 / rs1; // opt = 2
+------------------------------------------------------------------------------------------------
+
+
+4, ldr, b[i]                    opcode = 4
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  1  0  0|<--- rd  ---->| A|  ext   |<-------- simm12 ----------------->|<---- rb ---->|
+
+rd = *(uint8_t* )(rs0 +  (int64_t)simm12);        // ext = 0, zbq
+rd = *(uint16_t*)(rs0 + ((int64_t)simm12 << 1));  // ext = 1, zwq
+rd = *(uint32_t*)(rs0 + ((int64_t)simm12 << 2));  // ext = 2, zlq
+
+rd = *(uint64_t*)(rs0 + ((int64_t)simm12 << 3));  // ext = 3,
+
+rd = *( int8_t* )(rs0 +  (int64_t)simm12);        // ext = 4, sbq
+rd = *( int16_t*)(rs0 + ((int64_t)simm12 << 1));  // ext = 5, swq
+rd = *( int32_t*)(rs0 + ((int64_t)simm12 << 2));  // ext = 6, slq
+
+rb += simm12 << SH, if A = 1
+------------------------------------------------------------------------------------------------
+
+5, str, b[i]                    opcode = 5
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  1  0  1|<--- rd  ---->| A|  ext   |--------- simm12 ----------------->|<---- rb ---->|
+
+*(uint8_t* )(rs0 +  (int64_t)simm12)       = rd;  // ext = 0, zbq
+*(uint16_t*)(rs0 + ((int64_t)simm12 << 1)) = rd;  // ext = 1, zwq
+*(uint32_t*)(rs0 + ((int64_t)simm12 << 2)) = rd;  // ext = 2, zlq
+*(uint64_t*)(rs0 + ((int64_t)simm12 << 3)) = rd;  // ext = 3
+
+rb += simm12 << SH, if A = 1
+------------------------------------------------------------------------------------------------
+
+
+6, and, &, &=,                  opcode = 6
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  1  1  0|<--- rd  ---->|0 | sh  |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->|
+
+rd = rs0 & (rs1 << IMM);  // SH = 0, LSL
+rd = rs0 & (rs1 >> IMM);  // SH = 1, LSR
+rd = rs0 & (rs1 >> IMM);  // SH = 2, ASR
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  1  1  0|<--- rd  ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->|
+
+rd = rs0 & (uint64_t)uimm15;
+------------------------------------------------------------------------------------------------
+
+7, or, |, |=,                   opcode = 7
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  1  1  1|<--- rd  ---->|0 | sh  |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->|
+
+rd = rs0 | (rs1 << uimm8);  // SH = 0, LSL
+rd = rs0 | (rs1 >> uimm8);  // SH = 1, LSR
+rd = rs0 | (rs1 >> uimm8);  // SH = 2, ASR
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  0  1  1  1|<--- rd  ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->|
+
+rd = rs0 | (uint64_t)uimm15;
+------------------------------------------------------------------------------------------------
+
+8, jmp, disp                   opcode = 8
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  0  0  0|<-------------------------------- simm26:00 -------------------------------->|
+
+jmp disp; // -128M ~ 128M
+------------------------------------------------------------------------------------------------
+
+
+9, cmp, >, >=, <, <=, ==, !=,   opcode = 9
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  0  0  1| 0  0  0  0  0|0 | sh  |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->|
+
+flags = rs0 - (rs1 << IMM);  // SH = 0, LSL
+flags = rs0 - (rs1 >> IMM);  // SH = 1, LSR
+flags = rs0 - (rs1 >> IMM);  // SH = 2, ASR
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  0  0  1| 0  0  0  0  0|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->|
+
+flags = rs0 - (uint64_t)uimm15;
+------------------------------------------------------------------------------------------------
+
+
+10, jmp, reg,                   opcode = 10
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  0  1  0|<--- rd  ---->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+jmp *rd;
+------------------------------------------------------------------------------------------------
+
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  0  1  0|<----------------------------- simm21:00 -------------------->|<--- cc -->| 1|
+
+jcc simm21:00; // -4M ~ +4M
+cc = 0,  z,
+cc = 1, nz,
+cc = 2, ge,
+cc = 3, gt,
+cc = 4, le,
+cc = 5, lt,
+------------------------------------------------------------------------------------------------
+
+
+11, setcc, &&,||,               opcode = 11
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  0  1  1|<--- rd  ---->|    cc     | 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+cc = 0,  z,
+cc = 1, nz,
+cc = 2, ge,
+cc = 3, gt,
+cc = 4, le,
+cc = 5, lt,
+------------------------------------------------------------------------------------------------
+
+
+12, ldr, b[i << s]              opcode = 12
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  0  0|<--- rd  ---->|0 | ext    |<------ uimm7 ----->|<---- ri ---->|<---- rb ---->|
+
+rd = *(uint8_t* )(rb + (ri << uimm7));      // ext = 0, zbq
+rd = *(uint16_t*)(rb + (ri << uimm7)); // ext = 1, zwq
+rd = *(uint32_t*)(rb + (ri << uimm7)); // ext = 2, zlq
+
+rd = *(uint64_t*)(rb + (ri << uimm7));  // ext = 3,
+
+rd = *( int8_t* )(rb + (ri << uimm7));  // ext = 4, sbq
+rd = *( int16_t*)(rb + (ri << uimm7));  // ext = 5, swq
+rd = *( int32_t*)(rb + (ri << uimm7));  // ext = 6, slq
+------------------------------------------------------------------------------------------------
+
+13, str, b[i << s]              opcode = 13
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  0  1|<--- rd  ---->|0 |  ext   |<-------- uimm7  -->|<---- ri ---->|<---- rb ---->|
+
+rd = *(uint8_t* )(rb + (ri << uimm7));  // ext = 0, zbq
+rd = *(uint16_t*)(rb + (ri << uimm7));  // ext = 1, zwq
+rd = *(uint32_t*)(rb + (ri << uimm7));  // ext = 2, zlq
+
+rd = *(uint64_t*)(rb + (ri << uimm7));  // ext = 3,
+
+rd = *( int8_t* )(rb + (ri << uimm7));  // ext = 4, sbq
+rd = *( int16_t*)(rb + (ri << uimm7));  // ext = 5, swq
+rd = *( int32_t*)(rb + (ri << uimm7));  // ext = 6, slq
+------------------------------------------------------------------------------------------------
+
+
+14, teq, !,                  opcode = 14
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  1  0| 0  0  0  0  0|0 | sh  |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->|
+
+ZF = rs0 & (rs1 << IMM);  // SH = 0, LSL
+ZF = rs0 & (rs1 >> IMM);  // SH = 1, LSR
+ZF = rs0 & (rs1 >> IMM);  // SH = 2, ASR
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  1  0| 0  0  0  0  0|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->|
+
+ZF = rs0 & (uint64_t)uimm15;
+------------------------------------------------------------------------------------------------
+
+
+15, mov, =, ~, -,                opcode = 15
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  1  1|<--- rd  ---->|0 | 0|  opt   |<------------- uimm11 --------->|<---- rs ---->|
+
+rd =  rs;           // opt = 0 LSL, uimm11 = 0
+rd =  rs << uimm11; // opt = 0 LSL,
+rd =  rs >> uimm11; // opt = 1 LSR,
+rd =  rs >> uimm11; // opt = 2 ASR,
+rd = ~rs;           // opt = 3 NOT,
+rd = -rs;           // opt = 4 NEG,
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  1  1|<--- rd  ---->|0 | 1|  opt   | 0  0  0  0  0  0|<--- rs1 ---->|<---- rs0---->|
+
+rd =  rs << rs1; // opt = 0 LSL,
+rd =  rs >> rs1; // opt = 1 LSR,
+rd =  rs >> rs1; // opt = 2 ASR,
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  1  1|<--- rd  ---->|0 | x|  opt   |<------------- uimm11 --------->|<---- rs ---->|
+
+rd =  uint8_t(rs);  // x = 0, zbq, opt = 5,
+rd =   int8_t(rs);  // x = 1, sbq, opt = 5,
+rd = uint16_t(rs);  // x = 0, zwq, opt = 6,
+rd =  int16_t(rs);  // x = 1, swq, opt = 6,
+rd = uint32_t(rs);  // x = 0, zlq, opt = 7,
+rd =  int32_t(rs);  // x = 1, slq, opt = 7,
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  0  1  1  1  1|<--- rd  ---->|1 | x| opt    |<------------------  imm16 ------------------->|
+
+rd = uint64_t(imm16);       // opt = 0
+rd = uint64_t(imm16) << 16; // opt = 1
+rd = uint64_t(imm16) << 32; // opt = 2
+rd = uint64_t(imm16) << 48; // opt = 3
+
+rd = uint64_t(imm16);       // opt = 7, NOT
+
+rd = uint64_t(imm16);       //   x = 0, zwq
+rd =  int64_t(imm16);       //   x = 1, swq
+------------------------------------------------------------------------------------------------
+
+
+24, call, disp                  opcode = 24
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  1  0  0  0|<-------------------------------- simm26:00 -------------------------------->|
+
+call disp; // -128M ~ 128M
+------------------------------------------------------------------------------------------------
+
+26, call, reg,                  opcode = 26
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1  1  0  1  0|<--- rd  ---->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+call *rd;
+------------------------------------------------------------------------------------------------
+
+42, adrp, reg,                  opcode = 42
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0  1  0  1  0|<--- rd  ---->|<--------------------   simm21   ---------------------------->|
+
+rd = RIP + ((int64_t)simm21 << 15); // load address' high 21 bits relative to current RIP, -32G:+32G
+------------------------------------------------------------------------------------------------
+
+56, ret,                        opcode = 56
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1  1  0  0  0|<-------------------------------- 00        -------------------------------->|
+
+ret
+------------------------------------------------------------------------------------------------
+
diff --git a/examples/switch_case.c b/examples/switch_case.c
new file mode 100644 (file)
index 0000000..b9432c5
--- /dev/null
@@ -0,0 +1,19 @@
+int printf(const char* fmt, ...);
+
+int main()
+{
+       int a = 0;
+
+       switch (a) {
+               case 0:
+                       printf("0\n");
+               case 1:
+                       printf("1\n");
+                       break;
+               default:
+                       printf("default\n");
+                       break;
+       };
+
+       return 0;
+}
index 005b9f997794609a55694788ed5df276ab41e68c..47aae52c3999aa03826307d695b032327d1548e2 100644 (file)
@@ -18,7 +18,6 @@ static scf_lex_key_word_t     key_words[] = {
        {"return",    SCF_LEX_WORD_KEY_RETURN},
 
        {"goto",      SCF_LEX_WORD_KEY_GOTO},
-       {"error",     SCF_LEX_WORD_KEY_ERROR},
 
        {"sizeof",    SCF_LEX_WORD_KEY_SIZEOF},
 
index 44938841bc0619b78ffc369fabca32ed229901ca..b097b8a2ec41bfbca398328da0b99cffe8556b1d 100644 (file)
@@ -77,7 +77,6 @@ CFILES += ../core/scf_scope.c
 CFILES += ../core/scf_function.c
 
 CFILES += ../core/scf_operator.c
-CFILES += ../core/scf_operator_handler.c
 
 CFILES += ../core/scf_type_cast.c
 CFILES += ../core/scf_type_cast_i8.c
@@ -148,14 +147,14 @@ CFILES += scf_struct_array.c
 
 CFILES += scf_dfa_if.c
 CFILES += scf_dfa_while.c
-CFILES += scf_dfa_repeat.c
+CFILES += scf_dfa_do.c
 CFILES += scf_dfa_for.c
+CFILES += scf_dfa_switch.c
 
 CFILES += scf_dfa_break.c
 CFILES += scf_dfa_continue.c
 CFILES += scf_dfa_goto.c
 CFILES += scf_dfa_return.c
-CFILES += scf_dfa_error.c
 CFILES += scf_dfa_label.c
 CFILES += scf_dfa_async.c
 
index 8d7c10a77bd00402754047d8b4d108fc87bd29c8..210f41422ceabddd1b529dd7ac581191b8eb6f8c 100644 (file)
@@ -389,7 +389,7 @@ static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_ve
                                continue;
 
                        if (SCF_DFA_SWITCH_TO == ret) {
-                               scf_logi("\033[31m end hook: switch to %s->%s\033[0m\n", node->name, hook_node->name);
+                               scf_logi("\033[31m end hook: switch to %s->%s\033[0m\n\n", node->name, hook_node->name);
 
                                node = hook_node;
                                ret  = SCF_DFA_NEXT_WORD;
index 20600ae6e7e2bc0e77b9d14070ed1dffa6eca578..3158ee2d670f6c1bce762c447340a88b67fedba5 100644 (file)
@@ -14,8 +14,6 @@ typedef struct {
 
        scf_node_t*      parent_node;
 
-       scf_dfa_hook_t*  hook_end;
-
 } dfa_block_data_t;
 
 static int _block_action_entry(scf_dfa_t* dfa, scf_vector_t* words, void* data)
@@ -32,8 +30,7 @@ static int _block_action_entry(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                bd->parent_block = parse->ast->current_block;
                bd->parent_node  = d->current_node;
 
-               bd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END);
-               assert(bd->hook_end);
+               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END);
 
                scf_stack_push(s, bd);
 
@@ -56,8 +53,7 @@ static int _block_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                scf_logi("\033[31m end bd: %p, bd->nb_lbs: %d, bd->nb_rbs: %d, s->size: %d\033[0m\n",
                                bd, bd->nb_lbs, bd->nb_rbs, s->size);
 
-               bd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END);
-               assert(bd->hook_end);
+               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END);
 
                return SCF_DFA_SWITCH_TO;
        }
@@ -101,8 +97,7 @@ static int _block_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        parse->ast->current_block = b;
        d->current_node = NULL;
 
-       bd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END);
-       assert(bd->hook_end);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END);
 
        bd->nb_lbs++;
        scf_stack_push(s, bd);
@@ -125,7 +120,7 @@ static int _block_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_logi("\033[31m bd: %p, bd->nb_lbs: %d, bd->nb_rbs: %d, s->size: %d\033[0m\n",
                        bd, bd->nb_lbs, bd->nb_rbs, s->size);
 
-       assert(bd->nb_lbs       == bd->nb_rbs);
+       assert(bd->nb_lbs == bd->nb_rbs);
 
        parse->ast->current_block = bd->parent_block;
        d->current_node = bd->parent_node;
@@ -150,15 +145,18 @@ static int _dfa_init_module_block(scf_dfa_t* dfa)
 
        SCF_DFA_GET_MODULE_NODE(dfa, if,       _if,       _if);
        SCF_DFA_GET_MODULE_NODE(dfa, while,    _while,    _while);
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,   _do,       _do);
+       SCF_DFA_GET_MODULE_NODE(dfa, do,       _do,       _do);
        SCF_DFA_GET_MODULE_NODE(dfa, for,      _for,      _for);
 
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   _switch,   _switch);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   _case,     _case);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   _default,  _default);
+
        SCF_DFA_GET_MODULE_NODE(dfa, break,    _break,    _break);
        SCF_DFA_GET_MODULE_NODE(dfa, continue, _continue, _continue);
        SCF_DFA_GET_MODULE_NODE(dfa, return,   _return,   _return);
        SCF_DFA_GET_MODULE_NODE(dfa, goto,     _goto,     _goto);
        SCF_DFA_GET_MODULE_NODE(dfa, label,    label,     label);
-       SCF_DFA_GET_MODULE_NODE(dfa, error,    error,     error);
        SCF_DFA_GET_MODULE_NODE(dfa, async,    async,     async);
 
        SCF_DFA_GET_MODULE_NODE(dfa, va_arg,   start,     va_start);
@@ -177,13 +175,15 @@ static int _dfa_init_module_block(scf_dfa_t* dfa)
        scf_dfa_node_add_child(entry, _while);
        scf_dfa_node_add_child(entry, _do);
        scf_dfa_node_add_child(entry, _for);
+       scf_dfa_node_add_child(entry, _switch);
+       scf_dfa_node_add_child(entry, _case);
+       scf_dfa_node_add_child(entry, _default);
 
        scf_dfa_node_add_child(entry, _break);
        scf_dfa_node_add_child(entry, _continue);
        scf_dfa_node_add_child(entry, _return);
        scf_dfa_node_add_child(entry, _goto);
        scf_dfa_node_add_child(entry, label);
-       scf_dfa_node_add_child(entry, error);
        scf_dfa_node_add_child(entry, async);
 
 
@@ -225,7 +225,6 @@ static int _dfa_init_syntax_block(scf_dfa_t* dfa)
 
        scf_dfa_node_add_child(entry, end);
        scf_dfa_node_add_child(end,   entry);
-       //scf_dfa_node_add_child(entry, entry);
 
        int i;
        for (i = 0; i < entry->childs->size; i++) {
@@ -245,4 +244,3 @@ scf_dfa_module_t dfa_module_block =
 
        .fini_module = _dfa_fini_module_block,
 };
-
index 9aeead367f8f3bc4b47c7ba2cc95acec6399ebfa..21b0f07f6779441e4e54326e80a1d27968f764ac 100644 (file)
@@ -11,8 +11,6 @@ typedef struct {
 
        scf_type_t*      current_class;
 
-       scf_dfa_hook_t*  hook_end;
-
        int              nb_lbs;
        int              nb_rbs;
 
@@ -28,18 +26,13 @@ static int _class_is_class(scf_dfa_t* dfa, void* word)
 
 static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       if (!data) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
-               return SCF_DFA_ERROR;
-       }
-
        scf_parse_t*          parse = dfa->priv;
        dfa_parse_data_t*     d     = data;
        class_module_data_t*  md    = d->module_datas[dfa_module_class.index];
        scf_lex_word_t*       w     = words->data[words->size - 1];
 
        if (md->current_identity) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
+               scf_loge("\n");
                return SCF_DFA_ERROR;
        }
 
@@ -47,7 +40,7 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        if (!t) {
                t = scf_type_alloc(w, w->text->data, SCF_STRUCT + parse->ast->nb_structs, 0);
                if (!t) {
-                       printf("%s(), %d, error: \n", __func__, __LINE__);
+                       scf_loge("\n");
                        return SCF_DFA_ERROR;
                }
 
@@ -59,7 +52,7 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat
 
        md->current_identity = w;
        md->parent_block     = parse->ast->current_block;
-       md->hook_end         = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END);
 
        printf("\033[31m%s(), %d, t: %p, t->type: %d\033[0m\n", __func__, __LINE__, t, t->type);
 
@@ -68,24 +61,19 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat
 
 static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       if (!data) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
-               return SCF_DFA_ERROR;
-       }
-
        scf_parse_t*          parse = dfa->priv;
        dfa_parse_data_t*     d     = data;
        class_module_data_t*  md    = d->module_datas[dfa_module_class.index];
        scf_lex_word_t*       w     = words->data[words->size - 1];
 
        if (!md->current_identity) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
+               scf_loge("\n");
                return SCF_DFA_ERROR;
        }
 
        scf_type_t* t = scf_block_find_type(parse->ast->current_block, md->current_identity->text->data);
        if (!t) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
+               scf_loge("\n");
                return SCF_DFA_ERROR;
        }
 
@@ -98,8 +86,6 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        parse->ast->current_block = (scf_block_t*)t;
 
-       printf("%s(), %d, t: %p\n", __func__, __LINE__, t);
-
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -114,7 +100,7 @@ static int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s)
                scf_variable_t* v = s->scope->vars->data[i];
 
                if (v->size < 0) {
-                       printf("%s(), %d, error: sizeof var: '%s'\n", __func__, __LINE__, v->w->text->data);
+                       scf_loge("error: sizeof var: '%s'\n", v->w->text->data);
                        return SCF_DFA_ERROR;
                }
 
@@ -162,19 +148,12 @@ static int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s)
 
 static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       printf("%s(), %d\n", __func__, __LINE__);
-
-       if (!data) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
-               return SCF_DFA_ERROR;
-       }
-
        scf_parse_t*          parse = dfa->priv;
        dfa_parse_data_t*     d     = data;
        class_module_data_t*  md    = d->module_datas[dfa_module_class.index];
 
        if (_class_calculate_size(dfa, md->current_class) < 0) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
+               scf_loge("\n");
                return SCF_DFA_ERROR;
        }
 
@@ -185,24 +164,16 @@ static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
 static int _class_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       printf("%s(), %d\n", __func__, __LINE__);
-
        return SCF_DFA_OK;
 }
 
 static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       if (!data) {
-               printf("%s(), %d, error: \n", __func__, __LINE__);
-               return SCF_DFA_ERROR;
-       }
-
        scf_parse_t*          parse = dfa->priv;
        dfa_parse_data_t*     d     = data;
        class_module_data_t*  md    = d->module_datas[dfa_module_class.index];
 
        if (md->nb_rbs == md->nb_lbs) {
-               printf("%s(), %d, SCF_DFA_OK\n", __func__, __LINE__);
 
                parse->ast->current_block = md->parent_block;
 
@@ -211,14 +182,12 @@ static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                md->parent_block     = NULL;
                md->nb_lbs           = 0;
                md->nb_rbs           = 0;
-               md->hook_end         = NULL;
 
                return SCF_DFA_OK;
        }
 
-       md->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END);
 
-       printf("%s(), %d\n", __func__, __LINE__);
        return SCF_DFA_SWITCH_TO;
 }
 
diff --git a/parse/scf_dfa_do.c b/parse/scf_dfa_do.c
new file mode 100644 (file)
index 0000000..13d3e92
--- /dev/null
@@ -0,0 +1,226 @@
+#include"scf_dfa.h"
+#include"scf_dfa_util.h"
+#include"scf_parse.h"
+#include"scf_stack.h"
+
+extern scf_dfa_module_t dfa_module_do;
+
+typedef struct {
+       int              nb_lps;
+       int              nb_rps;
+
+       scf_block_t*     parent_block;
+       scf_node_t*      parent_node;
+
+       scf_node_t*      _do;
+
+} dfa_do_data_t;
+
+
+static int _do_action_do(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*      parse = dfa->priv;
+       dfa_parse_data_t* d     = data;
+       scf_lex_word_t*   w     = words->data[words->size - 1];
+       scf_stack_t*      s     = d->module_datas[dfa_module_do.index];
+       scf_block_t*      b     = NULL;
+
+       scf_node_t* _do = scf_node_alloc(w, SCF_OP_DO, NULL);
+       if (!_do) {
+               scf_loge("node alloc failed\n");
+               return SCF_DFA_ERROR;
+       }
+
+       dfa_do_data_t* dd = calloc(1, sizeof(dfa_do_data_t));
+       if (!dd) {
+               scf_loge("module data alloc failed\n");
+               return SCF_DFA_ERROR;
+       }
+
+       if (d->current_node)
+               scf_node_add_child(d->current_node, _do);
+       else
+               scf_node_add_child((scf_node_t*)parse->ast->current_block, _do);
+
+       dd->_do          = _do;
+       dd->parent_block = parse->ast->current_block;
+       dd->parent_node  = d->current_node;
+       d->current_node  = _do;
+
+       scf_stack_push(s, dd);
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do__while"),  SCF_DFA_HOOK_END);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _do_action_while(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_lex_word_t* w = dfa->ops->pop_word(dfa);
+
+       if (SCF_LEX_WORD_KEY_WHILE != w->type)
+               return SCF_DFA_ERROR;
+
+       return SCF_DFA_SWITCH_TO;
+}
+
+static int _do_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+
+       assert(!d->expr);
+       d->expr_local_flag = 1;
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_rp"),      SCF_DFA_HOOK_POST);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_lp_stat"), SCF_DFA_HOOK_POST);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _do_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       dfa_parse_data_t*  d  = data;
+       scf_stack_t*       s  = d->module_datas[dfa_module_do.index];
+       dfa_do_data_t*     dd = scf_stack_top(s);
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_lp_stat"), SCF_DFA_HOOK_POST);
+
+       dd->nb_lps++;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _do_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_lex_word_t*    w     = words->data[words->size - 1];
+       scf_stack_t*       s     = d->module_datas[dfa_module_do.index];
+       dfa_do_data_t*     dd    = scf_stack_top(s);
+
+       if (!d->expr) {
+               scf_loge("\n");
+               return SCF_DFA_ERROR;
+       }
+
+       dd->nb_rps++;
+
+       if (dd->nb_rps == dd->nb_lps) {
+
+               assert(1 == dd->_do->nb_nodes);
+
+               scf_node_add_child(dd->_do, d->expr);
+               d->expr = NULL;
+
+               d->expr_local_flag = 0;
+
+               return SCF_DFA_SWITCH_TO;
+       }
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_rp"),      SCF_DFA_HOOK_POST);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_lp_stat"), SCF_DFA_HOOK_POST);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _do_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_stack_t*       s     = d->module_datas[dfa_module_do.index];
+       dfa_do_data_t*     dd    = scf_stack_pop(s);
+
+       assert(parse->ast->current_block == dd->parent_block);
+
+       d->current_node = dd->parent_node;
+
+       scf_logi("\033[31m do: %d, dd: %p, s->size: %d\033[0m\n", dd->_do->w->line, dd, s->size);
+
+       free(dd);
+       dd = NULL;
+
+       assert(s->size >= 0);
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_init_module_do(scf_dfa_t* dfa)
+{
+       SCF_DFA_MODULE_NODE(dfa, do, semicolon, scf_dfa_is_semicolon, _do_action_semicolon);
+
+       SCF_DFA_MODULE_NODE(dfa, do, lp,        scf_dfa_is_lp,        _do_action_lp);
+       SCF_DFA_MODULE_NODE(dfa, do, rp,        scf_dfa_is_rp,        _do_action_rp);
+       SCF_DFA_MODULE_NODE(dfa, do, lp_stat,   scf_dfa_is_lp,        _do_action_lp_stat);
+
+       SCF_DFA_MODULE_NODE(dfa, do, _do,       scf_dfa_is_do,        _do_action_do);
+       SCF_DFA_MODULE_NODE(dfa, do, _while,    scf_dfa_is_while,     _do_action_while);
+
+       scf_parse_t*      parse = dfa->priv;
+       dfa_parse_data_t* d     = parse->dfa_data;
+       scf_stack_t*      s     = d->module_datas[dfa_module_do.index];
+
+       assert(!s);
+
+       s = scf_stack_alloc();
+       if (!s) {
+               scf_logi("\n");
+               return SCF_DFA_ERROR;
+       }
+
+       d->module_datas[dfa_module_do.index] = s;
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_fini_module_do(scf_dfa_t* dfa)
+{
+       scf_parse_t*      parse = dfa->priv;
+       dfa_parse_data_t* d     = parse->dfa_data;
+       scf_stack_t*      s     = d->module_datas[dfa_module_do.index];
+
+       if (s) {
+               scf_stack_free(s);
+               s = NULL;
+               d->module_datas[dfa_module_do.index] = NULL;
+       }
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_init_syntax_do(scf_dfa_t* dfa)
+{
+       SCF_DFA_GET_MODULE_NODE(dfa, do,   lp,         lp);
+       SCF_DFA_GET_MODULE_NODE(dfa, do,   rp,         rp);
+       SCF_DFA_GET_MODULE_NODE(dfa, do,   lp_stat,    lp_stat);
+       SCF_DFA_GET_MODULE_NODE(dfa, do,  _do,        _do);
+       SCF_DFA_GET_MODULE_NODE(dfa, do,  _while,     _while);
+       SCF_DFA_GET_MODULE_NODE(dfa, do,   semicolon,  semicolon);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, expr,  entry,     expr);
+       SCF_DFA_GET_MODULE_NODE(dfa, block, entry,     block);
+
+       // do start
+       scf_vector_add(dfa->syntaxes,   _do);
+
+       scf_dfa_node_add_child(_do,      block);
+       scf_dfa_node_add_child(block,   _while);
+
+       scf_dfa_node_add_child(_while,   lp);
+       scf_dfa_node_add_child(lp,       expr);
+       scf_dfa_node_add_child(expr,     rp);
+       scf_dfa_node_add_child(rp,       semicolon);
+
+       scf_logi("\n");
+       return 0;
+}
+
+scf_dfa_module_t dfa_module_do =
+{
+       .name        = "do",
+
+       .init_module = _dfa_init_module_do,
+       .init_syntax = _dfa_init_syntax_do,
+
+       .fini_module = _dfa_fini_module_do,
+};
diff --git a/parse/scf_dfa_error.c b/parse/scf_dfa_error.c
deleted file mode 100644 (file)
index 3416e8a..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-#include"scf_dfa.h"
-#include"scf_dfa_util.h"
-#include"scf_parse.h"
-
-extern scf_dfa_module_t dfa_module_error;
-
-typedef struct {
-       scf_node_t* error;
-
-} error_module_data_t;
-
-static int _error_is_error(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_ERROR == w->type;
-}
-
-static int _error_action_error(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*         parse = dfa->priv;
-       dfa_parse_data_t*    d     = data;
-       error_module_data_t* md    = d->module_datas[dfa_module_error.index];
-       scf_lex_word_t*      w     = words->data[words->size - 1];
-
-       if (d->expr) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       scf_node_t* error = scf_node_alloc(w, SCF_OP_ERROR, NULL);
-       if (!error) {
-               scf_loge("node alloc failed\n");
-               return SCF_DFA_ERROR;
-       }
-
-       if (d->current_node)
-               scf_node_add_child(d->current_node, error);
-       else
-               scf_node_add_child((scf_node_t*)parse->ast->current_block, error);
-
-       md->error = error;
-       d->expr_local_flag = 1;
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "error_semicolon"), SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "error_comma"),     SCF_DFA_HOOK_POST);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _error_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*         parse = dfa->priv;
-       dfa_parse_data_t*    d     = data;
-       error_module_data_t* md    = d->module_datas[dfa_module_error.index];
-
-       if (!d->expr) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       scf_node_add_child(md->error, d->expr);
-       d->expr = NULL;
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "error_comma"),     SCF_DFA_HOOK_POST);
-
-       return SCF_DFA_SWITCH_TO;
-}
-
-static int _error_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*         parse = dfa->priv;
-       dfa_parse_data_t*    d     = data;
-       error_module_data_t* md    = d->module_datas[dfa_module_error.index];
-
-       if (!d->expr) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       scf_node_add_child(md->error, d->expr);
-       d->expr = NULL;
-
-       if (md->error->nb_nodes < 3) {
-
-               scf_type_t* t = NULL;
-
-               if (scf_ast_find_type_type(&t, parse->ast, SCF_VAR_INT) < 0)
-                       return SCF_DFA_ERROR;
-               assert(t);
-
-               scf_expr_t* e = scf_expr_alloc();
-
-               scf_variable_t* var = SCF_VAR_ALLOC_BY_TYPE(md->error->w, t, 1, 0, NULL);
-               SCF_CHECK_ERROR(!var, SCF_DFA_ERROR, "add default error code -1 failed\n");
-               var->const_literal_flag = 1;
-               var->data.i = -1;
-
-               scf_node_t* node = scf_node_alloc(NULL, var->type, var);
-               SCF_CHECK_ERROR(!node, SCF_DFA_ERROR, "add default error code -1 failed\n");
-
-               scf_expr_add_node(e, node);
-               scf_node_add_child(md->error, e);
-               e = NULL;
-       }
-
-       d->expr_local_flag = 0;
-       md->error = NULL;
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_init_module_error(scf_dfa_t* dfa)
-{
-       SCF_DFA_MODULE_NODE(dfa, error, semicolon, scf_dfa_is_semicolon, _error_action_semicolon);
-       SCF_DFA_MODULE_NODE(dfa, error, comma,     scf_dfa_is_comma,     _error_action_comma);
-       SCF_DFA_MODULE_NODE(dfa, error, error,     _error_is_error,      _error_action_error);
-
-       scf_parse_t*         parse = dfa->priv;
-       dfa_parse_data_t*    d     = parse->dfa_data;
-       error_module_data_t* md    = d->module_datas[dfa_module_error.index];
-
-       assert(!md);
-
-       md = calloc(1, sizeof(error_module_data_t));
-       if (!md) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       d->module_datas[dfa_module_error.index] = md;
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_fini_module_error(scf_dfa_t* dfa)
-{
-       scf_parse_t*         parse = dfa->priv;
-       dfa_parse_data_t*    d     = parse->dfa_data;
-       error_module_data_t* md    = d->module_datas[dfa_module_error.index];
-
-       if (md) {
-               free(md);
-               md = NULL;
-               d->module_datas[dfa_module_error.index] = NULL;
-       }
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_init_syntax_error(scf_dfa_t* dfa)
-{
-       SCF_DFA_GET_MODULE_NODE(dfa, error,   semicolon, semicolon);
-       SCF_DFA_GET_MODULE_NODE(dfa, error,   comma,     comma);
-       SCF_DFA_GET_MODULE_NODE(dfa, error,   error,     error);
-       SCF_DFA_GET_MODULE_NODE(dfa, expr,    entry,     expr);
-
-       scf_dfa_node_add_child(error,    expr);
-       scf_dfa_node_add_child(expr,     comma);
-       scf_dfa_node_add_child(comma,    expr);
-       scf_dfa_node_add_child(expr,     semicolon);
-
-       scf_loge("\n");
-       return 0;
-}
-
-scf_dfa_module_t dfa_module_error =
-{
-       .name        = "error",
-       .init_module = _dfa_init_module_error,
-       .init_syntax = _dfa_init_syntax_error,
-
-       .fini_module = _dfa_fini_module_error,
-};
-
index 7ec70b42bbeb01cb8f26744e1b4ffb98af2e93c4..3970233e4f0765688a37ff9a7538ac36daca222f 100644 (file)
@@ -19,16 +19,8 @@ typedef struct {
        scf_expr_t*      cond_expr;
        scf_vector_t*    update_exprs;
 
-       scf_dfa_hook_t*  hook_end;
-
 } dfa_for_data_t;
 
-static int _for_is_for(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_FOR == w->type;
-}
 
 static int _for_is_end(scf_dfa_t* dfa, void* word)
 {
@@ -270,7 +262,7 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        _for_add_exprs(fd);
        d->expr_local_flag = 0;
 
-       fd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_end"), SCF_DFA_HOOK_END);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_end"), SCF_DFA_HOOK_END);
 
        return SCF_DFA_SWITCH_TO;
 }
@@ -291,8 +283,7 @@ static int _for_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        d->current_node = fd->parent_node;
 
-       scf_logi("\033[31m for: %d, fd: %p, hook_end: %p, s->size: %d\033[0m\n",
-                       fd->_for->w->line, fd, fd->hook_end, s->size);
+       scf_logi("\033[31m for: %d, fd: %p, s->size: %d\033[0m\n", fd->_for->w->line, fd, s->size);
 
        free(fd);
        fd = NULL;
@@ -312,7 +303,7 @@ static int _dfa_init_module_for(scf_dfa_t* dfa)
        SCF_DFA_MODULE_NODE(dfa, for, lp_stat,   scf_dfa_is_lp,         _for_action_lp_stat);
        SCF_DFA_MODULE_NODE(dfa, for, rp,        scf_dfa_is_rp,         _for_action_rp);
 
-       SCF_DFA_MODULE_NODE(dfa, for, _for,      _for_is_for,           _for_action_for);
+       SCF_DFA_MODULE_NODE(dfa, for, _for,      scf_dfa_is_for,        _for_action_for);
 
        scf_parse_t*      parse = dfa->priv;
        dfa_parse_data_t* d     = parse->dfa_data;
index 7485eea533465f2096b04cd76e2d32513103594a..33076e4b24bd9454df5bdaf9352b3a438280b31f 100644 (file)
@@ -8,8 +8,6 @@ typedef struct {
 
        scf_block_t*     parent_block;
 
-       scf_dfa_hook_t*  hook_end;
-
 } dfa_fun_data_t;
 
 int _function_add_function(scf_dfa_t* dfa, dfa_parse_data_t* d)
@@ -323,8 +321,7 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                scf_node_add_child((scf_node_t*)parse->ast->current_block, (scf_node_t*)d->current_function);
        }
 
-       fd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_end"), SCF_DFA_HOOK_END);
-       assert(fd->hook_end);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_end"), SCF_DFA_HOOK_END);
 
        fd->parent_block = parse->ast->current_block;
        parse->ast->current_block = (scf_block_t*)d->current_function;
@@ -345,7 +342,6 @@ static int _function_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                d->current_function->node.define_flag = 1;
 
        fd->parent_block = NULL;
-       fd->hook_end     = NULL;
 
        d->current_function = NULL;
        d->argc   = 0;
index 40869d4558ac8616de023e271d1364054f4951a7..176b067b547b510422d6e9c46349c6d7cac80b10 100644 (file)
@@ -4,13 +4,6 @@
 
 extern scf_dfa_module_t dfa_module_goto;
 
-static int _goto_is_goto(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_GOTO == w->type;
-}
-
 static int _goto_action_goto(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*      parse  = dfa->priv;
@@ -58,7 +51,7 @@ static int _goto_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* dat
 
 static int _dfa_init_module_goto(scf_dfa_t* dfa)
 {
-       SCF_DFA_MODULE_NODE(dfa, goto, _goto,     _goto_is_goto,        _goto_action_goto);
+       SCF_DFA_MODULE_NODE(dfa, goto, _goto,     scf_dfa_is_goto,      _goto_action_goto);
        SCF_DFA_MODULE_NODE(dfa, goto, identity,  scf_dfa_is_identity,  _goto_action_identity);
        SCF_DFA_MODULE_NODE(dfa, goto, semicolon, scf_dfa_is_semicolon, _goto_action_semicolon);
 
index 409e66e4b0691901deef77c6600408ded2235e56..dc50c611f7d5e934d63c61a6fd76c10d3f40d383 100644 (file)
@@ -1,4 +1,5 @@
 #include"scf_dfa.h"
+#include"scf_dfa_util.h"
 #include"scf_parse.h"
 #include"scf_stack.h"
 
@@ -16,37 +17,8 @@ typedef struct {
        scf_lex_word_t*  prev_else;
        scf_lex_word_t*  next_else;
 
-       scf_dfa_hook_t*  hook_end;
-
 } dfa_if_data_t;
 
-static int _if_is_lp(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_LP == w->type;
-}
-
-static int _if_is_rp(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_RP == w->type;
-}
-
-static int _if_is_if(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_IF == w->type;
-}
-
-static int _if_is_else(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_ELSE == w->type;
-}
 
 static int _if_is_end(scf_dfa_t* dfa, void* word)
 {
@@ -178,7 +150,7 @@ static int _if_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                d->expr_local_flag = 0;
 
-               ifd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END);
+               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END);
                return SCF_DFA_SWITCH_TO;
        }
 
@@ -212,7 +184,7 @@ static int _if_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                        if (1 == s->size)
                                return SCF_DFA_NEXT_WORD;
                } else {
-                       ifd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END);
+                       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END);
                        return SCF_DFA_NEXT_WORD;
                }
        }
@@ -223,8 +195,7 @@ static int _if_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        d->current_node = ifd->parent_node;
 
-       scf_logi("\033[31m if: %d, ifd: %p, hook_end: %p, s->size: %d\033[0m\n",
-                       ifd->_if->w->line, ifd, ifd->hook_end, s->size);
+       scf_logi("\033[31m if: %d, ifd: %p, s->size: %d\033[0m\n", ifd->_if->w->line, ifd, s->size);
 
        free(ifd);
        ifd = NULL;
@@ -238,12 +209,12 @@ static int _dfa_init_module_if(scf_dfa_t* dfa)
 {
        SCF_DFA_MODULE_NODE(dfa, if, end,       _if_is_end,       _if_action_end);
 
-       SCF_DFA_MODULE_NODE(dfa, if, lp,        _if_is_lp,        _if_action_lp);
-       SCF_DFA_MODULE_NODE(dfa, if, rp,        _if_is_rp,        _if_action_rp);
-       SCF_DFA_MODULE_NODE(dfa, if, lp_stat,   _if_is_lp,        _if_action_lp_stat);
+       SCF_DFA_MODULE_NODE(dfa, if, lp,        scf_dfa_is_lp,    _if_action_lp);
+       SCF_DFA_MODULE_NODE(dfa, if, rp,        scf_dfa_is_rp,    _if_action_rp);
+       SCF_DFA_MODULE_NODE(dfa, if, lp_stat,   scf_dfa_is_lp,    _if_action_lp_stat);
 
-       SCF_DFA_MODULE_NODE(dfa, if, _if,       _if_is_if,        _if_action_if);
-       SCF_DFA_MODULE_NODE(dfa, if, _else,     _if_is_else,      _if_action_else);
+       SCF_DFA_MODULE_NODE(dfa, if, _if,       scf_dfa_is_if,    _if_action_if);
+       SCF_DFA_MODULE_NODE(dfa, if, _else,     scf_dfa_is_else,  _if_action_else);
 
        scf_parse_t*      parse = dfa->priv;
        dfa_parse_data_t* d     = parse->dfa_data;
@@ -307,7 +278,7 @@ static int _dfa_init_syntax_if(scf_dfa_t* dfa)
        // last else block
        scf_dfa_node_add_child(_else,  block);
 
-       scf_loge("\n");
+       scf_logi("\n");
        return 0;
 }
 
index 1367eeaf410de1e5d363ad3fa5b9fcc9a9b1b8e1..20e5fe8e83c2afe57df8e030407afb475ee575cd 100644 (file)
@@ -4,13 +4,6 @@
 
 extern scf_dfa_module_t dfa_module_include;
 
-static int _include_is_include(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_INCLUDE == w->type;
-}
-
 static int _include_action_include(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*      parse  = dfa->priv;
@@ -57,7 +50,7 @@ static int _include_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void*
 
 static int _dfa_init_module_include(scf_dfa_t* dfa)
 {
-       SCF_DFA_MODULE_NODE(dfa, include, include,   _include_is_include,     _include_action_include);
+       SCF_DFA_MODULE_NODE(dfa, include, include,   scf_dfa_is_include,      _include_action_include);
        SCF_DFA_MODULE_NODE(dfa, include, path,      scf_dfa_is_const_string, _include_action_path);
        SCF_DFA_MODULE_NODE(dfa, include, semicolon, scf_dfa_is_semicolon,    _include_action_semicolon);
 
index b1339099e782eebf219e2137561272553f03bba4..22f50c64031d165aac96f392f701a8e9606ad187 100644 (file)
@@ -1,15 +1,9 @@
 #include"scf_dfa.h"
+#include"scf_dfa_util.h"
 #include"scf_parse.h"
 
 extern scf_dfa_module_t dfa_module_label;
 
-static int _label_is_colon(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_COLON == w->type;
-}
-
 static int _label_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*      parse  = dfa->priv;
@@ -37,7 +31,7 @@ static int _label_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
 static int _dfa_init_module_label(scf_dfa_t* dfa)
 {
-       SCF_DFA_MODULE_NODE(dfa, label, label,  _label_is_colon, _label_action_colon);
+       SCF_DFA_MODULE_NODE(dfa, label, label,  scf_dfa_is_colon, _label_action_colon);
 
        return SCF_DFA_OK;
 }
@@ -57,4 +51,3 @@ scf_dfa_module_t dfa_module_label =
        .init_module = _dfa_init_module_label,
        .init_syntax = _dfa_init_syntax_label,
 };
-
index 39fd4801f4ef39205b22bd0af39c5517abc50e12..cbd2698283101291a62b375c6244ca7be3680cc4 100644 (file)
@@ -10,8 +10,6 @@ typedef struct {
 
        scf_lex_word_t*  word_op;
 
-       scf_dfa_hook_t*  hook_end;
-
 } dfa_op_data_t;
 
 static int _operator_is_key(scf_dfa_t* dfa, void* word)
@@ -270,8 +268,7 @@ static int _operator_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                scf_node_add_child((scf_node_t*)parse->ast->current_block, (scf_node_t*)d->current_function);
        }
 
-       opd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_end"), SCF_DFA_HOOK_END);
-       assert(opd->hook_end);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_end"), SCF_DFA_HOOK_END);
 
        opd->parent_block = parse->ast->current_block;
        parse->ast->current_block = (scf_block_t*)d->current_function;
@@ -292,7 +289,6 @@ static int _operator_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                d->current_function->node.define_flag = 1;
 
        opd->parent_block = NULL;
-       opd->hook_end     = NULL;
 
        d->current_function = NULL;
        d->argc   = 0;
index dcfee6a84ce84f160a03d69249ccd57ea36aeb7b..5a4e61c07bdb484bbe88b717ffb25d8be96bfff8 100644 (file)
@@ -25,8 +25,9 @@ extern scf_dfa_module_t  dfa_module_operator;
 
 extern scf_dfa_module_t  dfa_module_if;
 extern scf_dfa_module_t  dfa_module_while;
-extern scf_dfa_module_t  dfa_module_repeat;
+extern scf_dfa_module_t  dfa_module_do;
 extern scf_dfa_module_t  dfa_module_for;
+extern scf_dfa_module_t  dfa_module_switch;
 
 #if 1
 extern scf_dfa_module_t  dfa_module_break;
@@ -34,7 +35,6 @@ extern scf_dfa_module_t  dfa_module_continue;
 extern scf_dfa_module_t  dfa_module_return;
 extern scf_dfa_module_t  dfa_module_goto;
 extern scf_dfa_module_t  dfa_module_label;
-extern scf_dfa_module_t  dfa_module_error;
 extern scf_dfa_module_t  dfa_module_async;
 #endif
 extern scf_dfa_module_t  dfa_module_block;
@@ -65,8 +65,9 @@ scf_dfa_module_t* dfa_modules[] =
 
        &dfa_module_if,
        &dfa_module_while,
-       &dfa_module_repeat,
+       &dfa_module_do,
        &dfa_module_for,
+       &dfa_module_switch,
 
 #if 1
        &dfa_module_break,
@@ -74,7 +75,6 @@ scf_dfa_module_t* dfa_modules[] =
        &dfa_module_goto,
        &dfa_module_return,
        &dfa_module_label,
-       &dfa_module_error,
        &dfa_module_async,
 #endif
        &dfa_module_block,
diff --git a/parse/scf_dfa_repeat.c b/parse/scf_dfa_repeat.c
deleted file mode 100644 (file)
index 15ee163..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-#include"scf_dfa.h"
-#include"scf_dfa_util.h"
-#include"scf_parse.h"
-#include"scf_stack.h"
-
-extern scf_dfa_module_t dfa_module_repeat;
-
-typedef struct {
-       int              nb_lps;
-       int              nb_rps;
-
-       scf_block_t*     parent_block;
-       scf_node_t*      parent_node;
-
-       scf_node_t*      repeat;
-
-       scf_dfa_hook_t*  hook_end;
-
-} dfa_repeat_data_t;
-
-
-static int _repeat_action_do(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = data;
-       scf_lex_word_t*   w     = words->data[words->size - 1];
-       scf_stack_t*      s     = d->module_datas[dfa_module_repeat.index];
-       scf_block_t*      b     = NULL;
-
-       scf_node_t*     repeat  = scf_node_alloc(w, SCF_OP_REPEAT, NULL);
-       if (!repeat) {
-               scf_loge("node alloc failed\n");
-               return SCF_DFA_ERROR;
-       }
-
-       dfa_repeat_data_t* rd = calloc(1, sizeof(dfa_repeat_data_t));
-       if (!rd) {
-               scf_loge("module data alloc failed\n");
-               return SCF_DFA_ERROR;
-       }
-
-       if (d->current_node)
-               scf_node_add_child(d->current_node, repeat);
-       else
-               scf_node_add_child((scf_node_t*)parse->ast->current_block, repeat);
-
-       rd->repeat       = repeat;
-       rd->parent_block = parse->ast->current_block;
-       rd->parent_node  = d->current_node;
-       d->current_node  = repeat;
-
-       scf_stack_push(s, rd);
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat__while"),  SCF_DFA_HOOK_END);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _repeat_action_while(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_lex_word_t* w = dfa->ops->pop_word(dfa);
-
-       if (SCF_LEX_WORD_KEY_WHILE != w->type)
-               return SCF_DFA_ERROR;
-
-       return SCF_DFA_SWITCH_TO;
-}
-
-static int _repeat_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*       parse = dfa->priv;
-       dfa_parse_data_t*  d     = data;
-       scf_lex_word_t*    w     = words->data[words->size - 1];
-       scf_stack_t*       s     = d->module_datas[dfa_module_repeat.index];
-       dfa_repeat_data_t* rd    = scf_stack_top(s);
-
-       assert(!d->expr);
-       d->expr_local_flag = 1;
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_rp"),      SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _repeat_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       dfa_parse_data_t*  d     = data;
-       scf_stack_t*       s     = d->module_datas[dfa_module_repeat.index];
-       dfa_repeat_data_t* rd    = scf_stack_top(s);
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST);
-
-       rd->nb_lps++;
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _repeat_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*       parse = dfa->priv;
-       dfa_parse_data_t*  d     = data;
-       scf_lex_word_t*    w     = words->data[words->size - 1];
-       scf_stack_t*       s     = d->module_datas[dfa_module_repeat.index];
-       dfa_repeat_data_t* rd    = scf_stack_top(s);
-
-       if (!d->expr) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       rd->nb_rps++;
-
-       if (rd->nb_rps == rd->nb_lps) {
-
-               assert(1 == rd->repeat->nb_nodes);
-
-               scf_node_add_child(rd->repeat, d->expr);
-               d->expr = NULL;
-
-               d->expr_local_flag = 0;
-
-               return SCF_DFA_SWITCH_TO;
-       }
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_rp"),      SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _repeat_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*       parse = dfa->priv;
-       dfa_parse_data_t*  d     = data;
-       scf_stack_t*       s     = d->module_datas[dfa_module_repeat.index];
-       dfa_repeat_data_t* rd    = scf_stack_pop(s);
-
-       assert(parse->ast->current_block == rd->parent_block);
-
-       d->current_node = rd->parent_node;
-
-       scf_logi("\033[31m repeat: %d, rd: %p, s->size: %d\033[0m\n", rd->repeat->w->line, rd, s->size);
-
-       free(rd);
-       rd = NULL;
-
-       assert(s->size >= 0);
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_init_module_repeat(scf_dfa_t* dfa)
-{
-       SCF_DFA_MODULE_NODE(dfa, repeat, semicolon, scf_dfa_is_semicolon, _repeat_action_semicolon);
-
-       SCF_DFA_MODULE_NODE(dfa, repeat, lp,        scf_dfa_is_lp,        _repeat_action_lp);
-       SCF_DFA_MODULE_NODE(dfa, repeat, rp,        scf_dfa_is_rp,        _repeat_action_rp);
-       SCF_DFA_MODULE_NODE(dfa, repeat, lp_stat,   scf_dfa_is_lp,        _repeat_action_lp_stat);
-
-       SCF_DFA_MODULE_NODE(dfa, repeat, _do,       scf_dfa_is_do,        _repeat_action_do);
-       SCF_DFA_MODULE_NODE(dfa, repeat, _while,    scf_dfa_is_while,     _repeat_action_while);
-
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = parse->dfa_data;
-       scf_stack_t*      s     = d->module_datas[dfa_module_repeat.index];
-
-       assert(!s);
-
-       s = scf_stack_alloc();
-       if (!s) {
-               scf_logi("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       d->module_datas[dfa_module_repeat.index] = s;
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_fini_module_repeat(scf_dfa_t* dfa)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = parse->dfa_data;
-       scf_stack_t*      s     = d->module_datas[dfa_module_repeat.index];
-
-       if (s) {
-               scf_stack_free(s);
-               s = NULL;
-               d->module_datas[dfa_module_repeat.index] = NULL;
-       }
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_init_syntax_repeat(scf_dfa_t* dfa)
-{
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,   lp,         lp);
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,   rp,         rp);
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,   lp_stat,    lp_stat);
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,  _do,        _do);
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,  _while,     _while);
-       SCF_DFA_GET_MODULE_NODE(dfa, repeat,   semicolon,  semicolon);
-
-       SCF_DFA_GET_MODULE_NODE(dfa, expr,  entry,     expr);
-       SCF_DFA_GET_MODULE_NODE(dfa, block, entry,     block);
-
-       // repeat start
-       scf_vector_add(dfa->syntaxes,   _do);
-
-       scf_dfa_node_add_child(_do,      block);
-       scf_dfa_node_add_child(block,   _while);
-
-       scf_dfa_node_add_child(_while,   lp);
-       scf_dfa_node_add_child(lp,       expr);
-       scf_dfa_node_add_child(expr,     rp);
-       scf_dfa_node_add_child(rp,       semicolon);
-
-       scf_logi("\n");
-       return 0;
-}
-
-scf_dfa_module_t dfa_module_repeat =
-{
-       .name        = "repeat",
-
-       .init_module = _dfa_init_module_repeat,
-       .init_syntax = _dfa_init_syntax_repeat,
-
-       .fini_module = _dfa_fini_module_repeat,
-};
-
index 26098b671dadf0559ccb8ed4769a835b8e4c00e8..a3915f3d6d9eb963b0c5214e59b74c04cd969900 100644 (file)
@@ -4,13 +4,6 @@
 
 extern scf_dfa_module_t dfa_module_return;
 
-static int _return_is_return(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_RETURN == w->type;
-}
-
 static int _return_action_return(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*      parse   = dfa->priv;
@@ -84,7 +77,7 @@ static int _dfa_init_module_return(scf_dfa_t* dfa)
 {
        SCF_DFA_MODULE_NODE(dfa, return, semicolon, scf_dfa_is_semicolon, _return_action_semicolon);
        SCF_DFA_MODULE_NODE(dfa, return, comma,     scf_dfa_is_comma,     _return_action_comma);
-       SCF_DFA_MODULE_NODE(dfa, return, _return,   _return_is_return,    _return_action_return);
+       SCF_DFA_MODULE_NODE(dfa, return, _return,   scf_dfa_is_return,    _return_action_return);
 
        return SCF_DFA_OK;
 }
diff --git a/parse/scf_dfa_struct.c b/parse/scf_dfa_struct.c
deleted file mode 100644 (file)
index 67f199b..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-#include"scf_dfa.h"
-#include"scf_dfa_util.h"
-#include"scf_parse.h"
-
-extern scf_dfa_module_t dfa_module_struct;
-
-static int _struct_is__struct(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-       return SCF_LEX_WORD_KEY_STRUCT == w->type;
-}
-
-static int _struct_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       scf_lex_word_t*   w1    = words->data[words->size - 1];
-       scf_type_t*       t     = NULL;
-       dfa_parse_data_t* d     = data;
-
-       if (!d->root_struct) {
-               t = scf_block_find_type(parse->ast->current_block, w1->text->data);
-               if (!t) {
-                       t = scf_type_alloc(w1, w1->text->data, SCF_STRUCT + parse->ast->nb_structs++, 0);
-                       if (!t) {
-                               scf_loge("\n");
-                               return SCF_DFA_ERROR;
-                       }
-
-                       scf_scope_push_type(parse->ast->current_block->scope, t);
-               } else {
-                       if (t->type < SCF_STRUCT) {
-                               scf_loge("struct name '%s' is same to base type\n", w1->text->data);
-                               return SCF_DFA_ERROR;
-                       }
-               }
-
-               d->root_struct      = t;
-               d->current_struct   = t;
-               d->current_type = t;
-               d->nb_lbs           = 0;
-               d->nb_rbs           = 0;
-
-               scf_logd("t: %p, d->current_type: %p\n", t, d->current_type);
-       } else {
-               if (!d->current_struct) {
-                       scf_loge("\n");
-                       return SCF_DFA_ERROR;
-               }
-
-               if (!d->current_struct->scope) {
-                       scf_loge("\n");
-                       return SCF_DFA_ERROR;
-               }
-
-               t = d->current_struct;
-               while (t) {
-                       if (!strcmp(w1->text->data, t->name->data))
-                               break;
-                       t = t->parent;
-               }
-
-               if (!t) {
-                       t = scf_scope_find_type(d->current_struct->scope, w1->text->data);
-                       if (!t) {
-                               t = scf_type_alloc(w1, w1->text->data, SCF_STRUCT + parse->ast->nb_structs++, 0);
-                               if (!t) {
-                                       printf("%s(), %d, error: \n", __func__, __LINE__);
-                                       return SCF_DFA_ERROR;
-                               }
-
-                               scf_scope_push_type(d->current_struct->scope, t);
-
-                               t->parent = d->current_struct;
-                       }
-               }
-
-               d->current_type = t;
-               scf_logd("t: %p, d->current_type: %p\n", t, d->current_type);
-       }
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t* parse = dfa->priv;
-
-       if (words->size < 3) {
-               printf("%s(), %d, words->size: %d\n", __func__, __LINE__, words->size);
-               return SCF_DFA_ERROR;
-       }
-
-       scf_lex_word_t* w0 = words->data[words->size - 3];
-       scf_lex_word_t* w1 = words->data[words->size - 2];
-       scf_lex_word_t* w2 = words->data[words->size - 1];
-
-       if (SCF_LEX_WORD_ASSIGN == w1->type)
-               return SCF_DFA_NEXT_SYNTAX;
-
-       assert(SCF_LEX_WORD_KEY_STRUCT == w0->type);
-
-       scf_type_t*        t = NULL;
-       dfa_parse_data_t*  d = data;
-
-       if (0 == d->nb_lbs) {
-               t = scf_block_find_type(parse->ast->current_block, w1->text->data);
-
-       } else if (d->nb_lbs > 0) {
-               t = scf_scope_find_type(d->current_struct->scope, w1->text->data);
-
-       } else {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       if (!t) {
-               scf_loge("type '%s' not found\n", w1->text->data);
-               return SCF_DFA_ERROR;
-       }
-
-       if (t->scope) {
-               scf_loge("repeated define struct '%s'\n", w1->text->data);
-               return SCF_DFA_ERROR;
-       }
-
-       t->scope = scf_scope_alloc(w2, t->name->data);
-       if (!t->scope) {
-               scf_loge("scope alloc failed\n");
-               return SCF_DFA_ERROR;
-       }
-
-       d->current_struct = t;
-       d->nb_lbs++;
-
-       scf_logi("t: %p, d->current_type: %p\n", t, d->current_type);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static scf_type_t* _struct_find_proper_type(scf_dfa_t* dfa, scf_type_t* s, int type)
-{
-       scf_parse_t* parse = dfa->priv;
-
-       char* name = NULL;
-       while (s) {
-               assert(s->scope);
-
-               scf_type_t* t = scf_scope_find_type_type(s->scope, type);
-               if (!t)
-                       continue;
-
-               name = t->name->data;
-               if (t->scope) {
-                       return t;
-               }
-
-               s = s->parent;
-       }
-
-       scf_type_t* t = scf_block_find_type_type(parse->ast->current_block, type);
-       if (!t)
-               t = scf_block_find_type(parse->ast->current_block, name);
-
-       return t;
-}
-
-static int _struct_calculate_size(scf_dfa_t* dfa, scf_type_t* s)
-{
-       scf_parse_t* parse = dfa->priv;
-
-       int size = 0;
-       int i;
-       for (i = 0; i < s->scope->vars->size; i++) {
-
-               scf_variable_t* v = s->scope->vars->data[i];
-
-               if (v->size <= 0) {
-                       assert(0 == v->nb_pointers);
-
-                       if (v->type < SCF_STRUCT) {
-                               scf_loge("v: '%s'\n", v->w->text->data);
-                               return SCF_DFA_ERROR;
-                       }
-
-                       scf_type_t* t = _struct_find_proper_type(dfa, s, v->type);
-                       if (!t) {
-                               scf_loge("can't find proper type of v: '%s'\n", v->w->text->data);
-                               return SCF_DFA_ERROR;
-                       }
-
-                       v->type = t->type;
-                       v->size = t->size;
-               }
-
-               int align;
-               if (1 == v->size)
-                       align = 1;
-               else if (2 == v->size)
-                       align = 2;
-               else if (v->size <= 4)
-                       align = 4;
-               else
-                       align = 8;
-
-               v->offset = (size + align - 1) / align * align;
-
-               if (v->nb_dimentions > 0) {
-                       int j;
-                       int capacity = 1;
-
-                       for (j = 0; j < v->nb_dimentions; j++) {
-                               if (v->dimentions[j] < 0) {
-                                       scf_loge("v: '%s'\n", v->w->text->data);
-                                       return SCF_DFA_ERROR;
-
-                               } else if (0 == v->dimentions[j]) {
-
-                                       if (j < v->nb_dimentions - 1) {
-                                               scf_loge("v: '%s'\n", v->w->text->data);
-                                               return SCF_DFA_ERROR;
-                                       }
-                               }
-
-                               capacity *= v->dimentions[j];
-                       }
-
-                       v->capacity = capacity;
-                       size = v->offset + v->size * v->capacity;
-               } else {
-                       size = v->offset + v->size;
-               }
-
-               scf_logi("struct '%s', member: '%s', offset: %d, size: %d, v->dim: %d, v->capacity: %d\n",
-                               s->name->data, v->w->text->data, v->offset, v->size, v->nb_dimentions, v->capacity);
-       }
-       s->size = size;
-
-       scf_logi("struct '%s', size: %d\n", s->name->data, s->size);
-       return 0;
-}
-
-static int _struct_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = data;
-
-       if (_struct_calculate_size(dfa, d->current_struct) < 0) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       d->current_type = d->current_struct;
-       d->current_struct   = d->current_struct->parent;
-       d->nb_rbs++;
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = data;
-
-       if (!d->current_var) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       assert(!d->expr);
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "struct_rs"), SCF_DFA_HOOK_POST);
-
-       d->nb_lss++;
-
-       scf_variable_add_array_dimention(d->current_var, -1);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = data;
-
-       if (!d->current_var) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       if (!d->expr) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       while (d->expr->parent)
-               d->expr = d->expr->parent;
-
-       scf_variable_t* r = NULL;
-       if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       assert(d->nb_rss < d->current_var->nb_dimentions);
-       d->current_var->dimentions[d->nb_rss] = r->data.i;
-
-       scf_loge("d->expr: %p, r->data.i: %d\n", d->expr, r->data.i);
-
-       d->nb_rss++;
-       assert(d->nb_rss == d->nb_lss);
-
-       scf_expr_free(d->expr);
-       d->expr = NULL;
-
-       scf_variable_free(r);
-       r = NULL;
-
-       return SCF_DFA_SWITCH_TO;
-}
-
-static int _struct_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       dfa_parse_data_t* d = data;
-
-       d->nb_pointers = 0;
-       d->const_flag  = 0;
-
-       if (d->nb_rbs == d->nb_lbs) {
-               scf_logi("SCF_DFA_OK\n");
-
-               d->root_struct      = NULL;
-               d->current_struct   = NULL;
-               d->current_type = NULL;
-               d->nb_lbs           = 0;
-               d->nb_rbs           = 0;
-               return SCF_DFA_OK;
-
-       } else if (d->nb_rbs > d->nb_lbs) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       scf_logi("SCF_DFA_NEXT_WORD\n");
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       dfa_parse_data_t* d = data;
-
-       d->nb_pointers = 0;
-       d->const_flag  = 0;
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_star(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       dfa_parse_data_t* d = data;
-
-       d->nb_pointers++;
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_base_type(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = data;
-       scf_lex_word_t*   w     = words->data[words->size - 1];
-
-       d->current_type  = scf_block_find_type(parse->ast->current_block, w->text->data);
-       if (!d->current_type) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _struct_action_var(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       scf_parse_t*      parse = dfa->priv;
-       dfa_parse_data_t* d     = data;
-       scf_lex_word_t*   w     = words->data[words->size - 1];
-
-       scf_logi("w: %s\n", w->text->data);
-
-       scf_variable_t* var  = scf_scope_find_variable(d->current_struct->scope, w->text->data);
-       if (var) {
-               scf_loge("repeated declaration: %s\n", w->text->data);
-               return SCF_DFA_ERROR;
-       }
-
-       if (0 == d->nb_pointers) {
-               if (d->nb_rbs < d->nb_lbs) {
-
-                       scf_type_t* t = d->current_struct;
-
-                       scf_logd("t: %p, d->current_type: %p\n", t, d->current_type);
-
-                       while (t) {
-                               if (t->type == d->current_type->type) {
-
-                                       scf_loge("recursive member var declaration of struct type: %s, var name: %s\n",
-                                                       t->name->data, w->text->data);
-                                       return SCF_DFA_ERROR;
-                               }
-                               t = t->parent;
-                       }
-               }
-       }
-
-       var = SCF_VAR_ALLOC_BY_TYPE(w, d->current_type, 0, d->nb_pointers, NULL);
-       if (!var) {
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
-       }
-       scf_scope_push_var(d->current_struct->scope, var);
-
-       d->current_var = var;
-       d->nb_lss      = 0;
-       d->nb_rss      = 0;
-
-       scf_logi("type: %d, nb_pointers: %d, var: %s, line: %d, pos: %d\n\n",
-                       var->type, var->nb_pointers,
-                       var->w->text->data, var->w->line, var->w->pos);
-
-       return SCF_DFA_NEXT_WORD;
-}
-
-static int _dfa_init_module_struct(scf_dfa_t* dfa)
-{
-       SCF_DFA_MODULE_ENTRY(dfa, struct);
-
-       SCF_DFA_MODULE_NODE(dfa, struct, _struct,   _struct_is__struct,   NULL);
-       SCF_DFA_MODULE_NODE(dfa, struct, lb,        scf_dfa_is_lb,        _struct_action_lb);
-       SCF_DFA_MODULE_NODE(dfa, struct, rb,        scf_dfa_is_rb,        _struct_action_rb);
-       SCF_DFA_MODULE_NODE(dfa, struct, identity,  scf_dfa_is_identity,  _struct_action_identity);
-       SCF_DFA_MODULE_NODE(dfa, struct, semicolon, scf_dfa_is_semicolon, _struct_action_semicolon);
-
-       SCF_DFA_MODULE_NODE(dfa, struct, base_type, scf_dfa_is_base_type, _struct_action_base_type);
-       SCF_DFA_MODULE_NODE(dfa, struct, var,       scf_dfa_is_identity,  _struct_action_var);
-       SCF_DFA_MODULE_NODE(dfa, struct, star,      scf_dfa_is_star,      _struct_action_star);
-       SCF_DFA_MODULE_NODE(dfa, struct, comma,     scf_dfa_is_comma,     _struct_action_comma);
-
-       SCF_DFA_MODULE_NODE(dfa, struct, ls,        scf_dfa_is_ls,        _struct_action_ls);
-       SCF_DFA_MODULE_NODE(dfa, struct, rs,        scf_dfa_is_rs,        _struct_action_rs);
-
-       return SCF_DFA_OK;
-}
-
-static int _dfa_init_syntax_struct(scf_dfa_t* dfa)
-{
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, entry,     entry);
-
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, _struct,   _struct);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, lb,        lb);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, rb,        rb);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, identity,  identity);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, semicolon, semicolon);
-
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, base_type, base_type);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, var,       var);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, star,      star);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, comma,     comma);
-
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, ls,        ls);
-       SCF_DFA_GET_MODULE_NODE(dfa, struct, rs,        rs);
-
-       SCF_DFA_GET_MODULE_NODE(dfa, expr,    entry,     expr);
-
-
-       scf_vector_add(dfa->syntaxes, entry);
-       scf_dfa_node_add_child(entry,     _struct);
-
-       // struct start
-       scf_dfa_node_add_child(_struct,   identity);
-
-       // only struct declaration
-       scf_dfa_node_add_child(identity,  semicolon);
-
-       // struct define start
-       scf_dfa_node_add_child(identity,  lb);
-
-       // empty struct define
-       scf_dfa_node_add_child(lb,        rb);
-
-       // recursive internal struct define
-       scf_dfa_node_add_child(lb,         _struct);
-
-       // end current struct define, if root struct then end all struct define
-       scf_dfa_node_add_child(rb,        semicolon);
-
-       // recursive end struct define
-       scf_dfa_node_add_child(semicolon, rb);
-
-       // next internal struct define
-       scf_dfa_node_add_child(semicolon, _struct);
-
-       // internal base type member var declaration
-
-       scf_dfa_node_add_child(lb,        base_type);
-       // pointer var
-       scf_dfa_node_add_child(base_type, star);
-
-       // multi pointer var
-       scf_dfa_node_add_child(star,      star);
-       scf_dfa_node_add_child(star,      var);
-
-       // normal var
-       scf_dfa_node_add_child(base_type, var);
-
-       // continuous var in same line: int a, b, *p, **pp, etc;
-       scf_dfa_node_add_child(var,       comma);
-       scf_dfa_node_add_child(comma,     star);
-       scf_dfa_node_add_child(comma,     var);
-
-       // array var
-       scf_dfa_node_add_child(var,       ls);
-       scf_dfa_node_add_child(ls,        expr);
-       scf_dfa_node_add_child(expr,      rs);
-       scf_dfa_node_add_child(rs,        ls);
-       scf_dfa_node_add_child(rs,        semicolon);
-
-       // end base type var define
-       scf_dfa_node_add_child(var,       semicolon);
-
-       // next internal base type member var
-       scf_dfa_node_add_child(semicolon, base_type);
-
-       // struct type member var declaration 
-       scf_dfa_node_add_child(identity, star);
-       scf_dfa_node_add_child(identity, var);
-       scf_dfa_node_add_child(rb,       star);
-       scf_dfa_node_add_child(rb,       var);
-
-       scf_logi("\n");
-       return 0;
-}
-
-scf_dfa_module_t dfa_module_struct = 
-{
-       .name        = "struct",
-       .init_module = _dfa_init_module_struct,
-       .init_syntax = _dfa_init_syntax_struct,
-};
-
diff --git a/parse/scf_dfa_switch.c b/parse/scf_dfa_switch.c
new file mode 100644 (file)
index 0000000..589279a
--- /dev/null
@@ -0,0 +1,285 @@
+#include"scf_dfa.h"
+#include"scf_dfa_util.h"
+#include"scf_parse.h"
+#include"scf_stack.h"
+
+extern scf_dfa_module_t dfa_module_switch;
+
+typedef struct {
+       int              nb_lps;
+       int              nb_rps;
+
+       scf_block_t*     parent_block;
+       scf_node_t*      parent_node;
+
+       scf_node_t*      _switch;
+       scf_node_t*      child;
+
+} dfa_switch_data_t;
+
+static int _switch_is_end(scf_dfa_t* dfa, void* word)
+{
+       return 1;
+}
+
+static int _switch_action_switch(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*      parse = dfa->priv;
+       dfa_parse_data_t* d     = data;
+       scf_lex_word_t*   w     = words->data[words->size - 1];
+       scf_stack_t*      s     = d->module_datas[dfa_module_switch.index];
+
+       scf_node_t*     _switch = scf_node_alloc(w, SCF_OP_SWITCH, NULL);
+       if (!_switch) {
+               scf_loge("node alloc failed\n");
+               return SCF_DFA_ERROR;
+       }
+
+       dfa_switch_data_t* sd = calloc(1, sizeof(dfa_switch_data_t));
+       if (!sd) {
+               scf_loge("module data alloc failed\n");
+               return SCF_DFA_ERROR;
+       }
+
+       if (d->current_node)
+               scf_node_add_child(d->current_node, _switch);
+       else
+               scf_node_add_child((scf_node_t*)parse->ast->current_block, _switch);
+
+       sd->_switch      = _switch;
+       sd->parent_block = parse->ast->current_block;
+       sd->parent_node  = d->current_node;
+       d->current_node  = _switch;
+
+       scf_stack_push(s, sd);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _switch_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+
+       assert(!d->expr);
+       d->expr_local_flag = 1;
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"),      SCF_DFA_HOOK_POST);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _switch_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       dfa_parse_data_t*  d  = data;
+       scf_stack_t*       s  = d->module_datas[dfa_module_switch.index];
+       dfa_switch_data_t* sd = scf_stack_top(s);
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST);
+
+       sd->nb_lps++;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _switch_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_stack_t*       s     = d->module_datas[dfa_module_switch.index];
+       dfa_switch_data_t* sd    = scf_stack_top(s);
+
+       if (!d->expr) {
+               scf_loge("\n");
+               return SCF_DFA_ERROR;
+       }
+
+       sd->nb_rps++;
+
+       if (sd->nb_rps == sd->nb_lps) {
+
+               assert(0 == sd->_switch->nb_nodes);
+
+               scf_node_add_child(sd->_switch, d->expr);
+               d->expr = NULL;
+               d->expr_local_flag = 0;
+
+               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_end"), SCF_DFA_HOOK_END);
+
+               return SCF_DFA_SWITCH_TO;
+       }
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"),      SCF_DFA_HOOK_POST);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _switch_action_case(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_lex_word_t*    w     = words->data[words->size - 1];
+       scf_stack_t*       s     = d->module_datas[dfa_module_switch.index];
+       dfa_switch_data_t* sd    = scf_stack_top(s);
+
+       assert(!d->expr);
+       d->expr_local_flag = 1;
+
+       sd->child = scf_node_alloc(w, SCF_OP_CASE, NULL);
+       if (!sd->child)
+               return SCF_DFA_ERROR;
+
+       scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _switch_action_default(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_lex_word_t*    w     = words->data[words->size - 1];
+       scf_stack_t*       s     = d->module_datas[dfa_module_switch.index];
+       dfa_switch_data_t* sd    = scf_stack_top(s);
+
+       assert(!d->expr);
+
+       sd->child = scf_node_alloc(w, SCF_OP_DEFAULT, NULL);
+       if (!sd->child)
+               return SCF_DFA_ERROR;
+
+       scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _switch_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_stack_t*       s     = d->module_datas[dfa_module_switch.index];
+       dfa_switch_data_t* sd    = scf_stack_top(s);
+
+       if (SCF_OP_CASE == sd->child->type) {
+
+               if (!d->expr) {
+                       scf_loge("NOT found the expr for case\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               scf_node_add_child(sd->child, d->expr);
+               d->expr = NULL;
+               d->expr_local_flag = 0;
+
+       } else {
+               assert(SCF_OP_DEFAULT == sd->child->type);
+               assert(!d->expr);
+       }
+
+       return SCF_DFA_OK;
+}
+
+static int _switch_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*       parse = dfa->priv;
+       dfa_parse_data_t*  d     = data;
+       scf_stack_t*       s     = d->module_datas[dfa_module_switch.index];
+       dfa_switch_data_t* sd    = scf_stack_pop(s);
+
+       assert(parse->ast->current_block == sd->parent_block);
+
+       d->current_node = sd->parent_node;
+
+       scf_logi("\033[31m switch: %d, sd: %p, s->size: %d\033[0m\n", sd->_switch->w->line, sd, s->size);
+
+       free(sd);
+       sd = NULL;
+
+       assert(s->size >= 0);
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_init_module_switch(scf_dfa_t* dfa)
+{
+       SCF_DFA_MODULE_NODE(dfa, switch, lp,        scf_dfa_is_lp,      _switch_action_lp);
+       SCF_DFA_MODULE_NODE(dfa, switch, rp,        scf_dfa_is_rp,      _switch_action_rp);
+       SCF_DFA_MODULE_NODE(dfa, switch, lp_stat,   scf_dfa_is_lp,      _switch_action_lp_stat);
+       SCF_DFA_MODULE_NODE(dfa, switch, colon,     scf_dfa_is_colon,   _switch_action_colon);
+
+       SCF_DFA_MODULE_NODE(dfa, switch, _switch,   scf_dfa_is_switch,  _switch_action_switch);
+       SCF_DFA_MODULE_NODE(dfa, switch, _case,     scf_dfa_is_case,    _switch_action_case);
+       SCF_DFA_MODULE_NODE(dfa, switch, _default,  scf_dfa_is_default, _switch_action_default);
+       SCF_DFA_MODULE_NODE(dfa, switch, end,       _switch_is_end,     _switch_action_end);
+
+       scf_parse_t*      parse = dfa->priv;
+       dfa_parse_data_t* d     = parse->dfa_data;
+       scf_stack_t*      s     = d->module_datas[dfa_module_switch.index];
+
+       assert(!s);
+
+       s = scf_stack_alloc();
+       if (!s) {
+               scf_logi("\n");
+               return SCF_DFA_ERROR;
+       }
+
+       d->module_datas[dfa_module_switch.index] = s;
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_fini_module_switch(scf_dfa_t* dfa)
+{
+       scf_parse_t*      parse = dfa->priv;
+       dfa_parse_data_t* d     = parse->dfa_data;
+       scf_stack_t*      s     = d->module_datas[dfa_module_switch.index];
+
+       if (s) {
+               scf_stack_free(s);
+               s = NULL;
+               d->module_datas[dfa_module_switch.index] = NULL;
+       }
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_init_syntax_switch(scf_dfa_t* dfa)
+{
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   lp,        lp);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   rp,        rp);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   lp_stat,   lp_stat);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   colon,     colon);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   _switch,   _switch);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   _case,     _case);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   _default,  _default);
+       SCF_DFA_GET_MODULE_NODE(dfa, switch,   end,       end);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, expr,  entry,     expr);
+       SCF_DFA_GET_MODULE_NODE(dfa, block, entry,     block);
+
+       scf_dfa_node_add_child(_switch,  lp);
+       scf_dfa_node_add_child(lp,       expr);
+       scf_dfa_node_add_child(expr,     rp);
+       scf_dfa_node_add_child(rp,       block);
+
+       scf_dfa_node_add_child(_case,    expr);
+       scf_dfa_node_add_child(expr,     colon);
+       scf_dfa_node_add_child(_default, colon);
+
+       scf_logi("\n");
+       return 0;
+}
+
+scf_dfa_module_t dfa_module_switch =
+{
+       .name        = "switch",
+
+       .init_module = _dfa_init_module_switch,
+       .init_syntax = _dfa_init_syntax_switch,
+
+       .fini_module = _dfa_fini_module_switch,
+};
index b4868a6fb802df4730acd0f91424f6209067cdf5..4db002cd150da1a410595e3434792c0d1966c6e2 100644 (file)
@@ -130,6 +130,13 @@ static inline int scf_dfa_is_sizeof(scf_dfa_t* dfa, void* word)
        return SCF_LEX_WORD_KEY_SIZEOF == w->type;
 }
 
+static inline int scf_dfa_is_include(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_KEY_INCLUDE == w->type;
+}
+
 static inline int scf_dfa_is_vargs(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
@@ -256,6 +263,13 @@ static inline int scf_dfa_is_return(scf_dfa_t* dfa, void* word)
        return SCF_LEX_WORD_KEY_RETURN == w->type;
 }
 
+static inline int scf_dfa_is_goto(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_KEY_GOTO == w->type;
+}
+
 static inline int scf_dfa_is_exit(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
@@ -312,6 +326,20 @@ static inline int scf_dfa_is_end_for(scf_dfa_t* dfa, void* word)
        return SCF_LEX_WORD_KEY_END_FOR == w->type;
 }
 
+static inline int scf_dfa_is_switch(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_KEY_SWITCH == w->type;
+}
+
+static inline int scf_dfa_is_default(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_KEY_DEFAULT == w->type;
+}
+
 static inline int scf_dfa_is_case(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
index 99e839ba3a2b5759e7102d6b05cdb487679c1b3b..fae3d662e7c7ccc33744a0f79f046014aa1fc229 100644 (file)
@@ -6,13 +6,6 @@ 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;
-
-       return SCF_LEX_WORD_ASSIGN == w->type;
-}
-
 int _check_recursive(scf_type_t* parent, scf_type_t* child, scf_lex_word_t* w)
 {
        if (child->type == parent->type) {
@@ -407,7 +400,7 @@ static int _dfa_init_module_var(scf_dfa_t* dfa)
        SCF_DFA_MODULE_NODE(dfa, var, ls,        scf_dfa_is_ls,        _var_action_ls);
        SCF_DFA_MODULE_NODE(dfa, var, rs,        scf_dfa_is_rs,        _var_action_rs);
 
-       SCF_DFA_MODULE_NODE(dfa, var, assign,    _var_is_assign,       _var_action_assign);
+       SCF_DFA_MODULE_NODE(dfa, var, assign,    scf_dfa_is_assign,    _var_action_assign);
 
        return SCF_DFA_OK;
 }
index 48071f81df4244b3dc743c00a49d89cea36f9c08..086b6522cb5e3c30e201567d7385f5b8047142bd 100644 (file)
@@ -14,16 +14,8 @@ typedef struct {
 
        scf_node_t*      _while;
 
-       scf_dfa_hook_t*  hook_end;
-
 } dfa_while_data_t;
 
-static int _while_is_while(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_KEY_WHILE == w->type;
-}
 
 static int _while_is_end(scf_dfa_t* dfa, void* word)
 {
@@ -118,7 +110,7 @@ static int _while_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                d->expr_local_flag = 0;
 
-               wd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "while_end"), SCF_DFA_HOOK_END);
+               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "while_end"), SCF_DFA_HOOK_END);
 
                return SCF_DFA_SWITCH_TO;
        }
@@ -140,9 +132,7 @@ static int _while_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        d->current_node = wd->parent_node;
 
-       scf_logi("\033[31m while: %d, wd: %p, hook_end: %p, s->size: %d\033[0m\n",
-                       wd->_while->w->line,
-                       wd, wd->hook_end, s->size);
+       scf_logi("\033[31m while: %d, wd: %p, s->size: %d\033[0m\n", wd->_while->w->line, wd, s->size);
 
        free(wd);
        wd = NULL;
@@ -160,7 +150,7 @@ static int _dfa_init_module_while(scf_dfa_t* dfa)
        SCF_DFA_MODULE_NODE(dfa, while, rp,        scf_dfa_is_rp,    _while_action_rp);
        SCF_DFA_MODULE_NODE(dfa, while, lp_stat,   scf_dfa_is_lp,    _while_action_lp_stat);
 
-       SCF_DFA_MODULE_NODE(dfa, while, _while,    _while_is_while,  _while_action_while);
+       SCF_DFA_MODULE_NODE(dfa, while, _while,    scf_dfa_is_while, _while_action_while);
 
        scf_parse_t*      parse = dfa->priv;
        dfa_parse_data_t* d     = parse->dfa_data;
index ab1c4031230d334cc1cbc90aab97dce95cf4f7a8..3d175cd89c8d60052f3e0232eaa8b7e992c4318c 100644 (file)
@@ -187,16 +187,16 @@ static int _scf_op_const_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
        if (0 == nb_nodes)
                return 0;
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d  = data;
+       scf_block_t*        up = ast->current_block;
 
-       scf_block_t* prev_block = ast->current_block;
-       ast->current_block      = (scf_block_t*)(nodes[0]->parent);
+       ast->current_block = (scf_block_t*)(nodes[0]->parent);
 
-       int i = 0;
-       while (i < nb_nodes) {
-               scf_node_t* node = nodes[i];
+       int ret;
+       int i;
 
-               int ret;
+       for (i = 0; i < nb_nodes; i++) {
+               scf_node_t* node = nodes[i];
 
                if (SCF_FUNCTION == node->type)
                        ret = __scf_op_const_call(ast, (scf_function_t*)node, data);
@@ -205,41 +205,12 @@ static int _scf_op_const_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
 
                if (ret < 0) {
                        scf_loge("\n");
-                       ast->current_block = prev_block;
+                       ast->current_block = up;
                        return -1;
                }
-
-               i++;
-       }
-
-       ast->current_block = prev_block;
-       return 0;
-}
-
-static int _scf_op_const_error(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
-{
-       scf_handler_data_t* d = data;
-
-       scf_block_t* b = ast->current_block;
-
-       while (b && SCF_FUNCTION  != b->node.type) {
-               b = (scf_block_t*)b->node.parent;
-       }
-
-       SCF_CHECK_ERROR(!b, -1, "error statement must in a function\n");
-       assert(SCF_FUNCTION == b->node.type);
-
-       assert(nb_nodes >= 2);
-       assert(nodes);
-
-       int i;
-       for (i = 0; i < nb_nodes; i++) {
-
-               int ret = _scf_expr_calculate_internal(ast, nodes[i], d);
-
-               SCF_CHECK_ERROR(ret < 0, -1, "expr calculate error\n");
        }
 
+       ast->current_block = up;
        return 0;
 }
 
@@ -309,7 +280,7 @@ static int _scf_op_const_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo
        return 0;
 }
 
-static int _scf_op_const_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+static int _scf_op_const_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(2 == nb_nodes);
 
@@ -349,6 +320,45 @@ static int _scf_op_const_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
        return 0;
 }
 
+static int _scf_op_const_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       assert(2 == nb_nodes);
+
+       scf_handler_data_t* d = data;
+       scf_variable_t*     r = NULL;
+       scf_expr_t*         e = nodes[0];
+
+       assert(SCF_OP_EXPR == e->type);
+
+       if (_scf_expr_calculate_internal(ast, e, &r) < 0)
+               return -1;
+
+       if (_scf_op_const_node(ast, nodes[1], d) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int _scf_op_const_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       assert(1 == nb_nodes);
+
+       scf_handler_data_t* d = data;
+       scf_variable_t*     r = NULL;
+       scf_expr_t*         e = nodes[0];
+
+       assert(SCF_OP_EXPR == e->type);
+
+       if (_scf_expr_calculate_internal(ast, e, &r) < 0)
+               return -1;
+       return 0;
+}
+
+static int _scf_op_const_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       return 0;
+}
+
 static int _scf_op_const_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(4 == nb_nodes);
@@ -392,10 +402,10 @@ static int __scf_op_const_call(scf_ast_t* ast, scf_function_t* f, void* data)
 {
        scf_logd("f: %p, f->node->w: %s\n", f, f->node.w->text->data);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d   = data;
+       scf_block_t*        tmp = ast->current_block;
 
-       // save & change the current block
-       scf_block_t* prev_block = ast->current_block;
+       // change the current block
        ast->current_block = (scf_block_t*)f;
 
        if (_scf_op_const_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) {
@@ -403,7 +413,7 @@ static int __scf_op_const_call(scf_ast_t* ast, scf_function_t* f, void* data)
                return -1;
        }
 
-       ast->current_block = prev_block;
+       ast->current_block = tmp;
        return 0;
 }
 
@@ -890,79 +900,82 @@ static int _scf_op_const_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
 }
 
 scf_operator_handler_t const_operator_handlers[] = {
-       {{NULL, NULL}, SCF_OP_EXPR,           _scf_op_const_expr},
-       {{NULL, NULL}, SCF_OP_CALL,           _scf_op_const_call},
-
-       {{NULL, NULL}, SCF_OP_ARRAY_INDEX,    _scf_op_const_array_index},
-       {{NULL, NULL}, SCF_OP_POINTER,        _scf_op_const_pointer},
-       {{NULL, NULL}, SCF_OP_CREATE,         _scf_op_const_create},
-
-       {{NULL, NULL}, SCF_OP_VA_START,       _scf_op_const_va_start},
-       {{NULL, NULL}, SCF_OP_VA_ARG,         _scf_op_const_va_arg},
-       {{NULL, NULL}, SCF_OP_VA_END,         _scf_op_const_va_end},
-
-       {{NULL, NULL}, SCF_OP_SIZEOF,         _scf_op_const_sizeof},
-       {{NULL, NULL}, SCF_OP_TYPE_CAST,      _scf_op_const_type_cast},
-       {{NULL, NULL}, SCF_OP_LOGIC_NOT,      _scf_op_const_logic_not},
-       {{NULL, NULL}, SCF_OP_BIT_NOT,        _scf_op_const_bit_not},
-       {{NULL, NULL}, SCF_OP_NEG,            _scf_op_const_neg},
-       {{NULL, NULL}, SCF_OP_POSITIVE,       _scf_op_const_positive},
-
-       {{NULL, NULL}, SCF_OP_INC,            _scf_op_const_inc},
-       {{NULL, NULL}, SCF_OP_DEC,            _scf_op_const_dec},
-
-       {{NULL, NULL}, SCF_OP_INC_POST,       _scf_op_const_inc_post},
-       {{NULL, NULL}, SCF_OP_DEC_POST,       _scf_op_const_dec_post},
-
-       {{NULL, NULL}, SCF_OP_DEREFERENCE,    _scf_op_const_dereference},
-       {{NULL, NULL}, SCF_OP_ADDRESS_OF,     _scf_op_const_address_of},
-
-       {{NULL, NULL}, SCF_OP_MUL,            _scf_op_const_mul},
-       {{NULL, NULL}, SCF_OP_DIV,            _scf_op_const_div},
-       {{NULL, NULL}, SCF_OP_MOD,            _scf_op_const_mod},
-
-       {{NULL, NULL}, SCF_OP_ADD,            _scf_op_const_add},
-       {{NULL, NULL}, SCF_OP_SUB,            _scf_op_const_sub},
-
-       {{NULL, NULL}, SCF_OP_SHL,            _scf_op_const_shl},
-       {{NULL, NULL}, SCF_OP_SHR,            _scf_op_const_shr},
-
-       {{NULL, NULL}, SCF_OP_BIT_AND,        _scf_op_const_bit_and},
-       {{NULL, NULL}, SCF_OP_BIT_OR,         _scf_op_const_bit_or},
-
-       {{NULL, NULL}, SCF_OP_EQ,             _scf_op_const_eq},
-       {{NULL, NULL}, SCF_OP_NE,             _scf_op_const_ne},
-       {{NULL, NULL}, SCF_OP_GT,             _scf_op_const_gt},
-       {{NULL, NULL}, SCF_OP_LT,             _scf_op_const_lt},
-       {{NULL, NULL}, SCF_OP_GE,             _scf_op_const_ge},
-       {{NULL, NULL}, SCF_OP_LE,             _scf_op_const_le},
-
-       {{NULL, NULL}, SCF_OP_LOGIC_AND,      _scf_op_const_logic_and},
-       {{NULL, NULL}, SCF_OP_LOGIC_OR,       _scf_op_const_logic_or},
-
-       {{NULL, NULL}, SCF_OP_ASSIGN,         _scf_op_const_assign},
-       {{NULL, NULL}, SCF_OP_ADD_ASSIGN,     _scf_op_const_add_assign},
-       {{NULL, NULL}, SCF_OP_SUB_ASSIGN,     _scf_op_const_sub_assign},
-       {{NULL, NULL}, SCF_OP_MUL_ASSIGN,     _scf_op_const_mul_assign},
-       {{NULL, NULL}, SCF_OP_DIV_ASSIGN,     _scf_op_const_div_assign},
-       {{NULL, NULL}, SCF_OP_MOD_ASSIGN,     _scf_op_const_mod_assign},
-       {{NULL, NULL}, SCF_OP_SHL_ASSIGN,     _scf_op_const_shl_assign},
-       {{NULL, NULL}, SCF_OP_SHR_ASSIGN,     _scf_op_const_shr_assign},
-       {{NULL, NULL}, SCF_OP_AND_ASSIGN,     _scf_op_const_and_assign},
-       {{NULL, NULL}, SCF_OP_OR_ASSIGN,      _scf_op_const_or_assign},
-
-       {{NULL, NULL}, SCF_OP_BLOCK,          _scf_op_const_block},
-       {{NULL, NULL}, SCF_OP_RETURN,         _scf_op_const_return},
-       {{NULL, NULL}, SCF_OP_BREAK,          _scf_op_const_break},
-       {{NULL, NULL}, SCF_OP_CONTINUE,       _scf_op_const_continue},
-       {{NULL, NULL}, SCF_OP_GOTO,           _scf_op_const_goto},
-       {{NULL, NULL}, SCF_LABEL,             _scf_op_const_label},
-       {{NULL, NULL}, SCF_OP_ERROR,          _scf_op_const_error},
-
-       {{NULL, NULL}, SCF_OP_IF,             _scf_op_const_if},
-       {{NULL, NULL}, SCF_OP_WHILE,          _scf_op_const_while},
-       {{NULL, NULL}, SCF_OP_REPEAT,         _scf_op_const_repeat},
-       {{NULL, NULL}, SCF_OP_FOR,            _scf_op_const_for},
+       {SCF_OP_EXPR,           _scf_op_const_expr},
+       {SCF_OP_CALL,           _scf_op_const_call},
+
+       {SCF_OP_ARRAY_INDEX,    _scf_op_const_array_index},
+       {SCF_OP_POINTER,        _scf_op_const_pointer},
+       {SCF_OP_CREATE,         _scf_op_const_create},
+
+       {SCF_OP_VA_START,       _scf_op_const_va_start},
+       {SCF_OP_VA_ARG,         _scf_op_const_va_arg},
+       {SCF_OP_VA_END,         _scf_op_const_va_end},
+
+       {SCF_OP_SIZEOF,         _scf_op_const_sizeof},
+       {SCF_OP_TYPE_CAST,      _scf_op_const_type_cast},
+       {SCF_OP_LOGIC_NOT,      _scf_op_const_logic_not},
+       {SCF_OP_BIT_NOT,        _scf_op_const_bit_not},
+       {SCF_OP_NEG,            _scf_op_const_neg},
+       {SCF_OP_POSITIVE,       _scf_op_const_positive},
+
+       {SCF_OP_INC,            _scf_op_const_inc},
+       {SCF_OP_DEC,            _scf_op_const_dec},
+
+       {SCF_OP_INC_POST,       _scf_op_const_inc_post},
+       {SCF_OP_DEC_POST,       _scf_op_const_dec_post},
+
+       {SCF_OP_DEREFERENCE,    _scf_op_const_dereference},
+       {SCF_OP_ADDRESS_OF,     _scf_op_const_address_of},
+
+       {SCF_OP_MUL,            _scf_op_const_mul},
+       {SCF_OP_DIV,            _scf_op_const_div},
+       {SCF_OP_MOD,            _scf_op_const_mod},
+
+       {SCF_OP_ADD,            _scf_op_const_add},
+       {SCF_OP_SUB,            _scf_op_const_sub},
+
+       {SCF_OP_SHL,            _scf_op_const_shl},
+       {SCF_OP_SHR,            _scf_op_const_shr},
+
+       {SCF_OP_BIT_AND,        _scf_op_const_bit_and},
+       {SCF_OP_BIT_OR,         _scf_op_const_bit_or},
+
+       {SCF_OP_EQ,             _scf_op_const_eq},
+       {SCF_OP_NE,             _scf_op_const_ne},
+       {SCF_OP_GT,             _scf_op_const_gt},
+       {SCF_OP_LT,             _scf_op_const_lt},
+       {SCF_OP_GE,             _scf_op_const_ge},
+       {SCF_OP_LE,             _scf_op_const_le},
+
+       {SCF_OP_LOGIC_AND,      _scf_op_const_logic_and},
+       {SCF_OP_LOGIC_OR,       _scf_op_const_logic_or},
+
+       {SCF_OP_ASSIGN,         _scf_op_const_assign},
+       {SCF_OP_ADD_ASSIGN,     _scf_op_const_add_assign},
+       {SCF_OP_SUB_ASSIGN,     _scf_op_const_sub_assign},
+       {SCF_OP_MUL_ASSIGN,     _scf_op_const_mul_assign},
+       {SCF_OP_DIV_ASSIGN,     _scf_op_const_div_assign},
+       {SCF_OP_MOD_ASSIGN,     _scf_op_const_mod_assign},
+       {SCF_OP_SHL_ASSIGN,     _scf_op_const_shl_assign},
+       {SCF_OP_SHR_ASSIGN,     _scf_op_const_shr_assign},
+       {SCF_OP_AND_ASSIGN,     _scf_op_const_and_assign},
+       {SCF_OP_OR_ASSIGN,      _scf_op_const_or_assign},
+
+       {SCF_OP_BLOCK,          _scf_op_const_block},
+       {SCF_OP_RETURN,         _scf_op_const_return},
+       {SCF_OP_BREAK,          _scf_op_const_break},
+       {SCF_OP_CONTINUE,       _scf_op_const_continue},
+       {SCF_OP_GOTO,           _scf_op_const_goto},
+       {SCF_LABEL,             _scf_op_const_label},
+
+       {SCF_OP_IF,             _scf_op_const_if},
+       {SCF_OP_WHILE,          _scf_op_const_while},
+       {SCF_OP_DO,             _scf_op_const_do},
+       {SCF_OP_FOR,            _scf_op_const_for},
+
+       {SCF_OP_SWITCH,         _scf_op_const_switch},
+       {SCF_OP_CASE,           _scf_op_const_case},
+       {SCF_OP_DEFAULT,        _scf_op_const_default},
 };
 
 scf_operator_handler_t* scf_find_const_operator_handler(const int type)
index 4382771638ed3172ae79a5692bf7004b3652cd16..ac2f9eb28f809258960db24bb98f4db4b843f2e1 100644 (file)
@@ -661,43 +661,43 @@ static int _scf_op_expr_bit_or(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
 
 scf_operator_handler_t expr_operator_handlers[] = {
 
-       {{NULL, NULL}, SCF_OP_EXPR,           _scf_op_expr_expr},
+       {SCF_OP_EXPR,           _scf_op_expr_expr},
 
-       {{NULL, NULL}, SCF_OP_ARRAY_INDEX,    _scf_op_expr_array_index},
-       {{NULL, NULL}, SCF_OP_POINTER,        _scf_op_expr_pointer},
+       {SCF_OP_ARRAY_INDEX,    _scf_op_expr_array_index},
+       {SCF_OP_POINTER,        _scf_op_expr_pointer},
 
-       {{NULL, NULL}, SCF_OP_SIZEOF,         _scf_op_expr_sizeof},
-       {{NULL, NULL}, SCF_OP_TYPE_CAST,      _scf_op_expr_type_cast},
-       {{NULL, NULL}, SCF_OP_LOGIC_NOT,      _scf_op_expr_logic_not},
-       {{NULL, NULL}, SCF_OP_BIT_NOT,        _scf_op_expr_bit_not},
-       {{NULL, NULL}, SCF_OP_NEG,            _scf_op_expr_neg},
+       {SCF_OP_SIZEOF,         _scf_op_expr_sizeof},
+       {SCF_OP_TYPE_CAST,      _scf_op_expr_type_cast},
+       {SCF_OP_LOGIC_NOT,      _scf_op_expr_logic_not},
+       {SCF_OP_BIT_NOT,        _scf_op_expr_bit_not},
+       {SCF_OP_NEG,            _scf_op_expr_neg},
 
-       {{NULL, NULL}, SCF_OP_ADDRESS_OF,     _scf_op_expr_address_of},
+       {SCF_OP_ADDRESS_OF,     _scf_op_expr_address_of},
 
-       {{NULL, NULL}, SCF_OP_MUL,            _scf_op_expr_mul},
-       {{NULL, NULL}, SCF_OP_DIV,            _scf_op_expr_div},
-       {{NULL, NULL}, SCF_OP_MOD,            _scf_op_expr_mod},
+       {SCF_OP_MUL,            _scf_op_expr_mul},
+       {SCF_OP_DIV,            _scf_op_expr_div},
+       {SCF_OP_MOD,            _scf_op_expr_mod},
 
-       {{NULL, NULL}, SCF_OP_ADD,            _scf_op_expr_add},
-       {{NULL, NULL}, SCF_OP_SUB,            _scf_op_expr_sub},
+       {SCF_OP_ADD,            _scf_op_expr_add},
+       {SCF_OP_SUB,            _scf_op_expr_sub},
 
-       {{NULL, NULL}, SCF_OP_SHL,            _scf_op_expr_shl},
-       {{NULL, NULL}, SCF_OP_SHR,            _scf_op_expr_shr},
+       {SCF_OP_SHL,            _scf_op_expr_shl},
+       {SCF_OP_SHR,            _scf_op_expr_shr},
 
-       {{NULL, NULL}, SCF_OP_BIT_AND,        _scf_op_expr_bit_and},
-       {{NULL, NULL}, SCF_OP_BIT_OR,         _scf_op_expr_bit_or},
+       {SCF_OP_BIT_AND,        _scf_op_expr_bit_and},
+       {SCF_OP_BIT_OR,         _scf_op_expr_bit_or},
 
-       {{NULL, NULL}, SCF_OP_EQ,             _scf_op_expr_eq},
-       {{NULL, NULL}, SCF_OP_NE,             _scf_op_expr_ne},
-       {{NULL, NULL}, SCF_OP_GT,             _scf_op_expr_gt},
-       {{NULL, NULL}, SCF_OP_LT,             _scf_op_expr_lt},
-       {{NULL, NULL}, SCF_OP_GE,             _scf_op_expr_ge},
-       {{NULL, NULL}, SCF_OP_LE,             _scf_op_expr_le},
+       {SCF_OP_EQ,             _scf_op_expr_eq},
+       {SCF_OP_NE,             _scf_op_expr_ne},
+       {SCF_OP_GT,             _scf_op_expr_gt},
+       {SCF_OP_LT,             _scf_op_expr_lt},
+       {SCF_OP_GE,             _scf_op_expr_ge},
+       {SCF_OP_LE,             _scf_op_expr_le},
 
-       {{NULL, NULL}, SCF_OP_LOGIC_AND,      _scf_op_expr_logic_and},
-       {{NULL, NULL}, SCF_OP_LOGIC_OR,       _scf_op_expr_logic_or},
+       {SCF_OP_LOGIC_AND,      _scf_op_expr_logic_and},
+       {SCF_OP_LOGIC_OR,       _scf_op_expr_logic_or},
 
-       {{NULL, NULL}, SCF_OP_ASSIGN,         _scf_op_expr_assign},
+       {SCF_OP_ASSIGN,         _scf_op_expr_assign},
 };
 
 scf_operator_handler_t* scf_find_expr_operator_handler(const int type, const int src0_type, const int src1_type, const int ret_type)
index cdfcdae89899b49368d0bf8b5d4a5f2f45deafe1..b2278493963a0cce71d19c60d8f104e2588c23be 100644 (file)
@@ -1020,22 +1020,22 @@ static int _scf_op_semantic_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
        if (0 == nb_nodes)
                return 0;
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d  = data;
+       scf_block_t*        up = ast->current_block;
 
-       scf_block_t* prev_block = ast->current_block;
-       ast->current_block      = (scf_block_t*)(nodes[0]->parent);
+       scf_variable_t**    pret;
+       scf_node_t*             node;
 
-       int i = 0;
-       while (i < nb_nodes) {
-               scf_node_t*     node = nodes[i];
+       int ret;
+       int i;
 
-               if (scf_type_is_var(node->type)) {
-                       i++;
-                       continue;
-               }
+       ast->current_block = (scf_block_t*)(nodes[0]->parent);
 
-               scf_variable_t** pret;
-               int ret;
+       for (i = 0; i < nb_nodes; i++) {
+               node = nodes[i];
+
+               if (scf_type_is_var(node->type))
+                       continue;
 
                if (SCF_FUNCTION == node->type) {
                        pret = d->pret;
@@ -1046,73 +1046,12 @@ static int _scf_op_semantic_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
 
                if (ret < 0) {
                        scf_loge("\n");
-                       ast->current_block = prev_block;
-                       return -1;
-               }
-
-               i++;
-       }
-
-       ast->current_block = prev_block;
-       return 0;
-}
-
-static int _scf_op_semantic_error(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
-{
-       scf_handler_data_t* d = data;
-       scf_variable_t**    pret = NULL;
-
-       scf_block_t* b = ast->current_block;
-
-       while (b && SCF_FUNCTION  != b->node.type) {
-               b = (scf_block_t*)b->node.parent;
-       }
-
-       SCF_CHECK_ERROR(!b, -1, "error statement must in a function\n");
-       assert(SCF_FUNCTION == b->node.type);
-
-       assert(nb_nodes >= 2);
-       assert(nodes);
-
-       int i;
-       for (i = 0; i < nb_nodes; i++) {
-
-               pret    = d->pret;
-               d->pret = &(nodes[i]->result);
-               int ret = _scf_expr_calculate_internal(ast, nodes[i], d);
-               d->pret = pret;
-
-               SCF_CHECK_ERROR(ret < 0, -1, "expr calculate error\n");
-       }
-
-       if (!scf_type_is_integer(nodes[0]->result->type)) {
-               scf_loge("1st expr in error statement should got an interger for condition\n");
-               return -1;
-       }
-
-       if (0 == nodes[1]->result->nb_pointers
-                       || SCF_FUNCTION_PTR == nodes[1]->result->type) {
-               scf_loge("2nd expr in error statement should got a pointer to be freed, but not a function pointer\n");
-               return -1;
-       }
-
-       if (nb_nodes >= 3) {
-               if (!scf_type_is_integer(nodes[2]->result->type)) {
-                       scf_loge("3rd expr in error statement should got an interger for return value\n");
-                       return -1;
-               }
-       } else if (nb_nodes < 3) {
-               scf_logw("error in line: %d not set return value\n", nodes[0]->parent->w->line);
-       }
-
-       if (nb_nodes >= 4) {
-               if (SCF_VAR_CHAR != nodes[3]->result->type
-                               || 1 != nodes[3]->result->nb_pointers) {
-                       scf_loge("4th expr in error statement should got an format string\n");
+                       ast->current_block = up;
                        return -1;
                }
        }
 
+       ast->current_block = up;
        return 0;
 }
 
@@ -1178,7 +1117,8 @@ static int _scf_op_semantic_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
 
        while (n
                        && SCF_OP_WHILE  != n->type
-                       && SCF_OP_REPEAT != n->type
+                       && SCF_OP_SWITCH != n->type
+                       && SCF_OP_DO     != n->type
                        && SCF_OP_FOR    != n->type)
                n = n->parent;
 
@@ -1187,8 +1127,6 @@ static int _scf_op_semantic_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
                return -1;
        }
 
-       assert(SCF_OP_WHILE == n->type || SCF_OP_FOR == n->type || SCF_OP_REPEAT == n->type);
-
        if (!n->parent) {
                scf_loge("\n");
                return -1;
@@ -1279,7 +1217,7 @@ static int _scf_op_semantic_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
        return 0;
 }
 
-static int _scf_op_semantic_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+static int _scf_op_semantic_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(2 == nb_nodes);
 
@@ -1347,6 +1285,66 @@ static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
        return 0;
 }
 
+static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       assert(2 == nb_nodes);
+
+       scf_handler_data_t* d = data;
+       scf_variable_t*     r = NULL;
+       scf_expr_t*         e = nodes[0];
+
+       assert(SCF_OP_EXPR == e->type);
+
+       if (_scf_expr_calculate(ast, e, &r) < 0) {
+               scf_loge("\n");
+               return -1;
+       }
+
+       if (!r || !scf_variable_interger(r)) {
+               scf_loge("\n");
+               return -1;
+       }
+       scf_variable_free(r);
+       r = NULL;
+
+       int ret = _scf_op_semantic_node(ast, nodes[1], d);
+       if (ret < 0) {
+               scf_loge("\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int _scf_op_semantic_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       assert(1 == nb_nodes);
+
+       scf_handler_data_t* d = data;
+       scf_variable_t*     r = NULL;
+       scf_expr_t*         e = nodes[0];
+
+       assert(SCF_OP_EXPR == e->type);
+
+       if (_scf_expr_calculate(ast, e, &r) < 0) {
+               scf_loge("\n");
+               return -1;
+       }
+
+       if (!r || !scf_variable_interger(r)) {
+               scf_loge("\n");
+               return -1;
+       }
+       scf_variable_free(r);
+
+       return 0;
+}
+
+static int _scf_op_semantic_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       return 0;
+}
+
 static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(4 == nb_nodes);
@@ -1400,10 +1398,10 @@ static int __scf_op_semantic_call(scf_ast_t* ast, scf_function_t* f, void* data)
 {
        scf_logd("f: %p, f->node->w: %s\n", f, f->node.w->text->data);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d   = data;
+       scf_block_t*        tmp = ast->current_block;
 
-       // save & change the current block
-       scf_block_t* prev_block = ast->current_block;
+       // change the current block
        ast->current_block = (scf_block_t*)f;
 
        if (_scf_op_semantic_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) {
@@ -1411,7 +1409,7 @@ static int __scf_op_semantic_call(scf_ast_t* ast, scf_function_t* f, void* data)
                return -1;
        }
 
-       ast->current_block = prev_block;
+       ast->current_block = tmp;
        return 0;
 }
 
@@ -1421,6 +1419,9 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
 
        scf_handler_data_t* d      = data;
        scf_variable_t**    pret   = d->pret;
+       scf_variable_t*     v0;
+       scf_variable_t*     v1;
+       scf_function_t*     f;
        scf_node_t*         parent = nodes[0]->parent;
 
        d->pret = &nodes[0]->result;
@@ -1432,14 +1433,14 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
                return -1;
        }
 
-       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
+       v0 = _scf_operand_get(nodes[0]);
 
        if (SCF_FUNCTION_PTR != v0->type || !v0->func_ptr) {
                scf_loge("\n");
                return -1;
        }
 
-       scf_function_t* f = v0->func_ptr;
+       f = v0->func_ptr;
 
        if (f->vargs_flag) {
                if (f->argv->size > nb_nodes - 1) {
@@ -1453,8 +1454,9 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
 
        int i;
        for (i = 0; i < f->argv->size; i++) {
-               scf_variable_t* v0 = f->argv->data[i];
-               scf_variable_t* v1 = _scf_operand_get(nodes[i + 1]);
+               v0 =        f->argv->data[i];
+
+               v1 = _scf_operand_get(nodes[i + 1]);
 
                if (SCF_VAR_VOID == v1->type && 0 == v1->nb_pointers) {
                        scf_loge("void var should be a pointer\n");
@@ -1485,8 +1487,8 @@ static int _scf_op_semantic_expr(scf_ast_t* ast, scf_node_t** nodes, int nb_node
        assert(1 == nb_nodes);
 
        scf_handler_data_t* d = data;
+       scf_node_t*         n = nodes[0];
 
-       scf_node_t* n = nodes[0];
        if (n->result) {
                scf_variable_free(n->result);
                n->result = 0;
@@ -1520,9 +1522,8 @@ static int _scf_op_semantic_neg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
-
-       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
+       scf_handler_data_t* d  = data;
+       scf_variable_t*     v0 = _scf_operand_get(nodes[0]);
 
        assert(v0);
 
@@ -1562,10 +1563,9 @@ static int _scf_op_semantic_inc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
-
-       scf_variable_t* v0     = _scf_operand_get(nodes[0]);
-       scf_node_t*     parent = nodes[0]->parent;
+       scf_handler_data_t* d      = data;
+       scf_variable_t*     v0     = _scf_operand_get(nodes[0]);
+       scf_node_t*         parent = nodes[0]->parent;
 
        assert(v0);
 
@@ -1641,9 +1641,9 @@ static int _scf_op_semantic_dereference(scf_ast_t* ast, scf_node_t** nodes, int
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d  = data;
+       scf_variable_t*     v0 = _scf_operand_get(nodes[0]);
 
-       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
        assert(v0);
 
        if (v0->nb_pointers <= 0) {
@@ -1669,9 +1669,9 @@ static int _scf_op_semantic_address_of(scf_ast_t* ast, scf_node_t** nodes, int n
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d  = data;
+       scf_variable_t*     v0 = _scf_operand_get(nodes[0]);
 
-       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
        assert(v0);
 
        if (v0->const_literal_flag) {
@@ -1821,9 +1821,8 @@ static int _scf_op_semantic_logic_not(scf_ast_t* ast, scf_node_t** nodes, int nb
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
-
-       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
+       scf_handler_data_t* d  = data;
+       scf_variable_t*     v0 = _scf_operand_get(nodes[0]);
 
        assert(v0);
 
@@ -1862,9 +1861,9 @@ static int _scf_op_semantic_bit_not(scf_ast_t* ast, scf_node_t** nodes, int nb_n
 {
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d  = data;
+       scf_variable_t*     v0 = _scf_operand_get(nodes[0]);
 
-       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
        assert(v0);
 
        if (scf_variable_is_struct_pointer(v0)) {
@@ -2765,81 +2764,84 @@ static int _scf_op_semantic_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_no
 }
 
 scf_operator_handler_t semantic_operator_handlers[] = {
-       {{NULL, NULL}, SCF_OP_EXPR,           _scf_op_semantic_expr},
-       {{NULL, NULL}, SCF_OP_CALL,           _scf_op_semantic_call},
-
-       {{NULL, NULL}, SCF_OP_ARRAY_INDEX,    _scf_op_semantic_array_index},
-       {{NULL, NULL}, SCF_OP_POINTER,        _scf_op_semantic_pointer},
-       {{NULL, NULL}, SCF_OP_CREATE,         _scf_op_semantic_create},
-
-       {{NULL, NULL}, SCF_OP_VA_START,       _scf_op_semantic_va_start},
-       {{NULL, NULL}, SCF_OP_VA_ARG,         _scf_op_semantic_va_arg},
-       {{NULL, NULL}, SCF_OP_VA_END,         _scf_op_semantic_va_end},
-
-       {{NULL, NULL}, SCF_OP_CONTAINER,      _scf_op_semantic_container},
-
-       {{NULL, NULL}, SCF_OP_SIZEOF,         _scf_op_semantic_sizeof},
-       {{NULL, NULL}, SCF_OP_TYPE_CAST,      _scf_op_semantic_type_cast},
-       {{NULL, NULL}, SCF_OP_LOGIC_NOT,      _scf_op_semantic_logic_not},
-       {{NULL, NULL}, SCF_OP_BIT_NOT,        _scf_op_semantic_bit_not},
-       {{NULL, NULL}, SCF_OP_NEG,            _scf_op_semantic_neg},
-       {{NULL, NULL}, SCF_OP_POSITIVE,       _scf_op_semantic_positive},
-
-       {{NULL, NULL}, SCF_OP_INC,            _scf_op_semantic_inc},
-       {{NULL, NULL}, SCF_OP_DEC,            _scf_op_semantic_dec},
-
-       {{NULL, NULL}, SCF_OP_INC_POST,       _scf_op_semantic_inc_post},
-       {{NULL, NULL}, SCF_OP_DEC_POST,       _scf_op_semantic_dec_post},
-
-       {{NULL, NULL}, SCF_OP_DEREFERENCE,    _scf_op_semantic_dereference},
-       {{NULL, NULL}, SCF_OP_ADDRESS_OF,     _scf_op_semantic_address_of},
-
-       {{NULL, NULL}, SCF_OP_MUL,            _scf_op_semantic_mul},
-       {{NULL, NULL}, SCF_OP_DIV,            _scf_op_semantic_div},
-       {{NULL, NULL}, SCF_OP_MOD,            _scf_op_semantic_mod},
-
-       {{NULL, NULL}, SCF_OP_ADD,            _scf_op_semantic_add},
-       {{NULL, NULL}, SCF_OP_SUB,            _scf_op_semantic_sub},
-
-       {{NULL, NULL}, SCF_OP_SHL,            _scf_op_semantic_shl},
-       {{NULL, NULL}, SCF_OP_SHR,            _scf_op_semantic_shr},
-
-       {{NULL, NULL}, SCF_OP_BIT_AND,        _scf_op_semantic_bit_and},
-       {{NULL, NULL}, SCF_OP_BIT_OR,         _scf_op_semantic_bit_or},
-
-       {{NULL, NULL}, SCF_OP_EQ,             _scf_op_semantic_eq},
-       {{NULL, NULL}, SCF_OP_NE,             _scf_op_semantic_ne},
-       {{NULL, NULL}, SCF_OP_GT,             _scf_op_semantic_gt},
-       {{NULL, NULL}, SCF_OP_LT,             _scf_op_semantic_lt},
-       {{NULL, NULL}, SCF_OP_GE,             _scf_op_semantic_ge},
-       {{NULL, NULL}, SCF_OP_LE,             _scf_op_semantic_le},
-
-       {{NULL, NULL}, SCF_OP_LOGIC_AND,      _scf_op_semantic_logic_and},
-       {{NULL, NULL}, SCF_OP_LOGIC_OR,       _scf_op_semantic_logic_or},
-
-       {{NULL, NULL}, SCF_OP_ASSIGN,         _scf_op_semantic_assign},
-       {{NULL, NULL}, SCF_OP_ADD_ASSIGN,     _scf_op_semantic_add_assign},
-       {{NULL, NULL}, SCF_OP_SUB_ASSIGN,     _scf_op_semantic_sub_assign},
-       {{NULL, NULL}, SCF_OP_MUL_ASSIGN,     _scf_op_semantic_mul_assign},
-       {{NULL, NULL}, SCF_OP_DIV_ASSIGN,     _scf_op_semantic_div_assign},
-       {{NULL, NULL}, SCF_OP_MOD_ASSIGN,     _scf_op_semantic_mod_assign},
-       {{NULL, NULL}, SCF_OP_SHL_ASSIGN,     _scf_op_semantic_shl_assign},
-       {{NULL, NULL}, SCF_OP_SHR_ASSIGN,     _scf_op_semantic_shr_assign},
-       {{NULL, NULL}, SCF_OP_AND_ASSIGN,     _scf_op_semantic_and_assign},
-       {{NULL, NULL}, SCF_OP_OR_ASSIGN,      _scf_op_semantic_or_assign},
-
-       {{NULL, NULL}, SCF_OP_BLOCK,          _scf_op_semantic_block},
-       {{NULL, NULL}, SCF_OP_RETURN,         _scf_op_semantic_return},
-       {{NULL, NULL}, SCF_OP_BREAK,          _scf_op_semantic_break},
-       {{NULL, NULL}, SCF_OP_CONTINUE,       _scf_op_semantic_continue},
-       {{NULL, NULL}, SCF_OP_GOTO,           _scf_op_semantic_goto},
-       {{NULL, NULL}, SCF_LABEL,             _scf_op_semantic_label},
-       {{NULL, NULL}, SCF_OP_ERROR,          _scf_op_semantic_error},
-
-       {{NULL, NULL}, SCF_OP_IF,             _scf_op_semantic_if},
-       {{NULL, NULL}, SCF_OP_WHILE,          _scf_op_semantic_while},
-       {{NULL, NULL}, SCF_OP_REPEAT,         _scf_op_semantic_repeat},
-       {{NULL, NULL}, SCF_OP_FOR,            _scf_op_semantic_for},
+       {SCF_OP_EXPR,           _scf_op_semantic_expr},
+       {SCF_OP_CALL,           _scf_op_semantic_call},
+
+       {SCF_OP_ARRAY_INDEX,    _scf_op_semantic_array_index},
+       {SCF_OP_POINTER,        _scf_op_semantic_pointer},
+       {SCF_OP_CREATE,         _scf_op_semantic_create},
+
+       {SCF_OP_VA_START,       _scf_op_semantic_va_start},
+       {SCF_OP_VA_ARG,         _scf_op_semantic_va_arg},
+       {SCF_OP_VA_END,         _scf_op_semantic_va_end},
+
+       {SCF_OP_CONTAINER,      _scf_op_semantic_container},
+
+       {SCF_OP_SIZEOF,         _scf_op_semantic_sizeof},
+       {SCF_OP_TYPE_CAST,      _scf_op_semantic_type_cast},
+       {SCF_OP_LOGIC_NOT,      _scf_op_semantic_logic_not},
+       {SCF_OP_BIT_NOT,        _scf_op_semantic_bit_not},
+       {SCF_OP_NEG,            _scf_op_semantic_neg},
+       {SCF_OP_POSITIVE,       _scf_op_semantic_positive},
+
+       {SCF_OP_INC,            _scf_op_semantic_inc},
+       {SCF_OP_DEC,            _scf_op_semantic_dec},
+
+       {SCF_OP_INC_POST,       _scf_op_semantic_inc_post},
+       {SCF_OP_DEC_POST,       _scf_op_semantic_dec_post},
+
+       {SCF_OP_DEREFERENCE,    _scf_op_semantic_dereference},
+       {SCF_OP_ADDRESS_OF,     _scf_op_semantic_address_of},
+
+       {SCF_OP_MUL,            _scf_op_semantic_mul},
+       {SCF_OP_DIV,            _scf_op_semantic_div},
+       {SCF_OP_MOD,            _scf_op_semantic_mod},
+
+       {SCF_OP_ADD,            _scf_op_semantic_add},
+       {SCF_OP_SUB,            _scf_op_semantic_sub},
+
+       {SCF_OP_SHL,            _scf_op_semantic_shl},
+       {SCF_OP_SHR,            _scf_op_semantic_shr},
+
+       {SCF_OP_BIT_AND,        _scf_op_semantic_bit_and},
+       {SCF_OP_BIT_OR,         _scf_op_semantic_bit_or},
+
+       {SCF_OP_EQ,             _scf_op_semantic_eq},
+       {SCF_OP_NE,             _scf_op_semantic_ne},
+       {SCF_OP_GT,             _scf_op_semantic_gt},
+       {SCF_OP_LT,             _scf_op_semantic_lt},
+       {SCF_OP_GE,             _scf_op_semantic_ge},
+       {SCF_OP_LE,             _scf_op_semantic_le},
+
+       {SCF_OP_LOGIC_AND,      _scf_op_semantic_logic_and},
+       {SCF_OP_LOGIC_OR,       _scf_op_semantic_logic_or},
+
+       {SCF_OP_ASSIGN,         _scf_op_semantic_assign},
+       {SCF_OP_ADD_ASSIGN,     _scf_op_semantic_add_assign},
+       {SCF_OP_SUB_ASSIGN,     _scf_op_semantic_sub_assign},
+       {SCF_OP_MUL_ASSIGN,     _scf_op_semantic_mul_assign},
+       {SCF_OP_DIV_ASSIGN,     _scf_op_semantic_div_assign},
+       {SCF_OP_MOD_ASSIGN,     _scf_op_semantic_mod_assign},
+       {SCF_OP_SHL_ASSIGN,     _scf_op_semantic_shl_assign},
+       {SCF_OP_SHR_ASSIGN,     _scf_op_semantic_shr_assign},
+       {SCF_OP_AND_ASSIGN,     _scf_op_semantic_and_assign},
+       {SCF_OP_OR_ASSIGN,      _scf_op_semantic_or_assign},
+
+       {SCF_OP_BLOCK,          _scf_op_semantic_block},
+       {SCF_OP_RETURN,         _scf_op_semantic_return},
+       {SCF_OP_BREAK,          _scf_op_semantic_break},
+       {SCF_OP_CONTINUE,       _scf_op_semantic_continue},
+       {SCF_OP_GOTO,           _scf_op_semantic_goto},
+       {SCF_LABEL,             _scf_op_semantic_label},
+
+       {SCF_OP_IF,             _scf_op_semantic_if},
+       {SCF_OP_WHILE,          _scf_op_semantic_while},
+       {SCF_OP_DO,             _scf_op_semantic_do},
+       {SCF_OP_FOR,            _scf_op_semantic_for},
+
+       {SCF_OP_SWITCH,         _scf_op_semantic_switch},
+       {SCF_OP_CASE,           _scf_op_semantic_case},
+       {SCF_OP_DEFAULT,        _scf_op_semantic_default},
 };
 
 scf_operator_handler_t* scf_find_semantic_operator_handler(const int type)
index 8c4ae85a1fe5ef9ff3ca3cd3bd390c06b241904d..87b97a07e236e13bfda9333b457a0a0c9ee8abfe 100644 (file)
@@ -1881,6 +1881,8 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions)
                        return ret;
                }
 
+//             scf_3ac_list_print(&h);
+
                ret = scf_3ac_split_basic_blocks(&h, f);
                if (ret < 0) {
                        scf_list_clear(&h, scf_3ac_code_t, list, scf_3ac_code_free);
diff --git a/parse/scf_rbtree.c b/parse/scf_rbtree.c
deleted file mode 100644 (file)
index 70a2332..0000000
+++ /dev/null
@@ -1,713 +0,0 @@
-
-struct scf_rbtree_node_t
-{
-       scf_rbtree_node_t*  parent;
-
-       scf_rbtree_node_t*  left;
-       scf_rbtree_node_t*  right;
-
-       uint16_t            depth;
-       uint16_t            bdepth;
-       uint8_t             color;
-};
-
-struct scf_rbtree_t
-{
-       scf_rbtree_node_t*  root;
-       scf_rbtree_node_t   sentinel;
-};
-
-const uint8_t SCF_RBTREE_BLACK = 0;
-const uint8_t SCF_RBTREE_RED   = 1;
-
-int scf_rbtree_node_do_pt(scf_rbtree_node_t* node0, void* data);
-
-inline scf_rbtree_node_t* scf_rbtree_sentinel(scf_rbtree_t* tree)
-{
-       return &tree->sentinel;
-}
-
-inline void scf_rbtree_init(scf_rbtree_t* tree)
-{
-       tree->sentinel->parent = &tree->sentinel;
-       tree->sentinel->left   = &tree->sentinel;
-       tree->sentinel->right  = &tree->sentinel;
-
-       tree->sentinel->color  = SCF_RBTREE_BLACK;
-
-       tree->root = &tree->sentinel;
-}
-
-static scf_rbtree_node_t* _rbtree_min(scf_rbtree_t* tree, scf_rbtree_node_t* root)
-{
-       while (root->left != &tree->sentinel)
-               root = root->left;
-
-       return root;
-}
-
-static scf_rbtree_node_t* _rbtree_max(scf_rbtree_t* tree, scf_rbtree_node_t* root)
-{
-       while (root->right != &tree->sentinel)
-               root = root->right;
-
-       return root;
-}
-
-scf_rbtree_node_t* scf_rbtree_min(scf_rbtree_t* tree, scf_rbtree_node_t* root)
-{
-       if (!tree || !root)
-               return NULL;
-
-       scf_rbtree_node_t* x = _rbtree_min(tree, root);
-
-       if (&tree->sentinel == x)
-               return NULL;
-       return x;
-}
-
-scf_rbtree_node_t* scf_rbtree_max(scf_rbtree_t* tree, scf_rbtree_node_t* root)
-{
-       if (!tree || !root)
-               return NULL;
-
-       scf_rbtree_node_t* x = _rbtree_max(tree, root);
-
-       if (&tree->sentinel == x)
-               return NULL;
-       return x;
-}
-
-static scf_rbtree_node_t* _rbtree_next(scf_rbtree_t* tree, scf_rbtree_node_t* x)
-{
-       if (x->right != &tree->sentinel)
-               return _rbtree_min(tree, x->right);
-
-       scf_rbtree_node_t* y = x->parent;
-
-       while (y != &tree->sentinel && x == y->right) {
-               x = y;
-               y = y->parent;
-       }
-
-       return y;
-}
-
-/* left rotate
-
-    px          px                 px (py)      px (py)
-    |           |                  |            |
-    x           x                  y            y
-   / \         / \                / \          / \
-  xl  y  -->  xl  yl  y   --> x     yr   -->  x   yr
-     / \             / \     / \             / \
-    yl  yr             yr   xl yl           xl yl
-*/
-static void _left_rotate(scf_rbtree_t* tree, scf_rbtree_node_t* x)
-{
-       scf_rbtree_node_t* y = x->right;
-
-       x->right             = y->left;
-       if (&tree->sentinel != y->left)
-               y->left->parent  = x;
-
-       y->parent            = x->parent;
-       if (&tree->sentinel == x->parent)
-               tree->root       = y;
-       else if (x->parent->left == x)
-               x->parent->left       = y;
-       else
-               x->parent->right      = y;
-
-       y->left   = x;
-       x->parent = y;
-}
-
-/* right rotate
-
-       py             py         py (px)           py (px)
-       |              |          |                 |
-       y              y          x                 x
-      / \            / \        / \               / \
-     x  yr -->  x   xr yr -->  xl     y   -->    xl  y
-    / \        / \                   / \            / \
-   xl xr      xl                    xr  yr         xr  yr
-*/
-static void _right_rotate(scf_rbtree_t* tree, scf_rbtree_node_t* y)
-{
-       scf_rbtree_node_t* x = y->left;
-
-       y->left              = x->right;
-       if (&tree->sentinel != x->right)
-               x->right->parent = y;
-
-       x->parent            = y->parent;
-       if (&tree->sentinel == y->parent)
-               tree->root       = x;
-       else if (y->parent->left == y)
-               y->parent->left       = x;
-       else
-               y->parent->right      = x;
-
-       x->right  = y;
-       y->parent = x;
-}
-
-static void _rb_insert_fixup(scf_rbtree_t* tree, scf_rbtree_node_t* z)
-{
-/*
-gp: z's grand-parent
-zp: z's parent
-zu: z's uncle
-*/
-       scf_rbtree_node_t* y;
-
-       while (SCF_RBTREE_RED == z->parent->color) {
-
-               if (z->parent     == z->parent->parent->left) {
-
-                       y = z->parent->parent->right; // y is z's uncle
-
-                       if (y->color == SCF_RBTREE_RED) {
-/*
-        gp (black)
-       /  \
-(red) zp   zu (red)
-      |
-      z (red)
-*/
-                               y->color         =  SCF_RBTREE_BLACK;
-                               z->parent->color =  SCF_RBTREE_BLACK;
-                               z->parent->parent->color = SCF_RBTREE_RED;
-
-                               z = z->parent->parent;
-
-                       } else {
-                               if (z == z->parent->right) {
-/*
-        gp (black)                 gp (black)
-       /  \           left        / \
-(red) zp   zu (black) ---> (red) z   zu (black)   
-     /  \                       / \
-    zb   z (red)     (z', red) zp  
-                                 /
-                             zb
-*/
-                                       z = z->parent;
-                                       _left_rotate(tree, z);
-                               }
-/*
-                gp (red)               (black) z
-               / \           right            / \
-      (black) z   zu (black) --->  (z', red) zp  gp (red)   
-             / \                            /    / \
-  (z', red) zp                             zb       zu (black)
-           /
-          zb
-*/
-                               z->parent->color = SCF_RBTREE_BLACK;
-                               z->parent->parent->color = SCF_RBTREE_RED;
-                               _right_rotate(tree, z->parent->parent);
-                       }
-               } else {
-                       y = z->parent->parent->left; // y is z's uncle
-
-                       if (y->color == SCF_RBTREE_RED) {
-
-                               y->color         =  SCF_RBTREE_BLACK;
-                               z->parent->color =  SCF_RBTREE_BLACK;
-                               z->parent->parent->color = SCF_RBTREE_RED;
-
-                               z = z->parent->parent;
-
-                       } else {
-                               if (z == z->parent->left) {
-/*
-          gp (black)                   gp (black)
-         /  \         right           / \
-(black) zu   zp (red) --->   (black) zu  z (red)  
-            /  \                        / \
-     (red) z   zb                          zp (red, z')
-                                               \
-                                                                                    zb
-*/
-
-                                       z = z->parent;
-                                       _right_rotate(tree, z);
-                               }
-
-/*
-           gp (red)                        z (black)
-          / \              left           / \
-(black) zu   z (black)     --->    (red) gp  zp (red, z')      
-            / \                         / \   \
-               zp (red, z')    (black) zu      zb
-                \
-                 zb
-*/
-                               z->parent->color = SCF_RBTREE_BLACK;
-                               z->parent->parent->color = SCF_RBTREE_RED;
-                               _left_rotate(tree, z->parent->parent);
-                       }
-               }
-       }
-
-       tree->root->color = SCF_RBTREE_BLACK;
-}
-
-int scf_rbtree_insert(scf_rbtree_t* tree, scf_rbtree_node_t* z, scf_rbtree_node_do_pt* cmp)
-{
-       if (!tree || !z || !cmp)
-               return -1;
-
-       scf_rbtree_node_t*  y  = &tree->sentinel;
-       scf_rbtree_node_t** px = &tree->root;
-       scf_rbtree_node_t*  x  = *px;
-
-       while (&tree->sentinel != x) {
-               y = x;
-
-               if (cmp(z, x) < 0)
-                       px = &x->left;
-               else
-                       px = &x->right;
-               x = *px;
-       }
-       // after 'while', y is x's parent, x is the position to insert z.
-
-       z->parent = y;
-       *px = z;
-
-       z->left  = &tree->sentinel;
-       z->right = &tree->sentinel;
-       z->color = SCF_RBTREE_RED;
-
-       _rb_insert_fixup(tree, z);
-       return 0;
-}
-
-static void _rb_delete_fixup(scf_rbtree_t* tree, scf_rbtree_node_t* x)
-{
-       scf_rbtree_node_t*  w;
-
-       //scf_loge("y: %p, z: %p, z->parent: %p\n", y, z, z->parent);
-
-       while (tree->root != x && SCF_RBTREE_BLACK == x->color) {
-
-               if (x == x->parent->left) {
-                       w =  x->parent->right;
-
-                       if (SCF_RBTREE_RED == w->color) {
-/*
-          px (black)  left             w (black)
-            /  \         --->            / \
-(black2)x    w (red)          (red) px  wr (black)
-            / \                     /  \
-  (black) wl   wr (black) (black2) x   wl (w', black)
-         /  \                         /  \
-          wll  wlr                         wll  wlr  
-*/
-                               w->color         == SCF_RBTREE_BLACK;
-                               x->parent->color =  SCF_RBTREE_RED;
-
-                               _left_rotate(tree, x->parent);
-
-                               w = x->parent->right;
-                       }
-
-                       if (SCF_RBTREE_BLACK == w->left->color && SCF_RBTREE_BLACK == w->right->color) {
-/*
-             w (black)
-            / \
-(red, x') px  wr (black)
-         /  \
-(black2)x   wl (w', red)
-           /  \
-         wll  wlr  
-*/
-
-                               w->color = SCF_RBTREE_RED;
-                               x = x->parent;
-
-                       } else {
-                               if (SCF_RBTREE_BLACK == w->right->color) {
-/*
-             w (black)                      w (black)
-            / \                            / \
-    (red) px  wr (black)     right  (red) px  wr (black)
-         /  \                --->        /  \
-(black2)x   wl (w', black)      (black2)x    wll (black, w'')
-           /  \                               \
-    (red) wll  wlr (black)                    wl (w', red)
-                                                  \
-                                                                                          wlr (black)
-*/
-
-                                       w->left->color = SCF_RBTREE_BLACK;
-                                       w->color       = SCF_RBTREE_RED;
-
-                                       _right_rotate(tree, w);
-                                       w = x->parent->right; // w''
-                               }
-
-/*
-             w (black)                                 w (black) 
-            / \                                       / \
-   (black) px  wr (black)         left   (red, w'') wll
-          /  \                    --->              / \
- (black2) x   wll (red, w'')               (black) px  wl (w', black)
-               \                                  /     \
-               wl (w', black)            (black) x      wlr (black)
-                 \
-                 wlr (black)
-*/
-                               w->color = x->parent->color;
-                               x->parent->color = SCF_RBTREE_BLACK;
-                               w->right->color  = SCF_RBTREE_BLACK;
-                               _left_rotate(tree, x->parent);
-
-                               x = tree->root;
-                       }
-               } else {
-                       w =  x->parent->left;
-
-                       if (SCF_RBTREE_RED == w->color) {
-/*
-             px (black)    right            w (black)
-            /  \           --->            /        \
-     (red) w    x (black2)       (black) wl          px (red) 
-          / \                                       / \
-(black) wl   wr (black)                 (black, w')wr  x (black2)
-             / \                                  / \
-           wrl  wrr                                wrl  wrr       
-*/
-                               w->color         == SCF_RBTREE_BLACK;
-                               x->parent->color =  SCF_RBTREE_RED;
-
-                               _right_rotate(tree, x->parent);
-
-                               w = x->parent->left;
-                       }
-
-                       if (SCF_RBTREE_BLACK == w->left->color && SCF_RBTREE_BLACK == w->right->color) {
-/*
-           w (black)
-          /        \
-(black) wl          px (red, x')
-                    / \
-       (black, w')wr   x (black2)
-                 / \
-              wrl   wrr
-*/
-                               w->color = SCF_RBTREE_RED;
-                               x = x->parent;
-
-                       } else {
-                               if (SCF_RBTREE_BLACK == w->left->color) {
-/*
-           w (black)                                w (black)
-          /        \                               / \
-(black) wl          px (red)        left  (black) wl  px (red)
-                    / \             --->             /  \
-       (black, w')wr   x (black2)     (black, w'') wrr   x (black2)
-                 / \                               / 
-      (black) wrl   wrr (red)           (red, w') wr
-                                                    /
-                                       (black) wrl
-*/
-                                       w->right->color = SCF_RBTREE_BLACK;
-                                       w->color        = SCF_RBTREE_RED;
-
-                                       _left_rotate(tree, w);
-                                       w = x->parent->left; // w''
-                               }
-
-/*
-           w (black)                               w (black)                    w (black)
-          /        \          set color           / \            right         / \
-(black) wl          px (red)    ---->    (black) wl  px (black)  ---> (black)wl  wr (w', red)
-                    / \                             / \                          / \
-       (black, w')wr   x (black2)       (red, w') wr   x (black)      (black)wrl   px (black)
-                 / \                              / \                               / \
-        (red) wrl   wrr (black)         (black) wrl  wrr (black)         (black) wrr   x (black)
-*/
-
-                               w->color = x->parent->color;
-                               x->parent->color = SCF_RBTREE_BLACK;
-                               w->left->color  = SCF_RBTREE_BLACK;
-                               _right_rotate(tree, x->parent);
-
-                               x = tree->root;
-                       }
-               }
-       }
-
-       x->color = SCF_RBTREE_BLACK;
-}
-
-int scf_rbtree_delete(scf_rbtree_t* tree, scf_rbtree_node_t* z)
-{
-       if (!tree || !z)
-               return -1;
-
-       scf_rbtree_node_t*  x = NULL;
-       scf_rbtree_node_t*  y = NULL;
-
-       if (&tree->sentinel == z->left || &tree->sentinel == z->right)
-               y = z;
-       else
-               y = _rbtree_next(tree, z);
-
-       if (&tree->sentinel != y->left)
-               x = y->left;
-       else
-               x = y->right;
-
-       // y is the position to delete
-       x->parent = y->parent;
-
-       if (&tree->sentinel == y->parent) {
-               tree->root = x;
-       } else if (y->parent->left == y) {
-               y->parent->left       = x;
-       } else {
-               y->parent->right      = x;
-       }
-
-       uint8_t color = y->color;
-
-       if (y != z) {
-               y->parent = z->parent;
-               y->left   = z->left;
-               y->right  = z->right;
-               y->color  = z->color;
-       }
-
-       // avoid wrong operations to these 3 pointers, only
-       z->parent = NULL;
-       z->left   = NULL;
-       z->right  = NULL;
-
-       if (SCF_RBTREE_BLACK == color)
-               _rb_delete_fixup(tree, x);
-
-       return 0;
-}
-
-scf_rbtree_node_t* scf_rbtree_find(scf_rbtree_t* tree, void* data, scf_rbtree_node_do_pt* cmp)
-{
-       if (!tree || !cmp)
-               return NULL;
-
-       scf_rbtree_node_t* node = tree->root;
-
-       while (&tree->sentinel != node) {
-
-               int ret = cmp(node, data);
-
-               if (ret < 0)
-                       node = node->right;
-               else if (ret > 0)
-                       node = node->left;
-               else
-                       return node;
-       }
-
-       return NULL;
-}
-
-int scf_rbtree_foreach(scf_rbtree_t* tree, scf_rbtree_node_t* root, void* data, scf_rbtree_node_do_pt* done)
-{
-       if (!tree || !root || !done)
-               return -1;
-
-       if (&tree->sentinel == root)
-               return 0;
-
-       int ret;
-
-       if (&tree->sentinel != root->left) {
-
-               ret = scf_rbtree_foreach(tree, root->left, data, done);
-               if (ret < 0)
-                       return ret;
-       }
-
-       ret = done(root, data);
-       if (ret < 0)
-               return ret;
-
-       if (&tree->sentinel != root->right) {
-
-               ret = scf_rbtree_foreach(tree, root->right, data, done);
-               if (ret < 0)
-                       return ret;
-       }
-       return 0;
-}
-
-int scf_rbtree_foreach_reverse(scf_rbtree_t* tree, scf_rbtree_node_t* root, void* data, scf_rbtree_node_do_pt* done)
-{
-       if (!tree || !root || !done)
-               return -1;
-
-       if (&tree->sentinel == root)
-               return 0;
-
-       int ret;
-
-       if (&tree->sentinel != root->right) {
-
-               ret = scf_rbtree_foreach_reverse(tree, root->right, data, done);
-               if (ret < 0)
-                       return ret;
-       }
-
-       ret = done(root, data);
-       if (ret < 0)
-               return ret;
-
-       if (&tree->sentinel != root->left) {
-
-               ret = scf_rbtree_foreach_reverse(tree, root->left, data, done);
-               if (ret < 0)
-                       return ret;
-       }
-       return 0;
-}
-
-int   scf_printf(const char* fmt, ...);
-void* calloc(uintptr_t n, uintptr_t size);
-int   free(void* p);
-
-int scf_rbtree_depth(scf_rbtree_t* tree, scf_rbtree_node_t* root)
-{
-       if (!tree || !root)
-               return -1;
-
-       if (&tree->sentinel == root)
-               return 0;
-
-       int ret;
-
-       if (root == tree->root) {
-               root->depth  = 1;
-               root->bdepth = 1;
-       } else if (SCF_RBTREE_BLACK == root->color) {
-               root->bdepth = root->parent->bdepth + 1;
-               root->depth  = root->parent->depth  + 1;
-       } else {
-               root->bdepth = root->parent->bdepth;
-               root->depth  = root->parent->depth  + 1;
-       }
-
-       scf_printf("root: %p, bdepth: %d, depth: %d\n", root, root->bdepth, root->depth);
-
-       if (&tree->sentinel != root->left) {
-
-               ret = scf_rbtree_depth(tree, root->left);
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (&tree->sentinel != root->right) {
-
-               ret = scf_rbtree_depth(tree, root->right);
-               if (ret < 0)
-                       return ret;
-       }
-       return 0;
-}
-
-
-struct rbtree_test_t
-{
-       scf_rbtree_node_t  node;
-       int d;
-};
-
-static int test_cmp(scf_rbtree_node_t* node0, void* data)
-{
-       rbtree_test_t* v0 = (rbtree_test_t*)node0;
-       rbtree_test_t* v1 = (rbtree_test_t*)data;
-
-       if (v0->d < v1->d)
-               return -1;
-       else if (v0->d > v1->d)
-               return 1;
-       return 0;
-}
-
-static int test_find(scf_rbtree_node_t* node0, void* data)
-{
-       rbtree_test_t* v0 = (rbtree_test_t*)node0;
-       int            d1 = (intptr_t)data;
-
-       if (v0->d < d1)
-               return -1;
-       else if (v0->d > d1)
-               return 1;
-       return 0;
-}
-
-static int test_print(scf_rbtree_node_t* node0, void* data)
-{
-       rbtree_test_t* v0 = (rbtree_test_t*)node0;
-
-       scf_printf("v0->d: %d\n", v0->d);
-       return 0;
-}
-
-const int N = 17;
-
-int main()
-{
-       scf_rbtree_t  tree;
-       scf_rbtree_init(&tree);
-
-       rbtree_test_t* d;
-
-       int i;
-       for (i = 0; i < N; i++) {
-               d = calloc(1, sizeof(rbtree_test_t));
-
-               d->d = i;
-
-               int ret = scf_rbtree_insert(&tree, &d->node, test_cmp);
-               if (ret < 0)
-                       return -1;
-       }
-
-       scf_rbtree_foreach(&tree, tree->root, NULL, test_print);
-
-       scf_rbtree_depth(&tree, tree->root);
-
-       for (i = 0; i < N / 2; i++) {
-               d = (rbtree_test_t*) scf_rbtree_find(&tree, (void*)(intptr_t)i, test_find);
-
-               int ret = scf_rbtree_delete(&tree, &d->node);
-
-               free(d);
-               d = NULL;
-       }
-
-       scf_rbtree_foreach(&tree, tree->root, NULL, test_print);
-
-       scf_rbtree_depth(&tree, tree->root);
-
-       for (i = 0; i < N / 2; i++) {
-               d = calloc(1, sizeof(rbtree_test_t));
-
-               d->d = i;
-
-               int ret = scf_rbtree_insert(&tree, &d->node, test_cmp);
-               if (ret < 0)
-                       return -1;
-       }
-       scf_rbtree_foreach_reverse(&tree, tree->root, NULL, test_print);
-
-       scf_rbtree_depth(&tree, tree->root);
-       return 0;
-}
-
-