Skip to content
Merged
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
1 change: 1 addition & 0 deletions Zend/zend_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ enum _zend_ast_kind {
ZEND_AST_NEW,
ZEND_AST_INSTANCEOF,
ZEND_AST_YIELD,
ZEND_AST_COALESCE,

ZEND_AST_STATIC,
ZEND_AST_WHILE,
Expand Down
27 changes: 27 additions & 0 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -6917,6 +6917,30 @@ void zend_compile_conditional(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
}
/* }}} */

void zend_compile_coalesce(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
{
zend_ast *expr_ast = ast->child[0];
zend_ast *default_ast = ast->child[1];

znode expr_node, default_node;
zend_op *opline;
uint32_t opnum;

zend_compile_var(&expr_node, expr_ast, BP_VAR_IS TSRMLS_CC);

opnum = get_next_op_number(CG(active_op_array));
zend_emit_op(result, ZEND_COALESCE, &expr_node, NULL TSRMLS_CC);

zend_compile_expr(&default_node, default_ast TSRMLS_CC);

opline = zend_emit_op(NULL, ZEND_QM_ASSIGN, &default_node, NULL TSRMLS_CC);
SET_NODE(opline->result, result);

opline = &CG(active_op_array)->opcodes[opnum];
opline->op2.opline_num = get_next_op_number(CG(active_op_array));
}
/* }}} */

void zend_compile_print(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
{
zend_ast *expr_ast = ast->child[0];
Expand Down Expand Up @@ -7754,6 +7778,9 @@ void zend_compile_expr(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
case ZEND_AST_CONDITIONAL:
zend_compile_conditional(result, ast TSRMLS_CC);
return;
case ZEND_AST_COALESCE:
zend_compile_coalesce(result, ast TSRMLS_CC);
return;
case ZEND_AST_PRINT:
zend_compile_print(result, ast TSRMLS_CC);
return;
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%right T_YIELD
%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL
%left '?' ':'
%right T_COALESCE
%left T_BOOLEAN_OR
%left T_BOOLEAN_AND
%left '|'
Expand Down Expand Up @@ -221,6 +222,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%token T_NS_C "__NAMESPACE__ (T_NS_C)"
%token T_NS_SEPARATOR "\\ (T_NS_SEPARATOR)"
%token T_ELLIPSIS "... (T_ELLIPSIS)"
%token T_COALESCE "?? (T_COALESCE)"
%token T_POW "** (T_POW)"
%token T_POW_EQUAL "**= (T_POW_EQUAL)"

Expand Down Expand Up @@ -827,6 +829,8 @@ expr_without_variable:
{ $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); }
| expr '?' ':' expr
{ $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, NULL, $4); }
| expr T_COALESCE expr
{ $$ = zend_ast_create(ZEND_AST_COALESCE, $1, $3); }
| internal_functions_in_yacc { $$ = $1; }
| T_INT_CAST expr { $$ = zend_ast_create_cast(IS_LONG, $2); }
| T_DOUBLE_CAST expr { $$ = zend_ast_create_cast(IS_DOUBLE, $2); }
Expand Down
Loading