Skip to content

Commit ad6564d

Browse files
committed
Implement match blocks
1 parent 3337f22 commit ad6564d

20 files changed

+368
-24
lines changed

Zend/tests/block_expr/coalesce.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Coalesce block
3+
--FILE--
4+
<?php
5+
$x = null;
6+
$y = $x ?? {
7+
echo "Executed\n";
8+
42
9+
};
10+
var_dump($y);
11+
12+
$x = 42;
13+
$y = $x ?? {
14+
echo "Never executed\n";
15+
};
16+
var_dump($y);
17+
?>
18+
--EXPECT--
19+
Executed
20+
int(42)
21+
int(42)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Coalesce assignment block
3+
--FILE--
4+
<?php
5+
$x = null;
6+
$x ??= {
7+
echo "Executed\n";
8+
42
9+
};
10+
var_dump($x);
11+
12+
$x = 42;
13+
$x ??= {
14+
echo "Never executed\n";
15+
};
16+
var_dump($x);
17+
?>
18+
--EXPECT--
19+
Executed
20+
int(42)
21+
int(42)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Match expression block must not use return
3+
--FILE--
4+
<?php
5+
foo(match (1) {
6+
1 => { return; }
7+
});
8+
?>
9+
--EXPECTF--
10+
Fatal error: Match expression whose result is used must not contain return, break, continue or goto in %s on line %d

Zend/tests/match/block_basic.phpt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Basic match blocks
3+
--FILE--
4+
<?php
5+
function foo() {
6+
echo "foo()\n";
7+
}
8+
9+
function bar() {
10+
return 3;
11+
}
12+
13+
function test($value) {
14+
var_dump(match ($value) {
15+
1 => { 1 },
16+
2 => {
17+
$x = 2;
18+
$x
19+
},
20+
3 => {
21+
foo();
22+
bar()
23+
},
24+
});
25+
}
26+
27+
test(1);
28+
test(2);
29+
test(3);
30+
?>
31+
--EXPECT--
32+
int(1)
33+
int(2)
34+
foo()
35+
int(3)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Match expression block must not use break
3+
--FILE--
4+
<?php
5+
var_dump(match ($value) {
6+
1 => { break; },
7+
});
8+
?>
9+
--EXPECTF--
10+
Fatal error: Match expression whose result is used must not contain return, break, continue or goto in %s on line %d
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Match expression block may use break if block is not escaped
3+
--FILE--
4+
<?php
5+
var_dump(match (1) {
6+
1 => {
7+
foreach ([1, 2, 3] as $value) {
8+
echo $value, "\n";
9+
break;
10+
}
11+
42
12+
},
13+
});
14+
?>
15+
--EXPECT--
16+
1
17+
int(42)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Match expression block must not use goto
3+
--FILE--
4+
<?php
5+
var_dump(match (1) {
6+
1 => {
7+
goto after;
8+
},
9+
});
10+
after:
11+
?>
12+
--EXPECTF--
13+
Fatal error: Match expression whose result is used must not contain return, break, continue or goto in %s on line %d
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
May not goto into match expression block
3+
--FILE--
4+
<?php
5+
goto in;
6+
var_dump(match (1) {
7+
1 => {
8+
in:
9+
42
10+
},
11+
});
12+
?>
13+
--EXPECTF--
14+
Fatal error: 'goto' into loop or switch statement is disallowed in %s on line %d
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Match expression block must return a value
3+
--FILE--
4+
<?php
5+
function test() {
6+
var_dump(match (1) {
7+
1 => {
8+
echo "Not returning anything\n";
9+
},
10+
});
11+
}
12+
try {
13+
test();
14+
} catch (Error $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
?>
18+
--EXPECT--
19+
Not returning anything
20+
NULL
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Match expression block must not use return
3+
--FILE--
4+
<?php
5+
var_dump(match ($value) {
6+
1 => { return; },
7+
});
8+
?>
9+
--EXPECTF--
10+
Fatal error: Match expression whose result is used must not contain return, break, continue or goto in %s on line %d
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Throwing match expression block must clean up live-vars
3+
--FILE--
4+
<?php
5+
6+
function throw_($value) {
7+
var_dump([new \stdClass] + match ($value) {
8+
1 => { throw new Exception('Exception with live var'); },
9+
});
10+
}
11+
12+
try {
13+
throw_(1);
14+
} catch (Exception $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
18+
?>
19+
--EXPECT--
20+
Exception with live var
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Match statement block may break out of block
3+
--FILE--
4+
<?php
5+
match (1) {
6+
1 => {
7+
echo "Before break\n";
8+
break;
9+
echo "After break\n";
10+
},
11+
};
12+
echo "After match\n";
13+
?>
14+
--EXPECT--
15+
Before break
16+
After match
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Match statement block may continue out of block, with a warning
3+
--FILE--
4+
<?php
5+
match (1) {
6+
1 => {
7+
echo "Before continue\n";
8+
continue;
9+
echo "After continue\n";
10+
},
11+
};
12+
echo "After match\n";
13+
?>
14+
--EXPECTF--
15+
Warning: "continue" targeting switch is equivalent to "break" in %s on line %d
16+
Before continue
17+
After match
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
May escape match statement block with goto
3+
--FILE--
4+
<?php
5+
match (1) {
6+
1 => {
7+
echo "Before goto\n";
8+
goto after;
9+
echo "After goto\n";
10+
},
11+
};
12+
after:
13+
echo "After match\n";
14+
?>
15+
--EXPECT--
16+
Before goto
17+
After match
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
May not goto into match statement block
3+
--FILE--
4+
<?php
5+
goto in;
6+
match (1) {
7+
1 => {
8+
in:
9+
echo "Inside match block\n";
10+
},
11+
};
12+
?>
13+
--EXPECTF--
14+
Fatal error: 'goto' into loop or switch statement is disallowed in %s on line %d
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Match statement block must not return a value
3+
--FILE--
4+
<?php
5+
match (1) {
6+
1 => { new stdClass },
7+
};
8+
?>
9+
===DONE===
10+
--EXPECT--
11+
===DONE===

Zend/zend_ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ enum _zend_ast_kind {
150150
ZEND_AST_ATTRIBUTE,
151151
ZEND_AST_MATCH,
152152
ZEND_AST_MATCH_ARM,
153+
ZEND_AST_BLOCK_EXPR,
153154
ZEND_AST_NAMED_ARG,
154155
ZEND_AST_PARENT_PROPERTY_HOOK_CALL,
155156

0 commit comments

Comments
 (0)