Ticket #1065 (closed bug: wontfix)
PGE should emit inline PIR with Grammar namespace
Reported by: | Austin_Hastings | Owned by: | pmichaud |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | PGE | Version: | 1.6.0 |
Severity: | low | Keywords: | PGE,inline,PIR,actions |
Cc: | Language: | ||
Patch status: | Platform: |
Description
This code, or at least the first alternate path, is pretty common in PGE grammars. In my situation, the <ws> token is compiled and becomes part of the [ 'close' ; 'Grammar' ] namespace.
token ws { | <?{{ ## Remember end of last ws, in case rule is called 2x $P0 = get_global '$!ws' if null $P0 goto noshort $P1 = $P0.'to'() $P2 = match.'to'() if $P1 != $P2 goto noshort .return(1) noshort: set_global '$!ws', match .return(0) }}> | <!ww> <.WS_ALL>+ | <.WS_ALL>* }
When the grammar is compiled, it produces output like this.
R2267: # closure $S1 = ".sub anon :anon\n.param pmc match\n\t## Remember end of last ws, in case rule is called 2x\n\t\t$P0 = get_global '$!ws'\n\t\tif null $P0 goto noshort\n\t\t$P1 = $P0.'to'()\n\t\t$P2 = match.'to'()\n\t\tif $P1 != $P2 goto noshort\n\t\t.return(1)\n\tnoshort:\n\t\tset_global '$!ws', match\n\t\t.return(0)\n\t\n.end\n" $P0 = get_hll_global ['PGE';'Match'], '%!cache' $P1 = $P0[$S1] unless null $P1 goto R2267_1 $P1 = compreg "PIR" $P1 = $P1($S1) $P0[$S1] = $P1 R2267_1:
The problem is that the anonymous sub that is eval'ed at runtime receives no namespace. As a result, any calls or variable references must be made with an explicit namespace resolution -- get_*_global or set_*_global, and any created symbols wind up in the root namespace by default. This is wrong because it pollutes the root namespace, and because it puts the in-line code in a completely different context from all the rest of the code associated with the grammar.
Inline PIR should be emitted with either the same namespace as the Grammar, or with the same namespace as the Actions. Given that the actions are pluggable, and that grammars may be subclassed or re-used, the simplest answer is probably to use the Grammar namespace.