Skip to content

RFC for conditional break, continue, & return statements #5552

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Zend/tests/guard_clauses/001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
return if in function
--FILE--
<?php

function divide($dividend, $divisor = null) {
return if ($divisor === null); // return null void

return if ($divisor == 0): 0; // explicit return value

return $dividend / $divisor;
}

var_dump(divide(10));
var_dump(divide(10, 0));
var_dump(divide(10, 5));

?>
--EXPECT--
NULL
int(0)
int(2)
37 changes: 37 additions & 0 deletions Zend/tests/guard_clauses/002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--TEST--
continue if
--FILE--
<?php

$x = 0;

for ($i = 0; $i < 10; $i ++) {
continue if ($i >= 5);

$x++;
}

$y = 0;

for ($j = 0; $j < 10; $j++) {
for ($k = 0; $k < 10; $k++) {
continue if ($j >= 5): 2;

$y++;
}
}

var_dump($x);
var_dump($i);
var_dump($y);
var_dump($j);
var_dump($k);


?>
--EXPECT--
int(5)
int(10)
int(50)
int(10)
int(0)
52 changes: 52 additions & 0 deletions Zend/tests/guard_clauses/003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
--TEST--
break if
--FILE--
<?php

$x = 0;

for ($i = 0; $i < 10; $i ++) {
break if ($i >= 5);

$x++;
}

$y = 0;

for ($j = 0; $j < 10; $j++) {
for ($k = 0; $k < 10; $k++) {
break if ($j >= 5): 2;

$y++;
}
}

$output = 'original';

switch (1) {
case 1:
switch (2) {
case 2:
break if (true): 2;
}

// never executed
$output = 'changed';
break;
}

var_dump($x);
var_dump($i);
var_dump($y);
var_dump($j);
var_dump($k);
var_dump($output);

?>
--EXPECT--
int(5)
int(5)
int(50)
int(5)
int(0)
string(8) "original"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't forget the newline at the end here :-)

31 changes: 30 additions & 1 deletion Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
%type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list
%type <ast> echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list
%type <ast> implements_list case_list if_stmt_without_else
%type <ast> implements_list case_list
%type <ast> break_if_stmt continue_if_stmt return_if_stmt guard_if_optional_return if_stmt_without_else
%type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
%type <ast> class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs
%type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
Expand Down Expand Up @@ -428,6 +429,9 @@ inner_statement:
statement:
'{' inner_statement_list '}' { $$ = $2; }
| if_stmt { $$ = $1; }
| continue_if_stmt { $$ = $1; }
| break_if_stmt { $$ = $1; }
| return_if_stmt { $$ = $1; }
| alt_if_stmt { $$ = $1; }
| T_WHILE '(' expr ')' while_statement
{ $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); }
Expand Down Expand Up @@ -600,6 +604,31 @@ while_statement:
| ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; }
;

break_if_stmt:
T_BREAK T_IF '(' expr ')' guard_if_optional_return
{ $$ = zend_ast_create_list(2, ZEND_AST_IF,
zend_ast_create(ZEND_AST_IF_ELEM, $4,
zend_ast_create(ZEND_AST_BREAK, $6))); }
;

continue_if_stmt:
T_CONTINUE T_IF '(' expr ')' guard_if_optional_return
{ $$ = zend_ast_create_list(2, ZEND_AST_IF,
zend_ast_create(ZEND_AST_IF_ELEM, $4,
zend_ast_create(ZEND_AST_CONTINUE, $6))); }
;

return_if_stmt:
T_RETURN T_IF '(' expr ')' guard_if_optional_return
{ $$ = zend_ast_create_list(2, ZEND_AST_IF,
zend_ast_create(ZEND_AST_IF_ELEM, $4,
zend_ast_create(ZEND_AST_RETURN, $6))); }
;

guard_if_optional_return:
':' optional_expr ';' { $$ = $2; }
| ';' { $$ = NULL; }
;

if_stmt_without_else:
T_IF '(' expr ')' statement
Expand Down
Binary file added build/v4.3.0
Binary file not shown.