Skip to content

Commit 2bfa47e

Browse files
committed
Implement pattern matching
1 parent f39b029 commit 2bfa47e

35 files changed

+1762
-573
lines changed

Zend/tests/numeric_literal_separator_002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Invalid use: trailing underscore
55
100_;
66
?>
77
--EXPECTF--
8-
Parse error: syntax error, unexpected identifier "_" in %s on line %d
8+
Parse error: syntax error, unexpected token "_" in %s on line %d

Zend/tests/numeric_literal_separator_004.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Invalid use: underscore left of period
55
100_.0;
66
?>
77
--EXPECTF--
8-
Parse error: syntax error, unexpected identifier "_" in %s on line %d
8+
Parse error: syntax error, unexpected token "_" in %s on line %d
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
Array pattern
3+
--FILE--
4+
<?php
5+
6+
var_dump([] is []);
7+
var_dump(42 is []);
8+
var_dump('foo' is []);
9+
var_dump([42] is [42]);
10+
var_dump([42] is []);
11+
var_dump([42] is [43]);
12+
var_dump([42] is ['0' => 42]);
13+
var_dump([42, 43] is [42]);
14+
var_dump([42, 43] is [42, ...]);
15+
var_dump([42] is [$a]);
16+
var_dump($a);
17+
18+
?>
19+
--EXPECT--
20+
bool(true)
21+
bool(false)
22+
bool(false)
23+
bool(true)
24+
bool(false)
25+
bool(false)
26+
bool(true)
27+
bool(false)
28+
bool(true)
29+
bool(true)
30+
int(42)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Object pattern matching
3+
--FILE--
4+
<?php
5+
6+
$o = new stdClass();
7+
8+
try {
9+
var_dump($o is self {});
10+
} catch (Throwable $e) {
11+
echo $e->getMessage(), "\n";
12+
}
13+
14+
try {
15+
var_dump($o is parent {});
16+
} catch (Throwable $e) {
17+
echo $e->getMessage(), "\n";
18+
}
19+
20+
try {
21+
var_dump($o is static {});
22+
} catch (Throwable $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
26+
class C {
27+
public static function test($o) {
28+
try {
29+
var_dump($o is parent {});
30+
} catch (Throwable $e) {
31+
echo $e->getMessage(), "\n";
32+
}
33+
}
34+
}
35+
36+
C::test($o);
37+
38+
?>
39+
--EXPECT--
40+
Cannot access "self" when no class scope is active
41+
Cannot access "parent" when no class scope is active
42+
Cannot access "static" when no class scope is active
43+
Cannot access "parent" when current class scope has no parent
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
Binding pattern
3+
--FILE--
4+
<?php
5+
6+
class Box {
7+
public function __construct(
8+
public $value,
9+
) {}
10+
}
11+
12+
class NotBox {
13+
public function __construct(
14+
public $value,
15+
) {}
16+
}
17+
18+
var_dump(10 is $a);
19+
var_dump($a);
20+
21+
var_dump('Hello world' is $a);
22+
var_dump($a);
23+
24+
var_dump(new Box(42) is Box { value: $a });
25+
var_dump($a);
26+
27+
var_dump(new NotBox(43) is Box { value: $a });
28+
var_dump($a);
29+
30+
var_dump(43 is $a @ int);
31+
var_dump($a);
32+
33+
var_dump([] is $a @ string);
34+
var_dump($a);
35+
36+
?>
37+
--EXPECT--
38+
bool(true)
39+
int(10)
40+
bool(true)
41+
string(11) "Hello world"
42+
bool(true)
43+
int(42)
44+
bool(false)
45+
int(42)
46+
bool(true)
47+
int(43)
48+
bool(false)
49+
int(43)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Object pattern matching destructor
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function __destruct() {
8+
throw new Exception('Here');
9+
}
10+
}
11+
12+
$foo = new Foo();
13+
$bar = 'bar';
14+
15+
try {
16+
42 is $foo or $bar;
17+
} catch (Exception $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
21+
// FIXME: This will change once bindings are delayed
22+
var_dump($foo);
23+
var_dump($bar);
24+
25+
?>
26+
--EXPECT--
27+
Here
28+
int(42)
29+
string(3) "bar"
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
--TEST--
2+
Object pattern matching
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function __construct(
8+
public int $a,
9+
) {}
10+
11+
public static function isSelfFoo($value) {
12+
return $value is self {};
13+
}
14+
15+
public static function isStaticFoo($value) {
16+
return $value is static {};
17+
}
18+
}
19+
20+
class Bar extends Foo implements Baz {
21+
public static function isSelfBar($value) {
22+
return $value is self {};
23+
}
24+
25+
public static function isParentBar($value) {
26+
return $value is parent {};
27+
}
28+
}
29+
30+
interface Baz {}
31+
class Qux {}
32+
33+
$foo = new Foo(42);
34+
$bar = new Bar(43);
35+
$qux = new Qux();
36+
37+
var_dump($foo is Foo {});
38+
var_dump($foo is Bar {});
39+
var_dump($foo is Baz {});
40+
var_dump($foo is Qux {});
41+
var_dump($foo is Quux {});
42+
var_dump($bar is Foo {});
43+
var_dump($bar is Bar {});
44+
var_dump($bar is Baz {});
45+
var_dump($bar is Qux {});
46+
var_dump($bar is Quux {});
47+
var_dump(null is Foo {});
48+
var_dump(null is Bar {});
49+
var_dump(null is Baz {});
50+
var_dump(null is Qux {});
51+
var_dump(null is Quux {});
52+
53+
var_dump($foo is Foo { a: 42 });
54+
var_dump($foo is Foo { a: 42|43 });
55+
var_dump($foo is Foo { a: 'hello world' });
56+
var_dump($foo is Foo { b: 42 });
57+
var_dump($bar is Foo { a: 42 });
58+
var_dump($bar is Foo { a: 42|43 });
59+
var_dump($bar is Foo { a: 'hello world' });
60+
var_dump($bar is Foo { b: 42 });
61+
62+
var_dump(Foo::isSelfFoo($foo));
63+
var_dump(Foo::isSelfFoo($bar));
64+
var_dump(Foo::isSelfFoo($qux));
65+
var_dump(Foo::isStaticFoo($foo));
66+
var_dump(Foo::isStaticFoo($bar));
67+
var_dump(Foo::isStaticFoo($qux));
68+
var_dump(Bar::isSelfFoo($foo));
69+
var_dump(Bar::isSelfFoo($bar));
70+
var_dump(Bar::isSelfFoo($qux));
71+
var_dump(Bar::isStaticFoo($foo));
72+
var_dump(Bar::isStaticFoo($bar));
73+
var_dump(Bar::isStaticFoo($qux));
74+
var_dump(Bar::isSelfBar($foo));
75+
var_dump(Bar::isSelfBar($bar));
76+
var_dump(Bar::isSelfBar($qux));
77+
var_dump(Bar::isParentBar($foo));
78+
var_dump(Bar::isParentBar($bar));
79+
var_dump(Bar::isParentBar($qux));
80+
81+
?>
82+
--EXPECTF--
83+
bool(true)
84+
bool(false)
85+
bool(false)
86+
bool(false)
87+
bool(false)
88+
bool(true)
89+
bool(true)
90+
bool(true)
91+
bool(false)
92+
bool(false)
93+
bool(false)
94+
bool(false)
95+
bool(false)
96+
bool(false)
97+
bool(false)
98+
bool(true)
99+
bool(true)
100+
bool(false)
101+
102+
Warning: Undefined property: Foo::$b in %s on line %d
103+
bool(false)
104+
bool(false)
105+
bool(true)
106+
bool(false)
107+
108+
Warning: Undefined property: Bar::$b in %s on line %d
109+
bool(false)
110+
bool(true)
111+
bool(true)
112+
bool(false)
113+
bool(true)
114+
bool(true)
115+
bool(false)
116+
bool(true)
117+
bool(true)
118+
bool(false)
119+
bool(false)
120+
bool(true)
121+
bool(false)
122+
bool(false)
123+
bool(true)
124+
bool(false)
125+
bool(true)
126+
bool(true)
127+
bool(false)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Or pattern
3+
--FILE--
4+
<?php
5+
6+
var_dump(1 is (1|2|3));
7+
var_dump(2 is (1|2|3));
8+
var_dump(3 is (1|2|3));
9+
var_dump(4 is (1|2|3));
10+
var_dump(null is (1|2|3));
11+
var_dump([] is (1|2|3));
12+
var_dump('hello world' is (1|2|3));
13+
14+
?>
15+
--EXPECT--
16+
bool(true)
17+
bool(true)
18+
bool(true)
19+
bool(false)
20+
bool(false)
21+
bool(false)
22+
bool(false)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Or pattern
3+
--FILE--
4+
<?php
5+
6+
var_dump(0 is 0 ..< 10);
7+
var_dump(5 is 0 ..< 10);
8+
var_dump(10 is 0 ..< 10);
9+
var_dump(11 is 0 ..< 10);
10+
var_dump(0 is 0 ..= 10);
11+
var_dump(5 is 0 ..= 10);
12+
var_dump(10 is 0 ..= 10);
13+
var_dump(11 is 0 ..= 10);
14+
15+
var_dump('a' is 'a' ..< 'c');
16+
var_dump('b' is 'a' ..< 'c');
17+
var_dump('c' is 'a' ..< 'c');
18+
var_dump('d' is 'a' ..< 'c');
19+
var_dump('a' is 'a' ..= 'c');
20+
var_dump('b' is 'a' ..= 'c');
21+
var_dump('c' is 'a' ..= 'c');
22+
var_dump('d' is 'a' ..= 'c');
23+
24+
?>
25+
--EXPECT--
26+
bool(true)
27+
bool(true)
28+
bool(false)
29+
bool(false)
30+
bool(true)
31+
bool(true)
32+
bool(true)
33+
bool(false)
34+
bool(true)
35+
bool(true)
36+
bool(false)
37+
bool(false)
38+
bool(true)
39+
bool(true)
40+
bool(true)
41+
bool(false)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Scalar pattern matching
3+
--FILE--
4+
<?php
5+
6+
var_dump(1 is 1);
7+
var_dump(1.0 is 1);
8+
var_dump('1' is 1);
9+
var_dump(1 is 1.0);
10+
var_dump(1.0 is 1.0);
11+
var_dump('1' is 1.0);
12+
var_dump(1 is '1');
13+
var_dump(1.0 is '1');
14+
var_dump('1' is '1');
15+
16+
?>
17+
--EXPECT--
18+
bool(true)
19+
bool(false)
20+
bool(false)
21+
bool(false)
22+
bool(true)
23+
bool(false)
24+
bool(false)
25+
bool(false)
26+
bool(true)

0 commit comments

Comments
 (0)