Skip to content

Commit

Permalink
Add support for list() in foreach (PHP 5.5)
Browse files Browse the repository at this point in the history
Example: foreach ($coords as list($x, $y)) { ... }

This change slightly breaks backwards compatability, as it changes the
node structure for the previously existing `list(...) = $foo` assignments.
Those no longer have a dedicated `AssignList` node; instead they are
parsed as a normal `Assign` node with a `List` as `var`. Similarly the
use in `foreach` will generate a `List` for `valueVar`.
  • Loading branch information
nikic committed Sep 7, 2012
1 parent 8d21811 commit f8f1e17
Show file tree
Hide file tree
Showing 7 changed files with 852 additions and 777 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Version 0.9.3-dev
-----------------

* [BC] [PHP 5.5] Add support for `list()` destructuring of `foreach` values.
Example: `foreach ($coords as list($x, $y)) { ... }`

This changes the node structure for the previously existing `list(...) = $foo` assignments. Those no longer have a
dedicated `AssignList` node; instead they are parsed as a normal `Assign` node with a `List` as `var`. Similarly the
use in `foreach` will generate a `List` for `valueVar`.

* Fix parsing of `$foo =& new Bar`. It is now properly parsed as `AssignRef` (instead of `Assign`).

Version 0.9.2 (07.07.2012)
Expand Down
22 changes: 15 additions & 7 deletions grammar/zend_language_parser.phpy
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,10 @@ statement:
| T_INLINE_HTML { $$ = Stmt_InlineHTML[$1]; }
| expr ';' { $$ = $1; }
| T_UNSET '(' variables_list ')' ';' { $$ = Stmt_Unset[$3]; }
| T_FOREACH '(' expr T_AS variable ')' foreach_statement
{ $$ = Stmt_Foreach[$3, $5, [keyVar: null, byRef: false, stmts: $7]]; }
| T_FOREACH '(' expr T_AS '&' variable ')' foreach_statement
{ $$ = Stmt_Foreach[$3, $6, [keyVar: null, byRef: true, stmts: $8]]; }
| T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW optional_ref variable ')' foreach_statement
{ $$ = Stmt_Foreach[$3, $8, [keyVar: $5, byRef: $7, stmts: $10]]; }
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
{ $$ = Stmt_Foreach[$3, $5[0], [keyVar: null, byRef: $5[1], stmts: $7]]; }
| T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement
{ $$ = Stmt_Foreach[$3, $7[0], [keyVar: $5, byRef: $7[1], stmts: $9]]; }
| T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt_Declare[$3, $5]; }
| ';' { $$ = array(); /* means: no statement */ }
| T_TRY '{' inner_statement_list '}' catches { $$ = Stmt_TryCatch[$3, $5]; }
Expand Down Expand Up @@ -342,6 +340,12 @@ new_else_single:
| T_ELSE ':' inner_statement_list { $$ = Stmt_Else[$3]; }
;

foreach_variable:
variable { $$ = array($1, false); }
| '&' variable { $$ = array($2, true); }
| list_expr { $$ = array($1, false); }
;

parameter_list:
non_empty_parameter_list { $$ = $1; }
| /* empty */ { $$ = array(); }
Expand Down Expand Up @@ -495,7 +499,7 @@ for_expr:

expr:
variable { $$ = $1; }
| T_LIST '(' assignment_list ')' '=' expr { $$ = Expr_AssignList[$3, $6]; }
| list_expr '=' expr { $$ = Expr_Assign[$1, $3]; }
| variable '=' expr { $$ = Expr_Assign[$1, $3]; }
| variable '=' '&' variable { $$ = Expr_AssignRef[$1, $4]; }
| variable '=' '&' new_expr { $$ = Expr_AssignRef[$1, $4]; }
Expand Down Expand Up @@ -581,6 +585,10 @@ new_expr:
T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; }
;

list_expr:
T_LIST '(' assignment_list ')' { $$ = Expr_List[$3]; }
;

lexical_vars:
/* empty */ { $$ = array(); }
| T_USE '(' lexical_var_list ')' { $$ = $3; }
Expand Down
25 changes: 0 additions & 25 deletions lib/PHPParser/Node/Expr/AssignList.php

This file was deleted.

22 changes: 22 additions & 0 deletions lib/PHPParser/Node/Expr/List.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/**
* @property array $vars List of variables to assign to
*/
class PHPParser_Node_Expr_List extends PHPParser_Node_Expr
{
/**
* Constructs a list() destructuring node.
*
* @param array $vars List of variables to assign to
* @param array $attributes Additional attributes
*/
public function __construct(array $vars, array $attributes = array()) {
parent::__construct(
array(
'vars' => $vars,
),
$attributes
);
}
}
Loading

0 comments on commit f8f1e17

Please sign in to comment.