From: yu.dongliang <18588496441@163.com> Date: Tue, 18 Nov 2025 13:35:37 +0000 (+0800) Subject: fix: for() loop without cond expr, such as 'for( ; ; )' X-Git-Url: http://baseworks.info/?a=commitdiff_plain;ds=inline;p=scf.git fix: for() loop without cond expr, such as 'for( ; ; )' --- diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index 3d31a07..33d276c 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -796,85 +796,98 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s scf_list_t* l2; scf_list_t* cond_prev = scf_list_tail(d->_3ac_list_head); - 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); + int jmp_op = -1; + if (jmp_end) { + 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); - c2 = scf_3ac_code_clone(c); - if (!c2) - return -ENOMEM; + c2 = scf_3ac_code_clone(c); + if (!c2) + return -ENOMEM; - scf_list_add_tail(d->_3ac_list_head, &c2->list); - } + scf_list_add_tail(d->_3ac_list_head, &c2->list); + } - for (l = scf_list_next(cond_prev); l != scf_list_sentinel(d->_3ac_list_head); l = scf_list_next(l)) { - c = scf_list_data(l, scf_3ac_code_t, list); + for (l = scf_list_next(cond_prev); l != scf_list_sentinel(d->_3ac_list_head); l = scf_list_next(l)) { + c = scf_list_data(l, scf_3ac_code_t, list); - if (!scf_type_is_jmp(c->op->type)) - continue; + 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); + 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); - dst = c->dsts->data[0]; + dst = c->dsts->data[0]; - if (dst->code == c2->origin) { - dst->code = c2; - break; + if (dst->code == c2->origin) { + dst->code = c2; + break; + } } + assert(l2 != scf_list_sentinel(d->_3ac_list_head)); + + if (scf_vector_add(d->branch_ops->_breaks, c) < 0) + return -1; } - assert(l2 != scf_list_sentinel(d->_3ac_list_head)); - if (scf_vector_add(d->branch_ops->_breaks, c) < 0) - return -1; - } + switch (jmp_end->op->type) { - int jmp_op = -1; - switch (jmp_end->op->type) { + case SCF_OP_3AC_JNZ: + jmp_op = SCF_OP_3AC_JZ; + break; + case SCF_OP_3AC_JZ: + jmp_op = SCF_OP_3AC_JNZ; + break; + case SCF_OP_3AC_JLE: + jmp_op = SCF_OP_3AC_JGT; + break; + case SCF_OP_3AC_JLT: + jmp_op = SCF_OP_3AC_JGE; + break; + case SCF_OP_3AC_JGE: + jmp_op = SCF_OP_3AC_JLT; + break; + case SCF_OP_3AC_JGT: + jmp_op = SCF_OP_3AC_JLE; + break; - case SCF_OP_3AC_JNZ: - jmp_op = SCF_OP_3AC_JZ; - break; - case SCF_OP_3AC_JZ: - jmp_op = SCF_OP_3AC_JNZ; - break; - case SCF_OP_3AC_JLE: - jmp_op = SCF_OP_3AC_JGT; - break; - case SCF_OP_3AC_JLT: - jmp_op = SCF_OP_3AC_JGE; - break; - case SCF_OP_3AC_JGE: - jmp_op = SCF_OP_3AC_JLT; - break; - case SCF_OP_3AC_JGT: - jmp_op = SCF_OP_3AC_JLE; - break; + case SCF_OP_3AC_JA: + jmp_op = SCF_OP_3AC_JBE; + break; + case SCF_OP_3AC_JAE: + jmp_op = SCF_OP_3AC_JB; + break; - case SCF_OP_3AC_JA: - jmp_op = SCF_OP_3AC_JBE; - break; - case SCF_OP_3AC_JAE: - jmp_op = SCF_OP_3AC_JB; - break; + case SCF_OP_3AC_JB: + jmp_op = SCF_OP_3AC_JAE; + break; + case SCF_OP_3AC_JBE: + jmp_op = SCF_OP_3AC_JA; + break; - case SCF_OP_3AC_JB: - jmp_op = SCF_OP_3AC_JAE; - break; - case SCF_OP_3AC_JBE: - jmp_op = SCF_OP_3AC_JA; - break; + default: + scf_loge("NOT support jmp op %d\n", jmp_end->op->type); + return -1; + break; + }; + } - default: - jmp_op = -1; - break; - }; + scf_3ac_code_t* loop = NULL; + scf_3ac_code_t* start = NULL; + + if (jmp_end) { + // add loop when true + loop = scf_3ac_jmp_code(jmp_op, NULL, NULL); + scf_list_add_tail(d->_3ac_list_head, &loop->list); - // add loop when true - 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, + start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list); + } else { + loop = scf_3ac_jmp_code(SCF_OP_GOTO, 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); + start = scf_list_data(scf_list_next(start_prev), scf_3ac_code_t, list); + } dst = loop->dsts->data[0]; dst->code = start; diff --git a/examples/for2.c b/examples/for2.c new file mode 100644 index 0000000..636d89b --- /dev/null +++ b/examples/for2.c @@ -0,0 +1,12 @@ +int printf(const char* fmt, ...); + +int main() +{ + for (int i = 0; ; i++) { + printf("%d\n", i); + if (i >= 9) + break; + } + + return 0; +} diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 415069e..4cf5867 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -1502,26 +1502,28 @@ static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes assert(4 == nb_nodes); scf_handler_data_t* d = data; - int ret = 0; + scf_variable_t* r; + scf_node_t* cond; + int i; - if (nodes[0]) { - ret = _scf_op_semantic_node(ast, nodes[0], d); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - } + for (i = 0; i < nb_nodes; i++) { + if (!nodes[i]) + continue; - scf_node_t* cond = nodes[1]; - if (cond) { - ret = _scf_op_semantic_node(ast, cond, d); + int ret = _scf_op_semantic_node(ast, nodes[i], d); if (ret < 0) { scf_loge("\n"); return ret; } - 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 (1 == i) { + cond = nodes[i]; + + if (cond->nb_nodes <= 0) + continue; + + // the final expr is real cond expr + r = _scf_operand_get(cond->nodes[cond->nb_nodes - 1]); if (!r || !scf_variable_integer(r)) { scf_loge("\n"); @@ -1530,18 +1532,6 @@ static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes } } - int i; - for (i = 2; i < nb_nodes; i++) { - if (!nodes[i]) - continue; - - ret = _scf_op_semantic_node(ast, nodes[i], d); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - } - return 0; }