Skip to content

[RFC] Switch expression #5308

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 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 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
36 changes: 36 additions & 0 deletions Zend/tests/switch/001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
--TEST--
Basic switch expression functionality test
--FILE--
<?php

function wordify($x) {
return $x switch {
0 => 'Zero',
1 => 'One',
2 => 'Two',
3 => 'Three',
4 => 'Four',
5 => 'Five',
6 => 'Six',
7 => 'Seven',
8 => 'Eight',
9 => 'Nine',
};
}

for ($i = 0; $i <= 9; $i++) {
print wordify($i) . "\n";
}

?>
--EXPECT--
Zero
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
19 changes: 19 additions & 0 deletions Zend/tests/switch/002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
Switch expression omit trailing comma
--FILE--
<?php

function print_bool($bool) {
echo $bool switch {
true => "true\n",
false => "false\n"
};
}

print_bool(true);
print_bool(false);

?>
--EXPECT--
true
false
24 changes: 24 additions & 0 deletions Zend/tests/switch/003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Switch expression default case
--FILE--
<?php

function get_value($i) {
return $i switch {
1 => 1,
2 => 2,
default => 'default',
};
}

echo get_value(0) . "\n";
echo get_value(1) . "\n";
echo get_value(2) . "\n";
echo get_value(3) . "\n";

?>
--EXPECT--
default
1
2
default
31 changes: 31 additions & 0 deletions Zend/tests/switch/004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--TEST--
Switch expression with true as expression
--FILE--
<?php

function get_range($i) {
return true switch {
$i >= 50 => '50+',
$i >= 40 => '40-50',
$i >= 30 => '30-40',
$i >= 20 => '20-30',
$i >= 10 => '10-20',
default => '0-10',
};
}

echo get_range(22) . "\n";
echo get_range(0) . "\n";
echo get_range(59) . "\n";
echo get_range(13) . "\n";
echo get_range(39) . "\n";
echo get_range(40) . "\n";

?>
--EXPECT--
20-30
0-10
50+
10-20
30-40
40-50
12 changes: 12 additions & 0 deletions Zend/tests/switch/005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Switch expression discarding result
--FILE--
<?php

1 switch {
1 => print "Executed\n",
};

?>
--EXPECT--
Executed
13 changes: 13 additions & 0 deletions Zend/tests/switch/006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Switch expression with no cases
--FILE--
<?php

$x = true switch {};

?>
--EXPECTF--
Fatal error: Uncaught InvalidArgumentException in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
26 changes: 26 additions & 0 deletions Zend/tests/switch/007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
Switch expression exception on unhandled case
--FILE--
<?php

function get_value($i) {
return $i switch {
1 => 1,
2 => 2,
};
}

echo get_value(1) . "\n";
echo get_value(2) . "\n";
echo get_value(3) . "\n";

?>
--EXPECTF--
1
2

Fatal error: Uncaught InvalidArgumentException in %s
Stack trace:
#0 %s: get_value(3)
#1 {main}
thrown in %s on line %d
23 changes: 23 additions & 0 deletions Zend/tests/switch/008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Copy link
Member Author

Choose a reason for hiding this comment

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

This test is useless now.

Switch expression precedence
--FILE--
<?php

print !true switch {
false => "! has higher precedence\n"
};

$throwableInterface = Throwable::class;
print new RuntimeException() instanceof $throwableInterface switch {
true => "instanceof has higher precedence\n"
};

print 10 ** 2 switch {
100 => "** has higher precedence\n"
};

?>
--EXPECT--
! has higher precedence
instanceof has higher precedence
** has higher precedence
25 changes: 25 additions & 0 deletions Zend/tests/switch/009.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
Switch expression multiple conditions per case
--FILE--
<?php

function is_working_day($day) {
return $day switch {
1, 7 => false,
2, 3, 4, 5, 6 => true,
};
}

for ($i = 1; $i <= 7; $i++) {
var_dump(is_working_day($i));
}

?>
--EXPECT--
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
31 changes: 31 additions & 0 deletions Zend/tests/switch/010.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--TEST--
Switch statement multiple conditions per case
--FILE--
<?php

function is_working_day($day) {
switch ($day) {
case 1, 7:
return false;
case 2, 3, 4, 5, 6:
return true;
};

return null;
}

for ($i = 0; $i <= 8; $i++) {
var_dump(is_working_day($i));
}

?>
--EXPECT--
NULL
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
NULL
2 changes: 1 addition & 1 deletion Zend/zend_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
zend_ast_export_indent(str, indent);
if (ast->child[0]) {
smart_str_appends(str, "case ");
zend_ast_export_ex(str, ast->child[0], 0, indent);
zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
smart_str_appends(str, ":\n");
} else {
smart_str_appends(str, "default:\n");
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum _zend_ast_kind {
ZEND_AST_STMT_LIST,
ZEND_AST_IF,
ZEND_AST_SWITCH_LIST,
ZEND_AST_SWITCH_CASE_COND_LIST,
Copy link
Member Author

Choose a reason for hiding this comment

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

We could actually probably reuse the ZEND_AST_EXPR_LIST.

ZEND_AST_CATCH_LIST,
ZEND_AST_PARAM_LIST,
ZEND_AST_CLOSURE_USES,
Expand Down
Loading