This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix our sub with proto
authorFather Chrysostomos <sprout@cpan.org>
Wed, 4 Jul 2012 07:17:55 +0000 (00:17 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 16 Sep 2012 05:44:55 +0000 (22:44 -0700)
commit60ac52eb5d5157fbe18e603a2d72ef6249b62083
tree185b8e8ee62f747a5d0f04e843901ef62dbe34e0
parent4b473a5a056427bc93ffb46dbb873c9e6ec5287f
Fix our sub with proto

yylex must emit exactly one token each time it is called.  Some-
times yylex needs to parse several tokens at once.  That’s what
the various force functions are for.  But that is also what
PL_pending_ident is for.

The various force_next, force_word, force_ident, etc., functions keep
a stack of tokens (PL_nextval/PL_nexttype) that yylex will check imme-
diately when called.

PL_pending_ident is used to track a single identifier that yylex will
hand off to S_pending_ident to handle.

S_pending_ident is the only piece of code for resolving an identi-
fier that could be lexical but could also be a package variable.
force_ident assumes it is looking for a package variable.

force_* takes precedence over PL_pending_ident.

All this means that, if an identifier needs to be looked up in the pad
on the next yylex invocation, it has to use PL_pending_ident, and the
force_* functions cannot be used at the same time.

Not realising that, when I made ‘our sub foo’ store the sub in the
pad I also made ‘our sub foo ($)’ into a syntax error, because it
was being parsed as ‘our sub ($) foo’ (the prototype being ‘forced’);
i.e., the pending tokens were being pulled out of the ‘queue’ in the
wrong order.  (I put queue in quotes, because one queue and one unre-
lated buffer together don’t exactly count as ‘a queue’.)

Changing PL_pending_ident to have precedence over the force stack
breaks ext/XS-APItest/t/swaptwostmts.t, because the statement-parsing
interface does not localise PL_pending_ident.  It could be changed to
do that, but I don’t think it is the right solution.

Having two separate pending token mechanisms makes things need-
lessly fragile.

This commit eliminates the PL_pending_ident mechanism and
modifies S_pending_ident (renaming it in the process to
S_force_ident_maybe_lex) to work with the force mechanism.  I was
going to merge it with force_ident, but the two make incompatible
assumptions that just complicate the code if merged.  S_pending_ident
needs the sigil in the same string buffer, to pass to the pad inter-
face.  force_ident needs to be able to work without a sigil present.

So now we only have one queue for pending tokens and the order is more
predictable.
embed.fnc
parser.h
proto.h
sv.c
t/cmd/lexsub.t
toke.c