Skip to content

Commit d21c925

Browse files
RFC for guard clauses, add continue and break support
1 parent 74638be commit d21c925

File tree

4 files changed

+110
-4
lines changed

4 files changed

+110
-4
lines changed

Zend/tests/guard_clauses/002.phpt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
continue if
3+
--FILE--
4+
<?php
5+
6+
$x = 0;
7+
8+
for ($i = 0; $i < 10; $i ++) {
9+
continue if ($i >= 5);
10+
11+
$x++;
12+
}
13+
14+
$y = 0;
15+
16+
for ($j = 0; $j < 10; $j++) {
17+
for ($k = 0; $k < 10; $k++) {
18+
continue if ($j >= 5): 2;
19+
20+
$y++;
21+
}
22+
}
23+
24+
var_dump($x);
25+
var_dump($i);
26+
var_dump($y);
27+
var_dump($j);
28+
var_dump($k);
29+
30+
31+
?>
32+
--EXPECT--
33+
int(5)
34+
int(10)
35+
int(50)
36+
int(10)
37+
int(0)

Zend/tests/guard_clauses/003.phpt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
break if
3+
--FILE--
4+
<?php
5+
6+
$x = 0;
7+
8+
for ($i = 0; $i < 10; $i ++) {
9+
break if ($i >= 5);
10+
11+
$x++;
12+
}
13+
14+
$y = 0;
15+
16+
for ($j = 0; $j < 10; $j++) {
17+
for ($k = 0; $k < 10; $k++) {
18+
break if ($j >= 5): 2;
19+
20+
$y++;
21+
}
22+
}
23+
24+
$output = 'original';
25+
26+
switch (1) {
27+
case 1:
28+
switch (2) {
29+
case 2:
30+
break if (true): 2;
31+
}
32+
33+
// never executed
34+
$output = 'changed';
35+
break;
36+
}
37+
38+
var_dump($x);
39+
var_dump($i);
40+
var_dump($y);
41+
var_dump($j);
42+
var_dump($k);
43+
var_dump($output);
44+
45+
?>
46+
--EXPECT--
47+
int(5)
48+
int(5)
49+
int(50)
50+
int(5)
51+
int(0)
52+
string(8) "original"

Zend/zend_language_parser.y

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
249249
%type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
250250
%type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list
251251
%type <ast> echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list
252-
%type <ast> implements_list case_list return_if_stmt return_if_optional_return if_stmt_without_else
252+
%type <ast> implements_list case_list
253+
%type <ast> break_if_stmt continue_if_stmt return_if_stmt guard_if_optional_return if_stmt_without_else
253254
%type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
254255
%type <ast> class_const_list class_const_decl class_name_list trait_adaptations method_body non_empty_for_exprs
255256
%type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
@@ -427,8 +428,10 @@ inner_statement:
427428

428429
statement:
429430
'{' inner_statement_list '}' { $$ = $2; }
430-
| return_if_stmt { $$ = $1; }
431431
| if_stmt { $$ = $1; }
432+
| continue_if_stmt { $$ = $1; }
433+
| break_if_stmt { $$ = $1; }
434+
| return_if_stmt { $$ = $1; }
432435
| alt_if_stmt { $$ = $1; }
433436
| T_WHILE '(' expr ')' while_statement
434437
{ $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); }
@@ -601,14 +604,28 @@ while_statement:
601604
| ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; }
602605
;
603606

607+
break_if_stmt:
608+
T_BREAK T_IF '(' expr ')' guard_if_optional_return
609+
{ $$ = zend_ast_create_list(2, ZEND_AST_IF,
610+
zend_ast_create(ZEND_AST_IF_ELEM, $4,
611+
zend_ast_create(ZEND_AST_BREAK, $6))); }
612+
;
613+
614+
continue_if_stmt:
615+
T_CONTINUE T_IF '(' expr ')' guard_if_optional_return
616+
{ $$ = zend_ast_create_list(2, ZEND_AST_IF,
617+
zend_ast_create(ZEND_AST_IF_ELEM, $4,
618+
zend_ast_create(ZEND_AST_CONTINUE, $6))); }
619+
;
620+
604621
return_if_stmt:
605-
T_RETURN T_IF '(' expr ')' return_if_optional_return
622+
T_RETURN T_IF '(' expr ')' guard_if_optional_return
606623
{ $$ = zend_ast_create_list(2, ZEND_AST_IF,
607624
zend_ast_create(ZEND_AST_IF_ELEM, $4,
608625
zend_ast_create(ZEND_AST_RETURN, $6))); }
609626
;
610627

611-
return_if_optional_return:
628+
guard_if_optional_return:
612629
':' optional_expr ';' { $$ = $2; }
613630
| ';' { $$ = NULL; }
614631
;

0 commit comments

Comments
 (0)