From: yu.dongliang <18588496441@163.com> Date: Sun, 16 Nov 2025 15:25:15 +0000 (+0800) Subject: support declare var in for(), such as for(int i = 0; ; ) X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=dbd1879890bf2d4a5439e0697e1c04e72696d0d5;p=scf.git support declare var in for(), such as for(int i = 0; ; ) --- diff --git a/core/scf_block.c b/core/scf_block.c index cf39598..5461b0d 100644 --- a/core/scf_block.c +++ b/core/scf_block.c @@ -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; +} diff --git a/core/scf_block.h b/core/scf_block.h index f405d24..6607f88 100644 --- a/core/scf_block.h +++ b/core/scf_block.h @@ -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 diff --git a/core/scf_dag.c b/core/scf_dag.c index 67e483c..422c74c 100644 --- a/core/scf_dag.c +++ b/core/scf_dag.c @@ -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) { diff --git a/core/scf_expr.c b/core/scf_expr.c index 8a8b081..2cff71c 100644 --- a/core/scf_expr.c +++ b/core/scf_expr.c @@ -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); diff --git a/core/scf_node.h b/core/scf_node.h index 1ad8432..7023d1e 100644 --- a/core/scf_node.h +++ b/core/scf_node.h @@ -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); diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index 7ed9cb1..3d31a07 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -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(); diff --git a/core/scf_optimizer_inline.c b/core/scf_optimizer_inline.c index f710578..1acc05c 100644 --- a/core/scf_optimizer_inline.c +++ b/core/scf_optimizer_inline.c @@ -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 index 0000000..50eddff --- /dev/null +++ b/examples/for.c @@ -0,0 +1,9 @@ +int printf(const char* fmt, ...); + +int main() +{ + for (int i = 0; i < 10; i++) + printf("%d\n", i); + + return 0; +} diff --git a/native/risc/scf_risc.c b/native/risc/scf_risc.c index 2915c98..d0b71d8 100644 --- a/native/risc/scf_risc.c +++ b/native/risc/scf_risc.c @@ -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; diff --git a/native/x64/scf_x64.c b/native/x64/scf_x64.c index 9d7da3b..ced05ba 100644 --- a/native/x64/scf_x64.c +++ b/native/x64/scf_x64.c @@ -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; diff --git a/parse/scf_dfa_call.c b/parse/scf_dfa_call.c index 0c9c5f8..71455bb 100644 --- a/parse/scf_dfa_call.c +++ b/parse/scf_dfa_call.c @@ -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(); diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 240fbcc..fde6bdf 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -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); diff --git a/parse/scf_dfa_for.c b/parse/scf_dfa_for.c index 543c116..c69b45b 100644 --- a/parse/scf_dfa_for.c +++ b/parse/scf_dfa_for.c @@ -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); diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index f1dfa57..35ebbae 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -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; diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 7dbdabe..415069e 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -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; diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 040a42e..8ed0aa6 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -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; diff --git a/parse/scf_parse_util.c b/parse/scf_parse_util.c index afb059c..377c822 100644 --- a/parse/scf_parse_util.c +++ b/parse/scf_parse_util.c @@ -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; -}