- Notifications
You must be signed in to change notification settings - Fork7.9k
Add generators support#177
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
9b101ac
252f623
9b51a3b
fd2a109
e14cfaf
1cec3f1
ca59e54
40b7533
46fa26a
5e763d9
9ce9a7e
2c5ecb4
ececcbc
f627be5
1a99d1c
fafce58
5bb3a99
d49d397
cbfa96c
39d3d5e
247bb73
64a643a
9f52c5c
bcc7d97
4aab08b
b770b22
3600914
ad525c2
12e9283
72a91d0
bc08c2c
8790160
0033a52
ee89e22
1477be9
6117f4c
7b3bfa5
bf82f46
40760ec
f169b26
d939d2d
6233408
1d3f37d
04e781f
14766e1
ab75ed6
5a9bddb
85f077c
c9709bf
612c249
1f70a4c
8074863
de80e3c
94b2cca
1340893
99f93dd
268740d
f4ce364
ae71693
7195a5b
05f1048
9003cd1
1823b16
f45a0f3
6517ed0
68c1e1c
7cdf636
4d8edda
f53225a
bd70d15
d60e3c6
cc07038
bef7958
dbc7809
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading.Please reload this page.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--TEST-- | ||
Temporary array expressions can be iterated by reference | ||
--FILE-- | ||
<?php | ||
$a = 'a'; | ||
$b = 'b'; | ||
foreach ([&$a, &$b] as &$value) { | ||
$value .= '-foo'; | ||
} | ||
var_dump($a, $b); | ||
?> | ||
--EXPECT-- | ||
string(5) "a-foo" | ||
string(5) "b-foo" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--TEST-- | ||
Generator keys are auto-incrementing by default | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
yield 'foo'; | ||
yield 'bar'; | ||
yield 5 => 'rab'; | ||
yield 'oof'; | ||
} | ||
foreach (gen() as $k => $v) { | ||
echo $k, ' => ', $v, "\n"; | ||
} | ||
?> | ||
--EXPECT-- | ||
0 => foo | ||
1 => bar | ||
5 => rab | ||
6 => oof |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--TEST-- | ||
Printing the stack trace in a generator | ||
--FILE-- | ||
<?php | ||
function f1() { | ||
debug_print_backtrace(); | ||
} | ||
function f2($arg1, $arg2) { | ||
f1(); | ||
yield; // force generator | ||
} | ||
function f3($gen) { | ||
$gen->rewind(); // trigger run | ||
} | ||
$gen = f2('foo', 'bar'); | ||
f3($gen); | ||
?> | ||
--EXPECTF-- | ||
#0 f1() called at [%s:%d] | ||
#1 f2(foo, bar) | ||
#2 Generator->rewind() called at [%s:%d] | ||
#3 f3(Generator Object ()) called at [%s:%d] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
--TEST-- | ||
Generators can be cloned | ||
--FILE-- | ||
<?php | ||
function firstN($end) { | ||
for ($i = 0; $i < $end; ++$i) { | ||
yield $i; | ||
} | ||
} | ||
$g1 = firstN(5); | ||
var_dump($g1->current()); | ||
$g1->next(); | ||
$g2 = clone $g1; | ||
var_dump($g2->current()); | ||
$g2->next(); | ||
var_dump($g2->current()); | ||
var_dump($g1->current()); | ||
$g1->next(); | ||
var_dump($g1->current()); | ||
?> | ||
--EXPECT-- | ||
int(0) | ||
int(1) | ||
int(2) | ||
int(1) | ||
int(2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--TEST-- | ||
Cloning a generator with a foreach loop properly adds a ref for the loop var | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
foreach ([1, 2, 3] as $i) { | ||
yield $i; | ||
} | ||
} | ||
$g1 = gen(); | ||
var_dump($g1->current()); | ||
$g2 = clone $g1; | ||
var_dump($g2->current()); | ||
$g1->next(); | ||
$g2->next(); | ||
var_dump($g1->current()); | ||
var_dump($g2->current()); | ||
unset($g1); | ||
$g2->next(); | ||
var_dump($g2->current()); | ||
?> | ||
--EXPECT-- | ||
int(1) | ||
int(1) | ||
int(2) | ||
int(2) | ||
int(3) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--TEST-- | ||
A generator with an active stack can be cloned | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
var_dump(str_repeat("x", yield)); | ||
} | ||
$g1 = gen(); | ||
$g1->rewind(); | ||
$g2 = clone $g1; | ||
unset($g1); | ||
$g2->send(10); | ||
?> | ||
--EXPECT-- | ||
string(10) "xxxxxxxxxx" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--TEST-- | ||
A generator using a symbol table can be cloned | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
// force compiled variable for $foo | ||
$foo = 'foo'; | ||
// force symbol table | ||
extract(['foo' => 'bar']); | ||
// interrupt | ||
yield; | ||
var_dump($foo); | ||
} | ||
$g1 = gen(); | ||
$g1->rewind(); | ||
$g2 = clone $g1; | ||
unset($g1); | ||
$g2->next(); | ||
?> | ||
--EXPECT-- | ||
string(3) "bar" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--TEST-- | ||
Cloning a generator method (with $this) | ||
--FILE-- | ||
<?php | ||
class Test { | ||
protected $foo; | ||
public function gen() { | ||
$this->foo = 'bar'; | ||
yield; // interrupt | ||
var_dump($this->foo); | ||
} | ||
} | ||
$g1 = (new Test)->gen(); | ||
$g1->rewind(); // goto yield | ||
$g2 = clone $g1; | ||
unset($g1); | ||
$g2->next(); | ||
?> | ||
--EXPECT-- | ||
string(3) "bar" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--TEST-- | ||
It's possible to invoke a generator dynamically | ||
--FILE-- | ||
<?php | ||
function gen($foo, $bar) { | ||
yield $foo; | ||
yield $bar; | ||
} | ||
$gen = call_user_func('gen', 'bar', 'foo'); | ||
foreach ($gen as $value) { | ||
var_dump($value); | ||
} | ||
?> | ||
--EXPECT-- | ||
string(3) "bar" | ||
string(3) "foo" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--TEST-- | ||
Generators cannot return values (even before yield) | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
return $foo; | ||
yield; | ||
} | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Generators cannot return values using "return" in %s on line 4 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--TEST-- | ||
Generators cannot return values | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
yield; | ||
return $abc; | ||
} | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Generators cannot return values using "return" in %s on line 5 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--TEST-- | ||
The Generator class cannot be extended | ||
--FILE-- | ||
<?php | ||
class ExtendedGenerator extends Generator { } | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Class ExtendedGenerator may not inherit from final class (Generator) in %s on line %d |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--TEST-- | ||
It's not possible to directly instantiate the Generator class | ||
--FILE-- | ||
<?php | ||
new Generator; | ||
?> | ||
--EXPECTF-- | ||
Catchable fatal error: The "Generator" class is reserved for internal use and cannot be manually instantiated in %s on line %d |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--TEST-- | ||
Non-ref generators cannot be iterated by-ref | ||
--FILE-- | ||
<?php | ||
function gen() { yield; } | ||
$gen = gen(); | ||
foreach ($gen as &$value) { } | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Uncaught exception 'Exception' with message 'You can only iterate a generator by-reference if it declared that it yields by-reference' in %s:%d | ||
Stack trace: | ||
#0 %s(%d): unknown() | ||
#1 {main} | ||
thrown in %s on line %d | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
--TEST-- | ||
It is not possible to resume an already running generator | ||
--FILE-- | ||
<?php | ||
function gen() { | ||
$gen = yield; | ||
$gen->next(); | ||
} | ||
$gen = gen(); | ||
$gen->send($gen); | ||
$gen->next(); | ||
?> | ||
--EXPECTF-- | ||
Fatal error: Cannot resume an already running generator in %s on line %d |
Uh oh!
There was an error while loading.Please reload this page.