]> granicus.if.org Git - php/commitdiff
Port do/while
authorNikita Popov <nikic@php.net>
Thu, 10 Jul 2014 12:46:22 +0000 (14:46 +0200)
committerNikita Popov <nikic@php.net>
Thu, 10 Jul 2014 12:46:22 +0000 (14:46 +0200)
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_language_parser.y

index 2137740a1d2645bacee1bec1755c8e2f2470e86c..99d81578759743321f02e111f60d23ff0cadb24d 100644 (file)
@@ -77,6 +77,7 @@ enum _zend_ast_kind {
        ZEND_AST_LABEL,
 
        ZEND_AST_WHILE,
+       ZEND_AST_DO_WHILE,
 };
 
 typedef unsigned short zend_ast_kind;
index efda0d69e3d0ad5fdddc4cc1c11dc06324780e5d..b08d1a94a7fc7af4b4bc1517f76836c6bf7455ef 100644 (file)
@@ -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;
index 782fc06565c710fe74f470b2b8121d5a055f08e8..a7c03439f76b3858a16393a1a98ebda879c17f52 100644 (file)
@@ -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