diff --git a/Zend/tests/short_functions/short-func-match.phpt b/Zend/tests/short_functions/short-func-match.phpt new file mode 100644 index 0000000000000..23d97450820f0 --- /dev/null +++ b/Zend/tests/short_functions/short-func-match.phpt @@ -0,0 +1,23 @@ +--TEST-- +Short functions with match statements. +--FILE-- + match($a) { + 1 => 'One', + 2 => 'Two', + 3 => 'Three', + default => 'More', +}; + +print pick_one(1) . PHP_EOL; +print pick_one(2) . PHP_EOL; +print pick_one(3) . PHP_EOL; +print pick_one(4) . PHP_EOL; + +?> +--EXPECT-- +One +Two +Three +More diff --git a/Zend/tests/short_functions/short-func-no-statement.phpt b/Zend/tests/short_functions/short-func-no-statement.phpt new file mode 100644 index 0000000000000..d49639b068a7d --- /dev/null +++ b/Zend/tests/short_functions/short-func-no-statement.phpt @@ -0,0 +1,12 @@ +--TEST-- +Non-expression statements parse error in short functions. +--FILE-- + foreach ($a as $v) print $v; + +test([1, 2, 3]); + +?> +--EXPECTF-- +Parse error: syntax error, unexpected token "foreach" in %s on line %d diff --git a/Zend/tests/short_functions/short-func.phpt b/Zend/tests/short_functions/short-func.phpt new file mode 100644 index 0000000000000..fb8c8c0aed19f --- /dev/null +++ b/Zend/tests/short_functions/short-func.phpt @@ -0,0 +1,17 @@ +--TEST-- +Basic short functions return values. +--FILE-- + $a + 1; + +function test2(int $b): int + => $b + 1; + +print test(5) . PHP_EOL; +print test2(5) . PHP_EOL; + +?> +--EXPECT-- +6 +6 diff --git a/Zend/tests/short_functions/short-generator.phpt b/Zend/tests/short_functions/short-generator.phpt new file mode 100644 index 0000000000000..bddd5d8c247e0 --- /dev/null +++ b/Zend/tests/short_functions/short-generator.phpt @@ -0,0 +1,19 @@ +--TEST-- +Short functions that yield. +--FILE-- + yield from $it; + +$a = [1, 2, 3]; + +print_r(iterator_to_array(read($a))); + +?> +--EXPECT-- +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) diff --git a/Zend/tests/short_functions/short-method-no-statement.phpt b/Zend/tests/short_functions/short-method-no-statement.phpt new file mode 100644 index 0000000000000..d13c862eeb828 --- /dev/null +++ b/Zend/tests/short_functions/short-method-no-statement.phpt @@ -0,0 +1,19 @@ +--TEST-- +Short methods. +--FILE-- + foreach ($a as $v) print $v; +} + +$t = new Test(1); + +print $t->out([1, 2, 3]) . PHP_EOL; + +?> +--EXPECTF-- +Parse error: syntax error, unexpected token "foreach" in %s on line %d diff --git a/Zend/tests/short_functions/short-method.phpt b/Zend/tests/short_functions/short-method.phpt new file mode 100644 index 0000000000000..cbfda7ace7927 --- /dev/null +++ b/Zend/tests/short_functions/short-method.phpt @@ -0,0 +1,24 @@ +--TEST-- +Short methods. +--FILE-- + $a + $this->b; + + public function addUp2(int $a): int + => $a + $this->b; +} + +$t = new Test(1); + +print $t->addUp(5) . PHP_EOL; +print $t->addUp2(5) . PHP_EOL; + +?> +--EXPECT-- +6 +6 diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index fcbdcb622261b..d20b84bafe977 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -236,7 +236,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); /* Token used to force a parse error from the lexer */ %token T_ERROR -%type top_statement namespace_name name statement function_declaration_statement +%type top_statement namespace_name name statement +%type function_declaration_statement function_body %type class_declaration_statement trait_declaration_statement legacy_namespace_name %type interface_declaration_statement interface_extends_list %type group_use_declaration inline_use_declarations inline_use_declaration @@ -547,12 +548,16 @@ unset_variable: ; function_declaration_statement: - function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type - backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4, - zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; } + function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type + backup_fn_flags function_body backup_fn_flags + { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $11, $1, $4, + zend_ast_get_str($3), $6, NULL, $10, $8, NULL); CG(extra_fn_flags) = $9; } ; +function_body: + '{' inner_statement_list '}' { $$ = $2; } + | T_DOUBLE_ARROW expr ';' { $$ = zend_ast_create(ZEND_AST_RETURN, $2); } + is_reference: %empty { $$ = 0; } | '&' { $$ = ZEND_PARAM_REF; } @@ -947,7 +952,7 @@ absolute_trait_method_reference: method_body: ';' /* abstract method */ { $$ = NULL; } - | '{' inner_statement_list '}' { $$ = $2; } + | function_body { $$ = $1; } ; variable_modifiers: