From: Nikita Popov Date: Thu, 10 Jul 2014 12:35:59 +0000 (+0200) Subject: Port while X-Git-Tag: POST_AST_MERGE^2~161 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c7656c06cca94132c69c874df720d789b75072ab;p=php Port while Note: From here on everything is broken --- diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index cb731a39da..2137740a1d 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -75,6 +75,8 @@ enum _zend_ast_kind { ZEND_AST_UNSET, ZEND_AST_RETURN, ZEND_AST_LABEL, + + ZEND_AST_WHILE, }; typedef unsigned short zend_ast_kind; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f4ac95e07f..efda0d69e3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7068,6 +7068,32 @@ void zend_compile_label(zend_ast *ast TSRMLS_DC) { } } +void zend_compile_while(zend_ast *ast TSRMLS_DC) { + zend_ast *cond_ast = ast->child[0]; + zend_ast *stmt_ast = ast->child[1]; + + znode cond_node; + zend_uint opnum_start, opnum_jmpz; + zend_op *opline; + + opnum_start = get_next_op_number(CG(active_op_array)); + zend_compile_expr(&cond_node, cond_ast TSRMLS_CC); + + opnum_jmpz = get_next_op_number(CG(active_op_array)); + emit_op(NULL, ZEND_JMPZ, &cond_node, NULL TSRMLS_CC); + do_begin_loop(TSRMLS_C); + + zend_compile_stmt(stmt_ast TSRMLS_CC); + + opline = emit_op(NULL, ZEND_JMP, NULL, NULL TSRMLS_CC); + opline->op1.opline_num = opnum_start; + + opline = &CG(active_op_array)->opcodes[opnum_jmpz]; + opline->op2.opline_num = get_next_op_number(CG(active_op_array)); + + do_end_loop(opnum_start, 0 TSRMLS_CC); +} + void zend_compile_stmt_list(zend_ast *ast TSRMLS_DC) { zend_uint i; for (i = 0; i < ast->children; ++i) { @@ -7853,6 +7879,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) { case ZEND_AST_LABEL: zend_compile_label(ast TSRMLS_CC); break; + case ZEND_AST_WHILE: + zend_compile_while(ast TSRMLS_CC); + break; default: { znode result; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 07039d2d6f..782fc06565 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -325,7 +325,9 @@ unticked_statement: '{' inner_statement_list '}' { AN($$); } | T_IF parenthesis_expr { AC($2); zend_do_if_cond(&$2, &$1 TSRMLS_CC); } statement { AS($4); zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); AN($$); } | 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 { $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_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_FOR '(' @@ -532,8 +534,8 @@ case_separator: while_statement: - statement { AS($1); } - | ':' inner_statement_list T_ENDWHILE ';' + statement { $$.u.ast = $1.u.ast; } + | ':' inner_statement_list T_ENDWHILE ';' { AN($$); } ;