support declare var in for(), such as for(int i = 0; ; )
authoryu.dongliang <18588496441@163.com>
Sun, 16 Nov 2025 15:25:15 +0000 (23:25 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 16 Nov 2025 15:25:15 +0000 (23:25 +0800)
17 files changed:
core/scf_block.c
core/scf_block.h
core/scf_dag.c
core/scf_expr.c
core/scf_node.h
core/scf_operator_handler_3ac.c
core/scf_optimizer_inline.c
examples/for.c [new file with mode: 0644]
native/risc/scf_risc.c
native/x64/scf_x64.c
parse/scf_dfa_call.c
parse/scf_dfa_expr.c
parse/scf_dfa_for.c
parse/scf_operator_handler_const.c
parse/scf_operator_handler_semantic.c
parse/scf_parse.c
parse/scf_parse_util.c

index cf3959861dd5cc75d5d5906d94fa065df523b5af..5461b0d364e55a0e22d8f4846d77c0442414d6f9 100644 (file)
@@ -104,7 +104,10 @@ scf_variable_t*    scf_block_find_variable(scf_block_t* b, const char* name)
 {
        assert(b);
        while (b) {
-               if (SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type || b->node.type >= SCF_STRUCT) {
+               if (SCF_OP_BLOCK        == b->node.type
+                               || SCF_OP_FOR   == b->node.type
+                               || SCF_FUNCTION == b->node.type
+                               || b->node.type >= SCF_STRUCT) {
 
                        if (b->scope) {
                                scf_variable_t* v = scf_scope_find_variable(b->scope, name);
@@ -151,3 +154,63 @@ scf_label_t* scf_block_find_label(scf_block_t* b, const char* name)
        }
        return NULL;
 }
+
+int __find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results)
+{
+       if (SCF_OP_BLOCK == node->type || SCF_OP_FOR == node->type || SCF_FUNCTION == node->type) {
+
+               scf_variable_t*  v;
+               scf_block_t*     b = (scf_block_t*)node;
+               int i;
+
+               if (b->scope) {
+                       for (i = 0; i < b->scope->vars->size; i++) {
+                               v =         b->scope->vars->data[i];
+
+                               int ret = scf_vector_add(results, v);
+                               if (ret < 0)
+                                       return ret;
+                       }
+               }
+       }
+       return 0;
+}
+
+int __find_function(scf_node_t* node, void* arg, scf_vector_t* results)
+{
+       if (SCF_FUNCTION == node->type) {
+
+               scf_function_t* f = (scf_function_t*)node;
+
+               return scf_vector_add(results, f);
+       }
+
+       return 0;
+}
+
+int __find_global_var(scf_node_t* node, void* arg, scf_vector_t* results)
+{
+       if (SCF_OP_BLOCK == node->type
+                       || (node->type >= SCF_STRUCT && node->class_flag)) {
+
+               scf_variable_t* v;
+               scf_block_t*    b = (scf_block_t*)node;
+               int i;
+
+               if (!b->scope || !b->scope->vars)
+                       return 0;
+
+               for (i = 0; i < b->scope->vars->size; i++) {
+                       v  =        b->scope->vars->data[i];
+
+                       if (v->global_flag || v->static_flag) {
+
+                               int ret = scf_vector_add(results, v);
+                               if (ret < 0)
+                                       return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
index f405d24727c1d7d55fe495f7396c7319d87cc68d..6607f88c263dc179bf8ce85efb2a21b201db6a6d 100644 (file)
@@ -28,5 +28,6 @@ scf_function_t*       scf_block_find_function(scf_block_t* b, const char* name);
 
 scf_label_t*    scf_block_find_label(scf_block_t* b, const char* name);
 
-#endif
+int             _find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results);
 
+#endif
index 67e483c6ba3624bac3fe1cf348dae82d2e17b720..422c74c42dc11725b801bfd20a39b4b42dc5224e 100644 (file)
@@ -280,7 +280,11 @@ void scf_dn_status_print(scf_dn_status_t* ds)
 
        if (ds->dag_node) {
                v = ds->dag_node->var;
-               printf("dn: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+
+               if (v->w)
+                       printf("dn: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+               else
+                       printf("dn: v_%#lx ", (uintptr_t)v & 0xffff);
 
                if (ds->dn_indexes) {
                        for (i = ds->dn_indexes->size - 1; i >= 0; i--) {
@@ -296,7 +300,10 @@ void scf_dn_status_print(scf_dn_status_t* ds)
 
        if (ds->alias) {
                v = ds->alias->var;
-               printf(" alias: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+               if (v->w)
+                       printf(" alias: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+               else
+                       printf(" alias: v_%#lx ", (uintptr_t)v & 0xffff);
 
                if (ds->alias_indexes) {
                        for (i = ds->alias_indexes->size - 1; i >= 0; i--) {
@@ -310,7 +317,7 @@ void scf_dn_status_print(scf_dn_status_t* ds)
                }
        }
 
-       printf(" alias_type: %d\n", ds->alias_type);
+       printf(" alias_type: %d, ret_flag: %d, ret_index: %d\n", ds->alias_type, ds->ret_flag, ds->ret_index);
 }
 
 scf_dag_node_t* scf_dag_node_alloc(int type, scf_variable_t* var, const scf_node_t* node)
@@ -548,9 +555,6 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node)
                scf_logd("dag   type: %d, node: %#lx, var: %#lx\n", dn->type, 0xffff & (uintptr_t)dn, 0xffff & (uintptr_t)dn->var);
        }
 
-       if (SCF_OP_NEW == node->type)
-               node = node->result_nodes->data[0];
-
        if (dn->type != node->type)
                return 0;
 
@@ -571,14 +575,26 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node)
                        || SCF_OP_INC_POST == node->type
                        || SCF_OP_DEC_POST == node->type
                        || SCF_OP_ADDRESS_OF == node->type) {
-               if (dn->var == _scf_operand_get((scf_node_t*)node))
+               if (dn->var == _scf_operand_get(node))
                        return 1;
+
                return 0;
        }
 
        if (!dn->childs) {
-               if (SCF_OP_CALL == node->type && 1 == node->nb_nodes)
-                       return __dn_same_call(dn, node, split);
+               switch (node->type) {
+                       case SCF_OP_CALL:
+                               //if (1 == node->nb_nodes)
+                               return __dn_same_call(dn, node, split);
+                               break;
+
+                       case SCF_OP_POINTER:
+                               return dn->var == _scf_operand_get(node);
+                               break;
+                       default:
+                               break;
+               };
+
                return 0;
        }
 
@@ -631,8 +647,12 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node)
                }
        }
 
-       if (dn->childs->size != node->nb_nodes)
+       if (dn->childs->size != node->nb_nodes) {
+               if (SCF_OP_CALL == node->type /*&& 1 == node->nb_nodes*/)
+                       return __dn_same_call(dn, node, split);
+
                return 0;
+       }
 
 cmp_childs:
        for (i = 0; i < node->nb_nodes; i++) {
@@ -715,7 +735,6 @@ int scf_dag_get_node(scf_list_t* h, const scf_node_t* node, scf_dag_node_t** pp)
                node2 = node;
 
        v  = _scf_operand_get((scf_node_t*)node2);
-
        dn = scf_dag_find_node(h, node2);
 
        if (!dn) {
index 8a8b081bc795992a5fb97747cd657322eeeeac5f..2cff71cc4aa5cfa1fefeb3f2e1cb0a318068f097 100644 (file)
@@ -91,6 +91,7 @@ static int __expr_node_add_node(scf_node_t** pparent, scf_node_t* child)
        }
 
        // parent->priority == child->priority
+       scf_logi("parent: %p, parent->type: %d, FOR: %d, SCF_VAR_INT: %d\n", parent, parent->type, SCF_OP_FOR, SCF_VAR_INT);
        assert(parent->op);
        assert(child->op);
 
index 1ad8432986ab6db4a480884d4ceb19c481ec5211..7023d1e77944f6f0919a4da8ecb9ad20d0db0e62 100644 (file)
@@ -79,6 +79,10 @@ scf_function_t* _scf_function_get(scf_node_t* node);
 typedef int     (*scf_node_find_pt)(scf_node_t* node, void* arg, scf_vector_t* results);
 int             scf_node_search_bfs(scf_node_t* root, void* arg, scf_vector_t* results, int max, scf_node_find_pt find);
 
+int             __find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results);
+int             __find_global_var(scf_node_t* node, void* arg, scf_vector_t* results);
+int             __find_function  (scf_node_t* node, void* arg, scf_vector_t* results);
+
 scf_label_t*   scf_label_alloc(scf_lex_word_t* w);
 void                   scf_label_free(scf_label_t* l);
 
index 7ed9cb1f40322248ee111ac8f99fafafda89b10f..3d31a07f70c08584a4b29dfe689a14f7b0292752 100644 (file)
@@ -1289,17 +1289,23 @@ static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d
        scf_list_t*     start_prev = scf_list_tail(d->_3ac_list_head);
        scf_3ac_code_t* jmp_end    = NULL;
 
-       if (nodes[1]) {
-               assert(SCF_OP_EXPR == nodes[1]->type);
-
-               int jmp_op = _scf_op_cond(ast, nodes[1], d);
-               if (jmp_op < 0) {
+       scf_node_t* cond = nodes[1];
+       if (cond) {
+               if (_scf_op_node(ast, cond, d) < 0) {
                        scf_loge("\n");
                        return -1;
                }
 
-               jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL);
-               scf_list_add_tail(d->_3ac_list_head, &jmp_end->list);
+               if (cond->nb_nodes > 0) {
+                       int jmp_op = _scf_op_cond(ast, cond->nodes[cond->nb_nodes - 1], d);
+                       if (jmp_op < 0) {
+                               scf_loge("\n");
+                               return -1;
+                       }
+
+                       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();
index f7105787b59f944a56d0ea6aad87fb63a2d19ff4..1acc05c9a53eadc6d0283fe4bbb03f6a8c142825 100644 (file)
@@ -186,25 +186,6 @@ static int _copy_codes(scf_list_t* hbb, scf_vector_t* argv, scf_3ac_code_t* c, s
        return 0;
 }
 
-static int _find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results)
-{
-       scf_block_t* b = (scf_block_t*)node;
-
-       if ((SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type) && b->scope) {
-
-               int i;
-               for (i = 0; i < b->scope->vars->size; i++) {
-
-                       scf_variable_t* var = b->scope->vars->data[i];
-
-                       int ret = scf_vector_add(results, var);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-       return 0;
-}
-
 static int _do_inline(scf_ast_t* ast, scf_3ac_code_t* c, scf_basic_block_t** pbb, scf_function_t* f, scf_function_t* f2)
 {
        scf_basic_block_t* bb = *pbb;
@@ -254,7 +235,7 @@ static int _do_inline(scf_ast_t* ast, scf_3ac_code_t* c, scf_basic_block_t** pbb
 
        scf_vector_clear(argv, NULL);
 
-       int ret = scf_node_search_bfs((scf_node_t*)f2, NULL, argv, -1, _find_local_vars);
+       int ret = scf_node_search_bfs((scf_node_t*)f2, NULL, argv, -1, __find_local_vars);
        if (ret < 0) {
                scf_vector_free(argv);
                return -ENOMEM;
diff --git a/examples/for.c b/examples/for.c
new file mode 100644 (file)
index 0000000..50eddff
--- /dev/null
@@ -0,0 +1,9 @@
+int printf(const char* fmt, ...);
+
+int main()
+{
+       for (int i = 0; i < 10; i++)
+               printf("%d\n", i);
+
+       return 0;
+}
index 2915c9868ade872d31bd4ac1fd08d35d2d94b6b6..d0b71d8b21bb0bbfb70f3b28c6b5a0b48b72c18f 100644 (file)
@@ -1079,25 +1079,6 @@ int      _scf_risc_select_inst(scf_native_t* ctx)
        return 0;
 }
 
-static int _find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results)
-{
-       scf_block_t* b = (scf_block_t*)node;
-
-       if ((SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type) && b->scope) {
-
-               int i;
-               for (i = 0; i < b->scope->vars->size; i++) {
-
-                       scf_variable_t* var = b->scope->vars->data[i];
-
-                       int ret = scf_vector_add(results, var);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-       return 0;
-}
-
 int scf_risc_select_inst(scf_native_t* ctx, scf_function_t* f)
 {
        scf_risc_context_t* risc = ctx->priv;
@@ -1110,7 +1091,7 @@ int scf_risc_select_inst(scf_native_t* ctx, scf_function_t* f)
        if (!local_vars)
                return -ENOMEM;
 
-       int ret = scf_node_search_bfs((scf_node_t*)f, NULL, local_vars, -1, _find_local_vars);
+       int ret = scf_node_search_bfs((scf_node_t*)f, NULL, local_vars, -1, __find_local_vars);
        if (ret < 0)
                return ret;
 
index 9d7da3bb3ae38c93e6530d7fa8a3427eb1cdebe3..ced05bad09c9daaa2167086f750156292f67e32b 100644 (file)
@@ -1100,25 +1100,6 @@ int      _scf_x64_select_inst(scf_native_t* ctx)
        return 0;
 }
 
-static int _find_local_vars(scf_node_t* node, void* arg, scf_vector_t* results)
-{
-       scf_block_t* b = (scf_block_t*)node;
-
-       if ((SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type) && b->scope) {
-
-               int i;
-               for (i = 0; i < b->scope->vars->size; i++) {
-
-                       scf_variable_t* var = b->scope->vars->data[i];
-
-                       int ret = scf_vector_add(results, var);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-       return 0;
-}
-
 int scf_x64_select_inst(scf_native_t* ctx, scf_function_t* f)
 {
        scf_x64_context_t* x64 = ctx->priv;
@@ -1129,7 +1110,7 @@ int scf_x64_select_inst(scf_native_t* ctx, scf_function_t* f)
        if (!local_vars)
                return -ENOMEM;
 
-       int ret = scf_node_search_bfs((scf_node_t*)f, NULL, local_vars, -1, _find_local_vars);
+       int ret = scf_node_search_bfs((scf_node_t*)f, NULL, local_vars, -1, __find_local_vars);
        if (ret < 0)
                return ret;
 
index 0c9c5f84201ee01ecb9a438c432c81fb7c6be6f1..71455bbce90bc88e6fb17eeffc893eb5bcdfd833 100644 (file)
@@ -122,7 +122,7 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
-       scf_logd("d->expr: %p\n", d->expr);
+       scf_logi("d->expr: %p, OP: %d\n", d->expr, d->expr->type);
 
        cd->func           = node_pf;
        cd->call           = node_call;
@@ -174,6 +174,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_stack_pop(s);
 
+       scf_logi("d->expr: %p\n", d->expr);
+
        if (cd->parent_expr) {
                scf_expr_add_node(cd->parent_expr, cd->func);
                scf_expr_add_node(cd->parent_expr, cd->call);
@@ -233,6 +235,7 @@ static int _call_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                scf_loge("\n");
                return SCF_DFA_ERROR;
        }
+       scf_logi("d->expr: %p\n", d->expr);
 
        if (!cd->argv)
                cd->argv = scf_vector_alloc();
index 240fbcc2b4ac77183cd1d87b342e5ab157abc526..fde6bdf0ac2f16ae4b15b0e1060175a494e48992 100644 (file)
@@ -716,7 +716,7 @@ int _expr_multi_rets(scf_expr_t* e)
        return 0;
 }
 
-static int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag)
+int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag)
 {
        expr_module_data_t* md = d->module_datas[dfa_module_expr.index];
        dfa_identity_t*     id = scf_stack_top(d->current_identities);
index 543c1169499454feb1467c2a656d438a2754baae..c69b45b8ff679024fb4b0ec4049645f29681059a 100644 (file)
@@ -12,15 +12,16 @@ typedef struct {
        scf_block_t*     parent_block;
        scf_node_t*      parent_node;
 
-       scf_node_t*      _for;
+       scf_block_t*     _for;
 
-       int              nb_semicolons;
-       scf_vector_t*    init_exprs;
-       scf_expr_t*      cond_expr;
-       scf_vector_t*    update_exprs;
+       scf_block_t*     init_exprs;
+       scf_block_t*     cond_exprs;
+       scf_block_t*     update_exprs;
 
+       int              nb_semicolons;
 } dfa_for_data_t;
 
+int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag);
 
 static int _for_is_end(scf_dfa_t* dfa, void* word)
 {
@@ -30,28 +31,37 @@ static int _for_is_end(scf_dfa_t* dfa, void* word)
 static int _for_action_for(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*     parse = dfa->priv;
+       scf_ast_t*       ast   = parse->ast;
        dfa_data_t*      d     = data;
        scf_lex_word_t*  w     = words->data[words->size - 1];
        dfa_for_data_t*  fd    = NULL;
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
-       scf_node_t*     _for   = scf_node_alloc(w, SCF_OP_FOR, NULL);
+       scf_block_t*    _for   = scf_block_alloc(w);
 
        if (!_for)
                return -ENOMEM;
+       _for->node.type = SCF_OP_FOR;
+
+       int ret;
+       if (d->current_node)
+               ret = scf_node_add_child(d->current_node, (scf_node_t*) _for);
+       else
+               ret = scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*) _for);
+       if (ret < 0) {
+               scf_block_free(_for);
+               return ret;
+       }
 
        fd = calloc(1, sizeof(dfa_for_data_t));
        if (!fd)
                return -ENOMEM;
 
-       if (d->current_node)
-               scf_node_add_child(d->current_node, _for);
-       else
-               scf_node_add_child((scf_node_t*)parse->ast->current_block, _for);
+       fd->parent_block   = ast->current_block;
+       fd->parent_node    = d->current_node;
+       fd->_for           = _for;
+       d->current_node    = (scf_node_t*) _for;
 
-       fd->parent_block = parse->ast->current_block;
-       fd->parent_node  = d->current_node;
-       fd->_for         = _for;
-       d->current_node  = _for;
+       ast->current_block = _for;
 
        scf_stack_push(s, fd);
 
@@ -67,11 +77,10 @@ static int _for_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_for_data_t*   fd    = scf_stack_top(s);
 
        assert(!d->expr);
-       d->expr_local_flag = 1;
+//     d->expr_local_flag = 1;
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_rp"),        SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_semicolon"), SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),     SCF_DFA_HOOK_POST);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_semicolon"), SCF_DFA_HOOK_END);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"),   SCF_DFA_HOOK_POST);
 
        return SCF_DFA_NEXT_WORD;
@@ -90,142 +99,82 @@ static int _for_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _for_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _for_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
+       if (!data)
+               return SCF_DFA_ERROR;
+
        scf_parse_t*     parse = dfa->priv;
        dfa_data_t*      d     = data;
        scf_lex_word_t*  w     = words->data[words->size - 1];
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
        dfa_for_data_t*  fd    = scf_stack_top(s);
+       scf_block_t*     b;
+       scf_node_t*      node;
+       int i;
 
-       if (!d->expr) {
-               scf_loge("need expr before ',' in file: %s, line: %d\n", w->file->data, w->line);
+       if (fd->nb_semicolons > 1) {
+               scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
                return SCF_DFA_ERROR;
        }
 
-       switch (fd->nb_semicolons) {
-               case 0:
-                       if (d->expr) {
-                               if (!fd->init_exprs)
-                                       fd->init_exprs = scf_vector_alloc();
-
-                               scf_vector_add(fd->init_exprs, d->expr);
-                               d->expr = NULL;
-                       }
-                       break;
-
-               case 1:
-                       fd->cond_expr = d->expr;
-                       d->expr = NULL;
-                       break;
-
-               case 2:
-                       if (d->expr) {
-                               if (!fd->update_exprs)
-                                       fd->update_exprs = scf_vector_alloc();
-
-                               scf_vector_add(fd->update_exprs, d->expr);
-                               d->expr = NULL;
-                       }
-                       break;
-               default:
-                       scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-                       return SCF_DFA_ERROR;
-                       break;
-       };
-
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),   SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"), SCF_DFA_HOOK_POST);
-
-       return SCF_DFA_NEXT_WORD;
-}
+       b = scf_block_alloc(w);
+       if (!b)
+               return -ENOMEM;
 
-static int _for_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       if (!data)
-               return SCF_DFA_ERROR;
+       SCF_XCHG(fd->_for->node.nb_nodes, b->node.nb_nodes);
+       SCF_XCHG(fd->_for->node.nodes,    b->node.nodes);
 
-       scf_parse_t*     parse = dfa->priv;
-       dfa_data_t*      d     = data;
-       scf_lex_word_t*  w     = words->data[words->size - 1];
-       scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
-       dfa_for_data_t*  fd    = scf_stack_top(s);
-
-       switch (fd->nb_semicolons) {
-               case 0:
-                       if (d->expr) {
-                               if (!fd->init_exprs)
-                                       fd->init_exprs = scf_vector_alloc();
-
-                               scf_vector_add(fd->init_exprs, d->expr);
-                               d->expr = NULL;
-                       }
-                       break;
-
-               case 1:
-                       fd->cond_expr = d->expr;
-                       d->expr = NULL;
-                       break;
-               default:
-                       scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-                       return SCF_DFA_ERROR;
-                       break;
+       for (i = 0; i < b->node.nb_nodes; i++) {
+               node      = b->node.nodes[i];
+               node->parent = (scf_node_t*)b;
        }
 
+       if (0 == fd->nb_semicolons)
+               fd->init_exprs = b;
+       else
+               fd->cond_exprs = b;
+
        fd->nb_semicolons++;
 
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_semicolon"), SCF_DFA_HOOK_POST);
-       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),     SCF_DFA_HOOK_POST);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_semicolon"), SCF_DFA_HOOK_END);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"),   SCF_DFA_HOOK_POST);
 
        return SCF_DFA_SWITCH_TO;
 }
 
-static int _for_add_expr_vector(dfa_for_data_t* fd, scf_vector_t* vec)
+static int _for_add_exprs(dfa_for_data_t* fd)
 {
-       if (!vec) {
-               scf_node_add_child(fd->_for, NULL);
-               return SCF_DFA_OK;
-       }
-
-       if (0 == vec->size) {
-               scf_node_add_child(fd->_for, NULL);
-
-               scf_vector_free(vec);
-               vec = NULL;
-               return SCF_DFA_OK;
-       }
-
-       scf_block_t* b = scf_block_alloc_cstr("for");
-       if (!b)
-               return -ENOMEM;
-       scf_node_add_child(fd->_for, (scf_node_t*)b);
-
-       int i;
-       for (i = 0; i < vec->size; i++) {
+       assert(0 == fd->_for->node.nb_nodes);
 
-               scf_expr_t* e = vec->data[i];
+       int ret = scf_node_add_child((scf_node_t*)fd->_for, (scf_node_t*)fd->init_exprs);
+       if (ret < 0)
+               goto _init_error;
 
-               scf_node_add_child((scf_node_t*)b, e);
-       }
+       ret = scf_node_add_child((scf_node_t*)fd->_for, (scf_node_t*)fd->cond_exprs);
+       if (ret < 0)
+               goto _cond_error;
 
-       scf_vector_free(vec);
-       vec = NULL;
-       return SCF_DFA_OK;
-}
+       ret = scf_node_add_child((scf_node_t*)fd->_for, (scf_node_t*)fd->update_exprs);
+       if (ret < 0)
+               goto _update_error;
 
-static int _for_add_exprs(dfa_for_data_t* fd)
-{
-       _for_add_expr_vector(fd, fd->init_exprs);
        fd->init_exprs = NULL;
+       fd->cond_exprs = NULL;
+       fd->update_exprs = NULL;
+       return 0;
 
-       scf_node_add_child(fd->_for, fd->cond_expr);
-       fd->cond_expr = NULL;
+_init_error:
+       scf_block_free(fd->init_exprs);
+_cond_error:
+       scf_block_free(fd->cond_exprs);
+_update_error:
+       scf_block_free(fd->update_exprs);
 
-       _for_add_expr_vector(fd, fd->update_exprs);
+       fd->init_exprs = NULL;
+       fd->cond_exprs = NULL;
        fd->update_exprs = NULL;
-
-       return SCF_DFA_OK;
+       return ret;
 }
 
 static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
@@ -235,34 +184,46 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_lex_word_t*  w     = words->data[words->size - 1];
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
        dfa_for_data_t*  fd    = scf_stack_top(s);
+       scf_block_t*     b;
+       scf_node_t*      node;
+       int i;
 
        fd->nb_rps++;
 
        if (fd->nb_rps < fd->nb_lps) {
 
                SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_rp"),        SCF_DFA_HOOK_POST);
-               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_semicolon"), SCF_DFA_HOOK_POST);
-               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),     SCF_DFA_HOOK_POST);
                SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"),   SCF_DFA_HOOK_POST);
 
                return SCF_DFA_NEXT_WORD;
        }
 
-       if (2 == fd->nb_semicolons) {
-               if (d->expr) {
-                       if (!fd->update_exprs)
-                               fd->update_exprs = scf_vector_alloc();
+       assert (2 == fd->nb_semicolons);
 
-                       scf_vector_add(fd->update_exprs, d->expr);
-                       d->expr = NULL;
-               }
-       } else {
-               scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-               return SCF_DFA_ERROR;
+       scf_dfa_del_hook_by_name(&dfa->hooks[SCF_DFA_HOOK_END], "for_semicolon");
+
+       if (d->expr) {
+               if (_expr_fini_expr(parse, d, 0) < 0)
+                       return SCF_DFA_ERROR;
        }
 
-       _for_add_exprs(fd);
-       d->expr_local_flag = 0;
+       b = scf_block_alloc(w);
+       if (!b)
+               return -ENOMEM;
+
+       SCF_XCHG(fd->_for->node.nb_nodes, b->node.nb_nodes);
+       SCF_XCHG(fd->_for->node.nodes,    b->node.nodes);
+
+       for (i = 0; i < b->node.nb_nodes; i++) {
+               node      = b->node.nodes[i];
+               node->parent = (scf_node_t*)b;
+       }
+
+       fd->update_exprs = b;
+
+       int ret = _for_add_exprs(fd);
+       if (ret < 0)
+               return ret;
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_end"), SCF_DFA_HOOK_END);
 
@@ -272,18 +233,18 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 static int _for_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*     parse = dfa->priv;
+       scf_ast_t*       ast   = parse->ast;
        dfa_data_t*      d     = data;
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
        dfa_for_data_t*  fd    = scf_stack_pop(s);
 
-       if (3 == fd->_for->nb_nodes)
-               scf_node_add_child(fd->_for, NULL);
-
-       assert(parse->ast->current_block == fd->parent_block);
+       if (3 == fd->_for->node.nb_nodes)
+               scf_node_add_child((scf_node_t*)fd->_for, NULL);
 
-       d->current_node = fd->parent_node;
+       ast->current_block = fd->parent_block;
+       d->current_node    = fd->parent_node;
 
-       scf_logi("for: %d, fd: %p, s->size: %d\n", fd->_for->w->line, fd, s->size);
+       scf_logi("for: %d, fd: %p, s->size: %d\n", fd->_for->node.w->line, fd, s->size);
 
        free(fd);
        fd = NULL;
@@ -296,7 +257,6 @@ static int _for_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 static int _dfa_init_module_for(scf_dfa_t* dfa)
 {
        SCF_DFA_MODULE_NODE(dfa, for, semicolon, scf_dfa_is_semicolon,  _for_action_semicolon);
-       SCF_DFA_MODULE_NODE(dfa, for, comma,     scf_dfa_is_comma,      _for_action_comma);
        SCF_DFA_MODULE_NODE(dfa, for, end,       _for_is_end,           _for_action_end);
 
        SCF_DFA_MODULE_NODE(dfa, for, lp,        scf_dfa_is_lp,         _for_action_lp);
@@ -340,7 +300,6 @@ static int _dfa_fini_module_for(scf_dfa_t* dfa)
 static int _dfa_init_syntax_for(scf_dfa_t* dfa)
 {
        SCF_DFA_GET_MODULE_NODE(dfa, for,   semicolon, semicolon);
-       SCF_DFA_GET_MODULE_NODE(dfa, for,   comma,     comma);
        SCF_DFA_GET_MODULE_NODE(dfa, for,   lp,        lp);
        SCF_DFA_GET_MODULE_NODE(dfa, for,   lp_stat,   lp_stat);
        SCF_DFA_GET_MODULE_NODE(dfa, for,   rp,        rp);
@@ -350,15 +309,25 @@ static int _dfa_init_syntax_for(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, expr,  entry,     expr);
        SCF_DFA_GET_MODULE_NODE(dfa, block, entry,     block);
 
+       SCF_DFA_GET_MODULE_NODE(dfa, type,     _const,    _const);
+       SCF_DFA_GET_MODULE_NODE(dfa, type,     base_type, base_type);
+       SCF_DFA_GET_MODULE_NODE(dfa, identity, identity,  type_name);
+
        // for start
        scf_vector_add(dfa->syntaxes,  _for);
 
-       // condition expr
+       // dead loop
        scf_dfa_node_add_child(_for,      lp);
        scf_dfa_node_add_child(lp,        semicolon);
        scf_dfa_node_add_child(semicolon, semicolon);
        scf_dfa_node_add_child(semicolon, rp);
 
+       // declare loop var in for
+       scf_dfa_node_add_child(lp,        _const);
+       scf_dfa_node_add_child(lp,        base_type);
+       scf_dfa_node_add_child(lp,        type_name);
+
+       // init, cond, update expr
        scf_dfa_node_add_child(lp,        expr);
        scf_dfa_node_add_child(expr,      semicolon);
        scf_dfa_node_add_child(semicolon, expr);
index f1dfa570506595637df83a5ab7d3b09c42d98d63..35ebbaeacb52ef7acd1deeacefe7980af6dd0507 100644 (file)
@@ -380,27 +380,8 @@ static int _scf_op_const_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, v
 
        scf_handler_data_t* d = data;
 
-       if (nodes[0]) {
-               if (_scf_op_const_node(ast, nodes[0], d) < 0) {
-                       scf_loge("\n");
-                       return -1;
-               }
-       }
-
-       scf_expr_t* e = nodes[1];
-       if (e) {
-               assert(SCF_OP_EXPR == e->type);
-
-               scf_variable_t* r = NULL;
-
-               if (_scf_expr_calculate_internal(ast, e, &r) < 0) {
-                       scf_loge("\n");
-                       return -1;
-               }
-       }
-
        int i;
-       for (i = 2; i < nb_nodes; i++) {
+       for (i = 0; i < nb_nodes; i++) {
                if (!nodes[i])
                        continue;
 
index 7dbdabe700430fae484975203dd45c57dbf8f05b..415069e6869b7bf2a95b7599e21940cc64156dce 100644 (file)
@@ -1512,23 +1512,22 @@ static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
                }
        }
 
-       scf_expr_t* e = nodes[1];
-       if (e) {
-               assert(SCF_OP_EXPR == e->type);
-
-               scf_variable_t* r = NULL;
-
-               if (_scf_expr_calculate(ast, e, &r) < 0) {
+       scf_node_t* cond = nodes[1];
+       if (cond) {
+               ret = _scf_op_semantic_node(ast, cond, d);
+               if (ret < 0) {
                        scf_loge("\n");
-                       return -1;
+                       return ret;
                }
 
-               if (!r || !scf_variable_integer(r)) {
-                       scf_loge("\n");
-                       return -1;
+               if (cond->nb_nodes > 0) { // the final expr is real cond expr
+                       scf_variable_t* r = _scf_operand_get(cond->nodes[cond->nb_nodes - 1]);
+
+                       if (!r || !scf_variable_integer(r)) {
+                               scf_loge("\n");
+                               return -1;
+                       }
                }
-               scf_variable_free(r);
-               r = NULL;
        }
 
        int i;
index 040a42e8057f99a65a47d09c346829608d1de188..8ed0aa68b830cdf81a98fed17641f576d60f3c78 100644 (file)
@@ -2374,7 +2374,7 @@ int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac)
        if (!functions)
                return -ENOMEM;
 
-       int ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, _find_function);
+       int ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, __find_function);
        if (ret < 0)
                goto error;
 
@@ -2407,7 +2407,7 @@ int scf_parse_to_obj(scf_parse_t* parse, const char* out, const char* arch)
        if (!functions)
                return -ENOMEM;
 
-       int ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, _find_function);
+       int ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, __find_function);
        if (ret < 0) {
                scf_vector_free(functions);
                return ret;
@@ -2426,7 +2426,7 @@ int scf_parse_to_obj(scf_parse_t* parse, const char* out, const char* arch)
                goto global_vars_error;
        }
 
-       ret = scf_node_search_bfs((scf_node_t*)b, NULL, global_vars, -1, _find_global_var);
+       ret = scf_node_search_bfs((scf_node_t*)b, NULL, global_vars, -1, __find_global_var);
        if (ret < 0) {
                scf_loge("\n");
                goto code_error;
index afb059c82b3043dcf36af15dd36679ba877a0058..377c8228c98a7574ef34a63e5f22913376b89a2a 100644 (file)
@@ -1,41 +1,3 @@
 #include"scf_parse.h"
 
-int _find_function(scf_node_t* node, void* arg, scf_vector_t* vec)
-{
-       if (SCF_FUNCTION == node->type) {
-
-               scf_function_t* f = (scf_function_t*)node;
-
-               return scf_vector_add(vec, f);
-       }
-
-       return 0;
-}
-
-int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec)
-{
-       if (SCF_OP_BLOCK == node->type
-                       || (node->type >= SCF_STRUCT && node->class_flag)) {
-
-               scf_block_t* b = (scf_block_t*)node;
-
-               if (!b->scope || !b->scope->vars)
-                       return 0;
-
-               int i;
-               for (i = 0; i < b->scope->vars->size; i++) {
-
-                       scf_variable_t* v = b->scope->vars->data[i];
-
-                       if (v->global_flag || v->static_flag) {
-
-                               int ret = scf_vector_add(vec, v);
-                               if (ret < 0)
-                                       return ret;
-                       }
-               }
-       }
-
-       return 0;
-}