php/e14genCorou.php
<?php
require_once('env.php');
outBegin('Generators and Coroutines');
function itRec($a, $p='') {
if (! is_array($a)) {
yield $p => $a;
} else {
$q = $p === '' ? '' : $p . ', ';
foreach($a as $k => $v) {
foreach( itRec($v, $q . $k) as $u => $v)
yield "($p + $k) $u" => $v;
}
}
}
function itStack($arg) {
$stack = [];
$a = $arg;
reset($a);
$p = '';
while (true) {
if (false === $c = current($a)) {
if (null === $a = array_pop($stack))
return;
$p = substr($p, 0, strrpos($p, ','));
} else {
$k = key($a);
next($a);
if (is_array($c)) {
array_push($stack, $a);
$p .= ', ' . $k;
$a = $c;
reset($a);
} else {
yield substr($p . ', ' . $k, 2) => $c;
}
}
}
}
function itOne($n) {
$cont = ["itOne arg=$n", "one", "zwei" => "two", 9 => ['nine', 'neun']];
$cx=0;
outLi("itOne", ++$cx, "begin");
foreach($cont as $k => $v) {
if (! is_string($k)) {
outLi("itOne$n", ++$cx, "foreach vor yield", $v);
$o = yield $v;
} else {
outLi("itOne$n", ++$cx, "foreach vor yield $k =>", $v);
$o = yield $k => $v;
}
outLi("itOne$n", ++$cx, "nach yield got", $o);
if ($n == 1 and $o != null)
foreach(itOne(2) as $r => $s) {
outLi("itOne$n", ++$cx, "subiterator got $r =>", $s, ", yield+");
yield "$r+" => (is_string($s) ? "$s+" : $s);
}
}
outLi("itOne$n", ++$cx, "end");
}
outH('itRec recursive???');
out('recursive use of generators does not work! they have to pass the yield back throu the whole chain of calls');
outTB();
outTRH('#', 'key', 'current');
$cc = 0;
foreach( itRec([0, 'eins', [20, [210, 'zweihundertelf', [2120, 2121], 'zweihundertdreizehn'], 22], 'drei'
, [40, [410]], 'fuenfSchluss']) as $k => $v)
outTRD($cc++, $k, $v);
outTBEnd();
outH('itStack: simulating recursion by a manual stack of course works');
outTB();
outTRH('#', 'key', 'current');
$cc = 0;foreach( itStack([0, 'eins', [20, [210, 'zweihundertelf', [2120, 2121], 'zweihundertdreizehn'], 22], 'drei'
, [40, [410]], 'fuenfSchluss']) as $k => $v)
outTRD($cc++, $k, $v);
outTBEnd();
outH('itOne');
outOL();
outLi("main calls itOne(1) =", print_r($it = itOne(1), true));
outLi("main it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
outLi("main it->next()", $it->next(), ", it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
outLi("main it->send([so send it])", $it->send(['so', 'send', 'it']),
", it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
for ($i=0; $i < 7; $i++)
outLi("main it->next()", $it->next(), ", it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
outEnd(__file__);
?>