From: Nikita Popov Date: Thu, 10 Jul 2014 12:46:22 +0000 (+0200) Subject: Port do/while X-Git-Tag: POST_AST_MERGE^2~160 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1738ee7e5a1fed651ac6d7c7dd38b35336d05847;p=php Port do/while --- diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 2137740a1d..99d8157875 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -77,6 +77,7 @@ enum _zend_ast_kind { ZEND_AST_LABEL, ZEND_AST_WHILE, + ZEND_AST_DO_WHILE, }; typedef unsigned short zend_ast_kind; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index efda0d69e3..b08d1a94a7 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7094,6 +7094,28 @@ void zend_compile_while(zend_ast *ast TSRMLS_DC) { do_end_loop(opnum_start, 0 TSRMLS_CC); } +void zend_compile_do_while(zend_ast *ast TSRMLS_DC) { + zend_ast *stmt_ast = ast->child[0]; + zend_ast *cond_ast = ast->child[1]; + + znode cond_node; + zend_op *opline; + zend_uint opnum_start, opnum_cond; + + do_begin_loop(TSRMLS_C); + + opnum_start = get_next_op_number(CG(active_op_array)); + zend_compile_stmt(stmt_ast TSRMLS_CC); + + opnum_cond = get_next_op_number(CG(active_op_array)); + zend_compile_expr(&cond_node, cond_ast TSRMLS_CC); + + opline = emit_op(NULL, ZEND_JMPNZ, &cond_node, NULL TSRMLS_CC); + opline->op2.opline_num = opnum_start; + + do_end_loop(opnum_cond, 0 TSRMLS_CC); +} + void zend_compile_stmt_list(zend_ast *ast TSRMLS_DC) { zend_uint i; for (i = 0; i < ast->children; ++i) { @@ -7882,6 +7904,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) { case ZEND_AST_WHILE: zend_compile_while(ast TSRMLS_CC); break; + case ZEND_AST_DO_WHILE: + zend_compile_do_while(ast TSRMLS_CC); + break; default: { znode result; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 782fc06565..a7c03439f7 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -327,8 +327,8 @@ unticked_statement: | T_IF parenthesis_expr ':' { AC($2); zend_do_if_cond(&$2, &$1 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); AN($$); } | T_WHILE parenthesis_expr while_statement { $$.u.ast = zend_ast_create_binary(ZEND_AST_WHILE, $2.u.ast, $3.u.ast); } - /*| T_WHILE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr { AC($3); zend_do_while_cond(&$3, &$$ TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$4 TSRMLS_CC); AN($$); }*/ - | T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE { AS($3); $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr ';' { AC($6); zend_do_do_while_end(&$1, &$4, &$6 TSRMLS_CC); AN($$); } + | T_DO statement T_WHILE parenthesis_expr ';' + { $$.u.ast = zend_ast_create_binary(ZEND_AST_DO_WHILE, $2.u.ast, $4.u.ast); } | T_FOR '(' for_expr