Perl6-Pugs
view release on metacpan or search on metacpan
docs/03Evaluator.pod view on Meta::CPAN
reduceSyn "for" [list, body] = do
This takes the two expressions to the C<for> syntax thingy, the list part, and
the body. C<for (@list) { print "i'm the body" }>.
The body is actually a subroutine; we'll look at that in a bit. After that
line are some details which we don't care about right now. Let's pretend they
don't exist and jump down to
let arity = max 1 $ length (subParams sub)
That part determines how many elements to take out of C<list> for each
iteration of C<body>. After that comes a lexically scoped function
definition, C<runBody>. Let's analyze it.
runBody [] _ = retVal undef
This takes care the case where there are no more elements in C<list>.
Contrast it with:
runBody vs sub' = do
let (these, rest) = arity `splitAt` vs
genSymCC "&next" $ \symNext -> do
genSymPrim "&redo" (const $ runBody vs sub') $ \symRedo -> do
apply (updateSubPad sub' (symRedo . symNext)) Nothing $
map (Val . VRef . MkRef) these
runBody rest sub'
Which matches C<vs> that isn't an empty list (the first C<runBody> matched
that case). The C<splitAt> takes C<arity> elements out of C<vs>, that is the
number of parameters the body subroutine wants, and puts them in C<these>. The
rest go into C<rest>.
The lines after that set the C<&redo> and C<&next> variables so that they
contain functions which will control the flow of the current iteration of the
loop.
The line starting with C<apply> applies the subroutine currently in C<sub'>,
and gives it C<these> as its parameters on the line starting with C<map>.
Lastly, after the subroutine is applied, C<runBody> is run again on C<rest>.
genSymCC "&last" $ \symLast -> do
let munge sub | subParams sub == [defaultArrayParam] =
munge sub{ subParams = [defaultScalarParam] }
munge sub = updateSubPad sub symLast
Outside of C<runBody>'s definition, the C<&last> variable is also defined. It
controls the whole loop, not only a single step, so it doesn't need to be in
C<&runBody>.
When all the auxiliary functions have been defined, we can run the body with
the list passed into the for (munging into C<elms> omitted):
runBody elms $ munge sub
=head2 VCode application
Now that we've seen a nice example of how a subroutine (which might be
masquerading as a simple block) is used, lets see how C<VCode>, the value
representing closures (subroutines, blocks, coroutines, etc) is called.
Subroutine application can be very simple, in the case of a C<Prim>. At other
times it involves entering a lexical scope, due to block open. Sometimes
parameter binding is involved too.
But have no fear, we will soon see that like most parts of pugs, these
things are actually pretty simple.
=cut
( run in 0.651 second using v1.01-cache-2.11-cpan-e93a5daba3e )