I think I figured it out. It’s for when you want to explicitly yield from the generator/comprehension
r = r { loop { {; yield(x*2), x <- (2..6)} } };
r.nextN(7);
// -> [ 4, 6, 8, 10, 12, 4, 6 ]
It gets more interesting perhaps that–like in a routine–you can yield more than once “in a row” in that first expression in the generator.
r = r { loop { {; yield(x*2); yield(x**3), x <- (2..6)} } };
r.nextN(12);
// -> [ 4, 8.0, 6, 27.0, 8, 64.0, 10, 125.0, 12, 216.0, 4, 8.0 ]
This became obvious after looking at “action” part of parser code for generators/comprehensions; the yield is removed too (in addition to the r
preamble) for “action 2”, which is what {;
puts on the generator stack.
nextqual :
{
// innermost part
int action = popls(&generatorStack);
PyrParseNode* expr = (PyrParseNode*)popls(&generatorStack);
switch (action)
{
case 1 :
{
PyrSlot slot;
SetSymbol(&slot, getsym("yield"));
PyrSlotNode* selectornode = newPyrSlotNode(&slot);
$$ = (intptr_t)newPyrCallNode(selectornode, expr, 0, 0);
} break;
case 2 :
{
$$ = (intptr_t)expr;
} break;
}
}
| ',' qual
{ $$ = $2; }
;