This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Get B::Deparse to load on perls back to 5.8.1
[perl5.git] / dist / B-Deparse / Deparse.pm
1 # B::Deparse.pm
2 # Copyright (c) 1998-2000, 2002, 2003, 2004, 2005, 2006 Stephen McCamant.
3 # All rights reserved.
4 # This module is free software; you can redistribute and/or modify
5 # it under the same terms as Perl itself.
6
7 # This is based on the module of the same name by Malcolm Beattie,
8 # but essentially none of his code remains.
9
10 package B::Deparse;
11 use Carp;
12 use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
13          OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
14          OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL OPf_MOD
15          OPpLVAL_INTRO OPpOUR_INTRO OPpENTERSUB_AMPER OPpSLICE OPpCONST_BARE
16          OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY
17          OPpCONST_ARYBASE OPpEXISTS_SUB OPpSORT_NUMERIC OPpSORT_INTEGER
18          OPpSORT_REVERSE
19          SVf_IOK SVf_NOK SVf_ROK SVf_POK SVpad_OUR SVf_FAKE SVs_RMG SVs_SMG
20          CVf_METHOD CVf_LVALUE
21          PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE
22          PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED),
23          ($] < 5.008004 ? () : 'OPpSORT_INPLACE'),
24          ($] < 5.008006 ? () : qw(OPpSORT_DESCEND OPpITER_REVERSED)),
25          ($] < 5.008009 ? () : qw(OPpCONST_NOVER OPpPAD_STATE)),
26          ($] < 5.009 ? 'PMf_SKIPWHITE' : qw(RXf_SKIPWHITE)),
27          ($] < 5.011 ? 'CVf_LOCKED' : 'OPpREVERSE_INPLACE'),
28          ($] < 5.013 ? () : 'PMf_NONDESTRUCT');
29 $VERSION = 1.01;
30 use strict;
31 use vars qw/$AUTOLOAD/;
32 use warnings ();
33
34 BEGIN {
35     # Easiest way to keep this code portable between version looks to
36     # be to fake up a dummy constant that will never actually be true.
37     foreach (qw(OPpSORT_INPLACE OPpSORT_DESCEND OPpITER_REVERSED OPpCONST_NOVER
38                 OPpPAD_STATE RXf_SKIPWHITE CVf_LOCKED OPpREVERSE_INPLACE
39                 PMf_NONDESTRUCT)) {
40         no strict 'refs';
41         *{$_} = sub () {0} unless *{$_}{CODE};
42     }
43 }
44
45 # Changes between 0.50 and 0.51:
46 # - fixed nulled leave with live enter in sort { }
47 # - fixed reference constants (\"str")
48 # - handle empty programs gracefully
49 # - handle infinte loops (for (;;) {}, while (1) {})
50 # - differentiate between `for my $x ...' and `my $x; for $x ...'
51 # - various minor cleanups
52 # - moved globals into an object
53 # - added `-u', like B::C
54 # - package declarations using cop_stash
55 # - subs, formats and code sorted by cop_seq
56 # Changes between 0.51 and 0.52:
57 # - added pp_threadsv (special variables under USE_5005THREADS)
58 # - added documentation
59 # Changes between 0.52 and 0.53:
60 # - many changes adding precedence contexts and associativity
61 # - added `-p' and `-s' output style options
62 # - various other minor fixes
63 # Changes between 0.53 and 0.54:
64 # - added support for new `for (1..100)' optimization,
65 #   thanks to Gisle Aas
66 # Changes between 0.54 and 0.55:
67 # - added support for new qr// construct
68 # - added support for new pp_regcreset OP
69 # Changes between 0.55 and 0.56:
70 # - tested on base/*.t, cmd/*.t, comp/*.t, io/*.t
71 # - fixed $# on non-lexicals broken in last big rewrite
72 # - added temporary fix for change in opcode of OP_STRINGIFY
73 # - fixed problem in 0.54's for() patch in `for (@ary)'
74 # - fixed precedence in conditional of ?:
75 # - tweaked list paren elimination in `my($x) = @_'
76 # - made continue-block detection trickier wrt. null ops
77 # - fixed various prototype problems in pp_entersub
78 # - added support for sub prototypes that never get GVs
79 # - added unquoting for special filehandle first arg in truncate
80 # - print doubled rv2gv (a bug) as `*{*GV}' instead of illegal `**GV'
81 # - added semicolons at the ends of blocks
82 # - added -l `#line' declaration option -- fixes cmd/subval.t 27,28
83 # Changes between 0.56 and 0.561:
84 # - fixed multiply-declared my var in pp_truncate (thanks to Sarathy)
85 # - used new B.pm symbolic constants (done by Nick Ing-Simmons)
86 # Changes between 0.561 and 0.57:
87 # - stylistic changes to symbolic constant stuff
88 # - handled scope in s///e replacement code
89 # - added unquote option for expanding "" into concats, etc.
90 # - split method and proto parts of pp_entersub into separate functions
91 # - various minor cleanups
92 # Changes after 0.57:
93 # - added parens in \&foo (patch by Albert Dvornik)
94 # Changes between 0.57 and 0.58:
95 # - fixed `0' statements that weren't being printed
96 # - added methods for use from other programs
97 #   (based on patches from James Duncan and Hugo van der Sanden)
98 # - added -si and -sT to control indenting (also based on a patch from Hugo)
99 # - added -sv to print something else instead of '???'
100 # - preliminary version of utf8 tr/// handling
101 # Changes after 0.58:
102 # - uses of $op->ppaddr changed to new $op->name (done by Sarathy)
103 # - added support for Hugo's new OP_SETSTATE (like nextstate)
104 # Changes between 0.58 and 0.59
105 # - added support for Chip's OP_METHOD_NAMED
106 # - added support for Ilya's OPpTARGET_MY optimization
107 # - elided arrows before `()' subscripts when possible
108 # Changes between 0.59 and 0.60
109 # - support for method attribues was added
110 # - some warnings fixed
111 # - separate recognition of constant subs
112 # - rewrote continue block handling, now recoginizing for loops
113 # - added more control of expanding control structures
114 # Changes between 0.60 and 0.61 (mostly by Robin Houston)
115 # - many bug-fixes
116 # - support for pragmas and 'use'
117 # - support for the little-used $[ variable
118 # - support for __DATA__ sections
119 # - UTF8 support
120 # - BEGIN, CHECK, INIT and END blocks
121 # - scoping of subroutine declarations fixed
122 # - compile-time output from the input program can be suppressed, so that the
123 #   output is just the deparsed code. (a change to O.pm in fact)
124 # - our() declarations
125 # - *all* the known bugs are now listed in the BUGS section
126 # - comprehensive test mechanism (TEST -deparse)
127 # Changes between 0.62 and 0.63 (mostly by Rafael Garcia-Suarez)
128 # - bug-fixes
129 # - new switch -P
130 # - support for command-line switches (-l, -0, etc.)
131 # Changes between 0.63 and 0.64
132 # - support for //, CHECK blocks, and assertions
133 # - improved handling of foreach loops and lexicals
134 # - option to use Data::Dumper for constants
135 # - more bug fixes
136 # - discovered lots more bugs not yet fixed
137 #
138 # ...
139 #
140 # Changes between 0.72 and 0.73
141 # - support new switch constructs
142
143 # Todo:
144 #  (See also BUGS section at the end of this file)
145 #
146 # - finish tr/// changes
147 # - add option for even more parens (generalize \&foo change)
148 # - left/right context
149 # - copy comments (look at real text with $^P?)
150 # - avoid semis in one-statement blocks
151 # - associativity of &&=, ||=, ?:
152 # - ',' => '=>' (auto-unquote?)
153 # - break long lines ("\r" as discretionary break?)
154 # - configurable syntax highlighting: ANSI color, HTML, TeX, etc.
155 # - more style options: brace style, hex vs. octal, quotes, ...
156 # - print big ints as hex/octal instead of decimal (heuristic?)
157 # - handle `my $x if 0'?
158 # - version using op_next instead of op_first/sibling?
159 # - avoid string copies (pass arrays, one big join?)
160 # - here-docs?
161
162 # Current test.deparse failures
163 # comp/hints 6 - location of BEGIN blocks wrt. block openings
164 # run/switchI 1 - missing -I switches entirely
165 #    perl -Ifoo -e 'print @INC'
166 # op/caller 2 - warning mask propagates backwards before warnings::register
167 #    'use warnings; BEGIN {${^WARNING_BITS} eq "U"x12;} use warnings::register'
168 # op/getpid 2 - can't assign to shared my() declaration (threads only)
169 #    'my $x : shared = 5'
170 # op/override 7 - parens on overriden require change v-string interpretation
171 #    'BEGIN{*CORE::GLOBAL::require=sub {}} require v5.6'
172 #    c.f. 'BEGIN { *f = sub {0} }; f 2'
173 # op/pat 774 - losing Unicode-ness of Latin1-only strings
174 #    'use charnames ":short"; $x="\N{latin:a with acute}"'
175 # op/recurse 12 - missing parens on recursive call makes it look like method
176 #    'sub f { f($x) }'
177 # op/subst 90 - inconsistent handling of utf8 under "use utf8"
178 # op/taint 29 - "use re 'taint'" deparsed in the wrong place wrt. block open
179 # op/tiehandle compile - "use strict" deparsed in the wrong place
180 # uni/tr_ several
181 # ext/B/t/xref 11 - line numbers when we add newlines to one-line subs
182 # ext/Data/Dumper/t/dumper compile
183 # ext/DB_file/several
184 # ext/Encode/several
185 # ext/Ernno/Errno warnings
186 # ext/IO/lib/IO/t/io_sel 23
187 # ext/PerlIO/t/encoding compile
188 # ext/POSIX/t/posix 6
189 # ext/Socket/Socket 8
190 # ext/Storable/t/croak compile
191 # lib/Attribute/Handlers/t/multi compile
192 # lib/bignum/ several
193 # lib/charnames 35
194 # lib/constant 32
195 # lib/English 40
196 # lib/ExtUtils/t/bytes 4
197 # lib/File/DosGlob compile
198 # lib/Filter/Simple/t/data 1
199 # lib/Math/BigInt/t/constant 1
200 # lib/Net/t/config Deparse-warning
201 # lib/overload compile
202 # lib/Switch/ several
203 # lib/Symbol 4
204 # lib/Test/Simple several
205 # lib/Term/Complete
206 # lib/Tie/File/t/29_downcopy 5
207 # lib/vars 22
208
209 # Object fields (were globals):
210 #
211 # avoid_local:
212 # (local($a), local($b)) and local($a, $b) have the same internal
213 # representation but the short form looks better. We notice we can
214 # use a large-scale local when checking the list, but need to prevent
215 # individual locals too. This hash holds the addresses of OPs that
216 # have already had their local-ness accounted for. The same thing
217 # is done with my().
218 #
219 # curcv:
220 # CV for current sub (or main program) being deparsed
221 #
222 # curcvlex:
223 # Cached hash of lexical variables for curcv: keys are names,
224 # each value is an array of pairs, indicating the cop_seq of scopes
225 # in which a var of that name is valid.
226 #
227 # curcop:
228 # COP for statement being deparsed
229 #
230 # curstash:
231 # name of the current package for deparsed code
232 #
233 # subs_todo:
234 # array of [cop_seq, CV, is_format?] for subs and formats we still
235 # want to deparse
236 #
237 # protos_todo:
238 # as above, but [name, prototype] for subs that never got a GV
239 #
240 # subs_done, forms_done:
241 # keys are addresses of GVs for subs and formats we've already
242 # deparsed (or at least put into subs_todo)
243 #
244 # subs_declared
245 # keys are names of subs for which we've printed declarations.
246 # That means we can omit parentheses from the arguments.
247 #
248 # subs_deparsed
249 # Keeps track of fully qualified names of all deparsed subs.
250 #
251 # parens: -p
252 # linenums: -l
253 # unquote: -q
254 # cuddle: ` ' or `\n', depending on -sC
255 # indent_size: -si
256 # use_tabs: -sT
257 # ex_const: -sv
258
259 # A little explanation of how precedence contexts and associativity
260 # work:
261 #
262 # deparse() calls each per-op subroutine with an argument $cx (short
263 # for context, but not the same as the cx* in the perl core), which is
264 # a number describing the op's parents in terms of precedence, whether
265 # they're inside an expression or at statement level, etc.  (see
266 # chart below). When ops with children call deparse on them, they pass
267 # along their precedence. Fractional values are used to implement
268 # associativity (`($x + $y) + $z' => `$x + $y + $y') and related
269 # parentheses hacks. The major disadvantage of this scheme is that
270 # it doesn't know about right sides and left sides, so say if you
271 # assign a listop to a variable, it can't tell it's allowed to leave
272 # the parens off the listop.
273
274 # Precedences:
275 # 26             [TODO] inside interpolation context ("")
276 # 25 left        terms and list operators (leftward)
277 # 24 left        ->
278 # 23 nonassoc    ++ --
279 # 22 right       **
280 # 21 right       ! ~ \ and unary + and -
281 # 20 left        =~ !~
282 # 19 left        * / % x
283 # 18 left        + - .
284 # 17 left        << >>
285 # 16 nonassoc    named unary operators
286 # 15 nonassoc    < > <= >= lt gt le ge
287 # 14 nonassoc    == != <=> eq ne cmp
288 # 13 left        &
289 # 12 left        | ^
290 # 11 left        &&
291 # 10 left        ||
292 #  9 nonassoc    ..  ...
293 #  8 right       ?:
294 #  7 right       = += -= *= etc.
295 #  6 left        , =>
296 #  5 nonassoc    list operators (rightward)
297 #  4 right       not
298 #  3 left        and
299 #  2 left        or xor
300 #  1             statement modifiers
301 #  0.5           statements, but still print scopes as do { ... }
302 #  0             statement level
303
304 # Nonprinting characters with special meaning:
305 # \cS - steal parens (see maybe_parens_unop)
306 # \n - newline and indent
307 # \t - increase indent
308 # \b - decrease indent (`outdent')
309 # \f - flush left (no indent)
310 # \cK - kill following semicolon, if any
311
312 sub null {
313     my $op = shift;
314     return class($op) eq "NULL";
315 }
316
317 sub todo {
318     my $self = shift;
319     my($cv, $is_form) = @_;
320     return unless ($cv->FILE eq $0 || exists $self->{files}{$cv->FILE});
321     my $seq;
322     if ($cv->OUTSIDE_SEQ) {
323         $seq = $cv->OUTSIDE_SEQ;
324     } elsif (!null($cv->START) and is_state($cv->START)) {
325         $seq = $cv->START->cop_seq;
326     } else {
327         $seq = 0;
328     }
329     push @{$self->{'subs_todo'}}, [$seq, $cv, $is_form];
330     unless ($is_form || class($cv->STASH) eq 'SPECIAL') {
331         $self->{'subs_deparsed'}{$cv->STASH->NAME."::".$cv->GV->NAME} = 1;
332     }
333 }
334
335 sub next_todo {
336     my $self = shift;
337     my $ent = shift @{$self->{'subs_todo'}};
338     my $cv = $ent->[1];
339     my $gv = $cv->GV;
340     my $name = $self->gv_name($gv);
341     if ($ent->[2]) {
342         return "format $name =\n"
343             . $self->deparse_format($ent->[1]). "\n";
344     } else {
345         $self->{'subs_declared'}{$name} = 1;
346         if ($name eq "BEGIN") {
347             my $use_dec = $self->begin_is_use($cv);
348             if (defined ($use_dec) and $self->{'expand'} < 5) {
349                 return () if 0 == length($use_dec);
350                 return $use_dec;
351             }
352         }
353         my $l = '';
354         if ($self->{'linenums'}) {
355             my $line = $gv->LINE;
356             my $file = $gv->FILE;
357             $l = "\n\f#line $line \"$file\"\n";
358         }
359         my $p = '';
360         if (class($cv->STASH) ne "SPECIAL") {
361             my $stash = $cv->STASH->NAME;
362             if ($stash ne $self->{'curstash'}) {
363                 $p = "package $stash;\n";
364                 $name = "$self->{'curstash'}::$name" unless $name =~ /::/;
365                 $self->{'curstash'} = $stash;
366             }
367             $name =~ s/^\Q$stash\E::(?!\z|.*::)//;
368         }
369         return "${p}${l}sub $name " . $self->deparse_sub($cv);
370     }
371 }
372
373 # Return a "use" declaration for this BEGIN block, if appropriate
374 sub begin_is_use {
375     my ($self, $cv) = @_;
376     my $root = $cv->ROOT;
377     local @$self{qw'curcv curcvlex'} = ($cv);
378 #require B::Debug;
379 #B::walkoptree($cv->ROOT, "debug");
380     my $lineseq = $root->first;
381     return if $lineseq->name ne "lineseq";
382
383     my $req_op = $lineseq->first->sibling;
384     return if $req_op->name ne "require";
385
386     my $module;
387     if ($req_op->first->private & OPpCONST_BARE) {
388         # Actually it should always be a bareword
389         $module = $self->const_sv($req_op->first)->PV;
390         $module =~ s[/][::]g;
391         $module =~ s/.pm$//;
392     }
393     else {
394         $module = $self->const($self->const_sv($req_op->first), 6);
395     }
396
397     my $version;
398     my $version_op = $req_op->sibling;
399     return if class($version_op) eq "NULL";
400     if ($version_op->name eq "lineseq") {
401         # We have a version parameter; skip nextstate & pushmark
402         my $constop = $version_op->first->next->next;
403
404         return unless $self->const_sv($constop)->PV eq $module;
405         $constop = $constop->sibling;
406         $version = $self->const_sv($constop);
407         if (class($version) eq "IV") {
408             $version = $version->int_value;
409         } elsif (class($version) eq "NV") {
410             $version = $version->NV;
411         } elsif (class($version) ne "PVMG") {
412             # Includes PVIV and PVNV
413             $version = $version->PV;
414         } else {
415             # version specified as a v-string
416             $version = 'v'.join '.', map ord, split //, $version->PV;
417         }
418         $constop = $constop->sibling;
419         return if $constop->name ne "method_named";
420         return if $self->const_sv($constop)->PV ne "VERSION";
421     }
422
423     $lineseq = $version_op->sibling;
424     return if $lineseq->name ne "lineseq";
425     my $entersub = $lineseq->first->sibling;
426     if ($entersub->name eq "stub") {
427         return "use $module $version ();\n" if defined $version;
428         return "use $module ();\n";
429     }
430     return if $entersub->name ne "entersub";
431
432     # See if there are import arguments
433     my $args = '';
434
435     my $svop = $entersub->first->sibling; # Skip over pushmark
436     return unless $self->const_sv($svop)->PV eq $module;
437
438     # Pull out the arguments
439     for ($svop=$svop->sibling; $svop->name ne "method_named";
440                 $svop = $svop->sibling) {
441         $args .= ", " if length($args);
442         $args .= $self->deparse($svop, 6);
443     }
444
445     my $use = 'use';
446     my $method_named = $svop;
447     return if $method_named->name ne "method_named";
448     my $method_name = $self->const_sv($method_named)->PV;
449
450     if ($method_name eq "unimport") {
451         $use = 'no';
452     }
453
454     # Certain pragmas are dealt with using hint bits,
455     # so we ignore them here
456     if ($module eq 'strict' || $module eq 'integer'
457         || $module eq 'bytes' || $module eq 'warnings'
458         || $module eq 'feature') {
459         return "";
460     }
461
462     if (defined $version && length $args) {
463         return "$use $module $version ($args);\n";
464     } elsif (defined $version) {
465         return "$use $module $version;\n";
466     } elsif (length $args) {
467         return "$use $module ($args);\n";
468     } else {
469         return "$use $module;\n";
470     }
471 }
472
473 sub stash_subs {
474     my ($self, $pack) = @_;
475     my (@ret, $stash);
476     if (!defined $pack) {
477         $pack = '';
478         $stash = \%::;
479     }
480     else {
481         $pack =~ s/(::)?$/::/;
482         no strict 'refs';
483         $stash = \%$pack;
484     }
485     my %stash = svref_2object($stash)->ARRAY;
486     while (my ($key, $val) = each %stash) {
487         my $class = class($val);
488         if ($class eq "PV") {
489             # Just a prototype. As an ugly but fairly effective way
490             # to find out if it belongs here is to see if the AUTOLOAD
491             # (if any) for the stash was defined in one of our files.
492             my $A = $stash{"AUTOLOAD"};
493             if (defined ($A) && class($A) eq "GV" && defined($A->CV)
494                 && class($A->CV) eq "CV") {
495                 my $AF = $A->FILE;
496                 next unless $AF eq $0 || exists $self->{'files'}{$AF};
497             }
498             push @{$self->{'protos_todo'}}, [$pack . $key, $val->PV];
499         } elsif ($class eq "IV" && !($val->FLAGS & SVf_ROK)) {
500             # Just a name. As above.
501             # But skip proxy constant subroutines, as some form of perl-space
502             # visible code must have created them, be it a use statement, or
503             # some direct symbol-table manipulation code that we will Deparse
504             my $A = $stash{"AUTOLOAD"};
505             if (defined ($A) && class($A) eq "GV" && defined($A->CV)
506                 && class($A->CV) eq "CV") {
507                 my $AF = $A->FILE;
508                 next unless $AF eq $0 || exists $self->{'files'}{$AF};
509             }
510             push @{$self->{'protos_todo'}}, [$pack . $key, undef];
511         } elsif ($class eq "GV") {
512             if (class(my $cv = $val->CV) ne "SPECIAL") {
513                 next if $self->{'subs_done'}{$$val}++;
514                 next if $$val != ${$cv->GV};   # Ignore imposters
515                 $self->todo($cv, 0);
516             }
517             if (class(my $cv = $val->FORM) ne "SPECIAL") {
518                 next if $self->{'forms_done'}{$$val}++;
519                 next if $$val != ${$cv->GV};   # Ignore imposters
520                 $self->todo($cv, 1);
521             }
522             if (class($val->HV) ne "SPECIAL" && $key =~ /::$/) {
523                 $self->stash_subs($pack . $key)
524                     unless $pack eq '' && $key eq 'main::';
525                     # avoid infinite recursion
526             }
527         }
528     }
529 }
530
531 sub print_protos {
532     my $self = shift;
533     my $ar;
534     my @ret;
535     foreach $ar (@{$self->{'protos_todo'}}) {
536         my $proto = (defined $ar->[1] ? " (". $ar->[1] . ")" : "");
537         push @ret, "sub " . $ar->[0] .  "$proto;\n";
538     }
539     delete $self->{'protos_todo'};
540     return @ret;
541 }
542
543 sub style_opts {
544     my $self = shift;
545     my $opts = shift;
546     my $opt;
547     while (length($opt = substr($opts, 0, 1))) {
548         if ($opt eq "C") {
549             $self->{'cuddle'} = " ";
550             $opts = substr($opts, 1);
551         } elsif ($opt eq "i") {
552             $opts =~ s/^i(\d+)//;
553             $self->{'indent_size'} = $1;
554         } elsif ($opt eq "T") {
555             $self->{'use_tabs'} = 1;
556             $opts = substr($opts, 1);
557         } elsif ($opt eq "v") {
558             $opts =~ s/^v([^.]*)(.|$)//;
559             $self->{'ex_const'} = $1;
560         }
561     }
562 }
563
564 sub new {
565     my $class = shift;
566     my $self = bless {}, $class;
567     $self->{'cuddle'} = "\n";
568     $self->{'curcop'} = undef;
569     $self->{'curstash'} = "main";
570     $self->{'ex_const'} = "'???'";
571     $self->{'expand'} = 0;
572     $self->{'files'} = {};
573     $self->{'indent_size'} = 4;
574     $self->{'linenums'} = 0;
575     $self->{'parens'} = 0;
576     $self->{'subs_todo'} = [];
577     $self->{'unquote'} = 0;
578     $self->{'use_dumper'} = 0;
579     $self->{'use_tabs'} = 0;
580
581     $self->{'ambient_arybase'} = 0;
582     $self->{'ambient_warnings'} = undef; # Assume no lexical warnings
583     $self->{'ambient_hints'} = 0;
584     $self->{'ambient_hinthash'} = undef;
585     $self->init();
586
587     while (my $arg = shift @_) {
588         if ($arg eq "-d") {
589             $self->{'use_dumper'} = 1;
590             require Data::Dumper;
591         } elsif ($arg =~ /^-f(.*)/) {
592             $self->{'files'}{$1} = 1;
593         } elsif ($arg eq "-l") {
594             $self->{'linenums'} = 1;
595         } elsif ($arg eq "-p") {
596             $self->{'parens'} = 1;
597         } elsif ($arg eq "-P") {
598             $self->{'noproto'} = 1;
599         } elsif ($arg eq "-q") {
600             $self->{'unquote'} = 1;
601         } elsif (substr($arg, 0, 2) eq "-s") {
602             $self->style_opts(substr $arg, 2);
603         } elsif ($arg =~ /^-x(\d)$/) {
604             $self->{'expand'} = $1;
605         }
606     }
607     return $self;
608 }
609
610 {
611     # Mask out the bits that L<warnings::register> uses
612     my $WARN_MASK;
613     BEGIN {
614         $WARN_MASK = $warnings::Bits{all} | $warnings::DeadBits{all};
615     }
616     sub WARN_MASK () {
617         return $WARN_MASK;
618     }
619 }
620
621 # Initialise the contextual information, either from
622 # defaults provided with the ambient_pragmas method,
623 # or from perl's own defaults otherwise.
624 sub init {
625     my $self = shift;
626
627     $self->{'arybase'}  = $self->{'ambient_arybase'};
628     $self->{'warnings'} = defined ($self->{'ambient_warnings'})
629                                 ? $self->{'ambient_warnings'} & WARN_MASK
630                                 : undef;
631     $self->{'hints'}    = $self->{'ambient_hints'};
632     $self->{'hints'} &= 0xFF if $] < 5.009;
633     $self->{'hinthash'} = $self->{'ambient_hinthash'};
634
635     # also a convenient place to clear out subs_declared
636     delete $self->{'subs_declared'};
637 }
638
639 sub compile {
640     my(@args) = @_;
641     return sub {
642         my $self = B::Deparse->new(@args);
643         # First deparse command-line args
644         if (defined $^I) { # deparse -i
645             print q(BEGIN { $^I = ).perlstring($^I).qq(; }\n);
646         }
647         if ($^W) { # deparse -w
648             print qq(BEGIN { \$^W = $^W; }\n);
649         }
650         if ($/ ne "\n" or defined $O::savebackslash) { # deparse -l and -0
651             my $fs = perlstring($/) || 'undef';
652             my $bs = perlstring($O::savebackslash) || 'undef';
653             print qq(BEGIN { \$/ = $fs; \$\\ = $bs; }\n);
654         }
655         my @BEGINs  = B::begin_av->isa("B::AV") ? B::begin_av->ARRAY : ();
656         my @UNITCHECKs = B::unitcheck_av->isa("B::AV")
657             ? B::unitcheck_av->ARRAY
658             : ();
659         my @CHECKs  = B::check_av->isa("B::AV") ? B::check_av->ARRAY : ();
660         my @INITs   = B::init_av->isa("B::AV") ? B::init_av->ARRAY : ();
661         my @ENDs    = B::end_av->isa("B::AV") ? B::end_av->ARRAY : ();
662         for my $block (@BEGINs, @UNITCHECKs, @CHECKs, @INITs, @ENDs) {
663             $self->todo($block, 0);
664         }
665         $self->stash_subs();
666         local($SIG{"__DIE__"}) =
667           sub {
668               if ($self->{'curcop'}) {
669                   my $cop = $self->{'curcop'};
670                   my($line, $file) = ($cop->line, $cop->file);
671                   print STDERR "While deparsing $file near line $line,\n";
672               }
673             };
674         $self->{'curcv'} = main_cv;
675         $self->{'curcvlex'} = undef;
676         print $self->print_protos;
677         @{$self->{'subs_todo'}} =
678           sort {$a->[0] <=> $b->[0]} @{$self->{'subs_todo'}};
679         print $self->indent($self->deparse_root(main_root)), "\n"
680           unless null main_root;
681         my @text;
682         while (scalar(@{$self->{'subs_todo'}})) {
683             push @text, $self->next_todo;
684         }
685         print $self->indent(join("", @text)), "\n" if @text;
686
687         # Print __DATA__ section, if necessary
688         no strict 'refs';
689         my $laststash = defined $self->{'curcop'}
690             ? $self->{'curcop'}->stash->NAME : $self->{'curstash'};
691         if (defined *{$laststash."::DATA"}{IO}) {
692             print "package $laststash;\n"
693                 unless $laststash eq $self->{'curstash'};
694             print "__DATA__\n";
695             print readline(*{$laststash."::DATA"});
696         }
697     }
698 }
699
700 sub coderef2text {
701     my $self = shift;
702     my $sub = shift;
703     croak "Usage: ->coderef2text(CODEREF)" unless UNIVERSAL::isa($sub, "CODE");
704
705     $self->init();
706     return $self->indent($self->deparse_sub(svref_2object($sub)));
707 }
708
709 sub ambient_pragmas {
710     my $self = shift;
711     my ($arybase, $hint_bits, $warning_bits, $hinthash) = (0, 0);
712
713     while (@_ > 1) {
714         my $name = shift();
715         my $val  = shift();
716
717         if ($name eq 'strict') {
718             require strict;
719
720             if ($val eq 'none') {
721                 $hint_bits &= ~strict::bits(qw/refs subs vars/);
722                 next();
723             }
724
725             my @names;
726             if ($val eq "all") {
727                 @names = qw/refs subs vars/;
728             }
729             elsif (ref $val) {
730                 @names = @$val;
731             }
732             else {
733                 @names = split' ', $val;
734             }
735             $hint_bits |= strict::bits(@names);
736         }
737
738         elsif ($name eq '$[') {
739             $arybase = $val;
740         }
741
742         elsif ($name eq 'integer'
743             || $name eq 'bytes'
744             || $name eq 'utf8') {
745             require "$name.pm";
746             if ($val) {
747                 $hint_bits |= ${$::{"${name}::"}{"hint_bits"}};
748             }
749             else {
750                 $hint_bits &= ~${$::{"${name}::"}{"hint_bits"}};
751             }
752         }
753
754         elsif ($name eq 're') {
755             require re;
756             if ($val eq 'none') {
757                 $hint_bits &= ~re::bits(qw/taint eval/);
758                 next();
759             }
760
761             my @names;
762             if ($val eq 'all') {
763                 @names = qw/taint eval/;
764             }
765             elsif (ref $val) {
766                 @names = @$val;
767             }
768             else {
769                 @names = split' ',$val;
770             }
771             $hint_bits |= re::bits(@names);
772         }
773
774         elsif ($name eq 'warnings') {
775             if ($val eq 'none') {
776                 $warning_bits = $warnings::NONE;
777                 next();
778             }
779
780             my @names;
781             if (ref $val) {
782                 @names = @$val;
783             }
784             else {
785                 @names = split/\s+/, $val;
786             }
787
788             $warning_bits = $warnings::NONE if !defined ($warning_bits);
789             $warning_bits |= warnings::bits(@names);
790         }
791
792         elsif ($name eq 'warning_bits') {
793             $warning_bits = $val;
794         }
795
796         elsif ($name eq 'hint_bits') {
797             $hint_bits = $val;
798         }
799
800         elsif ($name eq '%^H') {
801             $hinthash = $val;
802         }
803
804         else {
805             croak "Unknown pragma type: $name";
806         }
807     }
808     if (@_) {
809         croak "The ambient_pragmas method expects an even number of args";
810     }
811
812     $self->{'ambient_arybase'} = $arybase;
813     $self->{'ambient_warnings'} = $warning_bits;
814     $self->{'ambient_hints'} = $hint_bits;
815     $self->{'ambient_hinthash'} = $hinthash;
816 }
817
818 # This method is the inner loop, so try to keep it simple
819 sub deparse {
820     my $self = shift;
821     my($op, $cx) = @_;
822
823     Carp::confess("Null op in deparse") if !defined($op)
824                                         || class($op) eq "NULL";
825     my $meth = "pp_" . $op->name;
826     return $self->$meth($op, $cx);
827 }
828
829 sub indent {
830     my $self = shift;
831     my $txt = shift;
832     my @lines = split(/\n/, $txt);
833     my $leader = "";
834     my $level = 0;
835     my $line;
836     for $line (@lines) {
837         my $cmd = substr($line, 0, 1);
838         if ($cmd eq "\t" or $cmd eq "\b") {
839             $level += ($cmd eq "\t" ? 1 : -1) * $self->{'indent_size'};
840             if ($self->{'use_tabs'}) {
841                 $leader = "\t" x ($level / 8) . " " x ($level % 8);
842             } else {
843                 $leader = " " x $level;
844             }
845             $line = substr($line, 1);
846         }
847         if (substr($line, 0, 1) eq "\f") {
848             $line = substr($line, 1); # no indent
849         } else {
850             $line = $leader . $line;
851         }
852         $line =~ s/\cK;?//g;
853     }
854     return join("\n", @lines);
855 }
856
857 sub deparse_sub {
858     my $self = shift;
859     my $cv = shift;
860     my $proto = "";
861 Carp::confess("NULL in deparse_sub") if !defined($cv) || $cv->isa("B::NULL");
862 Carp::confess("SPECIAL in deparse_sub") if $cv->isa("B::SPECIAL");
863     local $self->{'curcop'} = $self->{'curcop'};
864     if ($cv->FLAGS & SVf_POK) {
865         $proto = "(". $cv->PV . ") ";
866     }
867     if ($cv->CvFLAGS & (CVf_METHOD|CVf_LOCKED|CVf_LVALUE)) {
868         $proto .= ": ";
869         $proto .= "lvalue " if $cv->CvFLAGS & CVf_LVALUE;
870         $proto .= "locked " if $cv->CvFLAGS & CVf_LOCKED;
871         $proto .= "method " if $cv->CvFLAGS & CVf_METHOD;
872     }
873
874     local($self->{'curcv'}) = $cv;
875     local($self->{'curcvlex'});
876     local(@$self{qw'curstash warnings hints hinthash'})
877                 = @$self{qw'curstash warnings hints hinthash'};
878     my $body;
879     if (not null $cv->ROOT) {
880         my $lineseq = $cv->ROOT->first;
881         if ($lineseq->name eq "lineseq") {
882             my @ops;
883             for(my$o=$lineseq->first; $$o; $o=$o->sibling) {
884                 push @ops, $o;
885             }
886             $body = $self->lineseq(undef, @ops).";";
887             my $scope_en = $self->find_scope_en($lineseq);
888             if (defined $scope_en) {
889                 my $subs = join"", $self->seq_subs($scope_en);
890                 $body .= ";\n$subs" if length($subs);
891             }
892         }
893         else {
894             $body = $self->deparse($cv->ROOT->first, 0);
895         }
896     }
897     else {
898         my $sv = $cv->const_sv;
899         if ($$sv) {
900             # uh-oh. inlinable sub... format it differently
901             return $proto . "{ " . $self->const($sv, 0) . " }\n";
902         } else { # XSUB? (or just a declaration)
903             return "$proto;\n";
904         }
905     }
906     return $proto ."{\n\t$body\n\b}" ."\n";
907 }
908
909 sub deparse_format {
910     my $self = shift;
911     my $form = shift;
912     my @text;
913     local($self->{'curcv'}) = $form;
914     local($self->{'curcvlex'});
915     local($self->{'in_format'}) = 1;
916     local(@$self{qw'curstash warnings hints hinthash'})
917                 = @$self{qw'curstash warnings hints hinthash'};
918     my $op = $form->ROOT;
919     my $kid;
920     return "\f." if $op->first->name eq 'stub'
921                 || $op->first->name eq 'nextstate';
922     $op = $op->first->first; # skip leavewrite, lineseq
923     while (not null $op) {
924         $op = $op->sibling; # skip nextstate
925         my @exprs;
926         $kid = $op->first->sibling; # skip pushmark
927         push @text, "\f".$self->const_sv($kid)->PV;
928         $kid = $kid->sibling;
929         for (; not null $kid; $kid = $kid->sibling) {
930             push @exprs, $self->deparse($kid, 0);
931         }
932         push @text, "\f".join(", ", @exprs)."\n" if @exprs;
933         $op = $op->sibling;
934     }
935     return join("", @text) . "\f.";
936 }
937
938 sub is_scope {
939     my $op = shift;
940     return $op->name eq "leave" || $op->name eq "scope"
941       || $op->name eq "lineseq"
942         || ($op->name eq "null" && class($op) eq "UNOP"
943             && (is_scope($op->first) || $op->first->name eq "enter"));
944 }
945
946 sub is_state {
947     my $name = $_[0]->name;
948     return $name eq "nextstate" || $name eq "dbstate" || $name eq "setstate";
949 }
950
951 sub is_miniwhile { # check for one-line loop (`foo() while $y--')
952     my $op = shift;
953     return (!null($op) and null($op->sibling)
954             and $op->name eq "null" and class($op) eq "UNOP"
955             and (($op->first->name =~ /^(and|or)$/
956                   and $op->first->first->sibling->name eq "lineseq")
957                  or ($op->first->name eq "lineseq"
958                      and not null $op->first->first->sibling
959                      and $op->first->first->sibling->name eq "unstack")
960                  ));
961 }
962
963 # Check if the op and its sibling are the initialization and the rest of a
964 # for (..;..;..) { ... } loop
965 sub is_for_loop {
966     my $op = shift;
967     # This OP might be almost anything, though it won't be a
968     # nextstate. (It's the initialization, so in the canonical case it
969     # will be an sassign.) The sibling is (old style) a lineseq whose
970     # first child is a nextstate and whose second is a leaveloop, or
971     # (new style) an unstack whose sibling is a leaveloop.
972     my $lseq = $op->sibling;
973     return 0 unless !is_state($op) and !null($lseq);
974     if ($lseq->name eq "lineseq") {
975         if ($lseq->first && !null($lseq->first) && is_state($lseq->first)
976             && (my $sib = $lseq->first->sibling)) {
977             return (!null($sib) && $sib->name eq "leaveloop");
978         }
979     } elsif ($lseq->name eq "unstack" && ($lseq->flags & OPf_SPECIAL)) {
980         my $sib = $lseq->sibling;
981         return $sib && !null($sib) && $sib->name eq "leaveloop";
982     }
983     return 0;
984 }
985
986 sub is_scalar {
987     my $op = shift;
988     return ($op->name eq "rv2sv" or
989             $op->name eq "padsv" or
990             $op->name eq "gv" or # only in array/hash constructs
991             $op->flags & OPf_KIDS && !null($op->first)
992               && $op->first->name eq "gvsv");
993 }
994
995 sub maybe_parens {
996     my $self = shift;
997     my($text, $cx, $prec) = @_;
998     if ($prec < $cx              # unary ops nest just fine
999         or $prec == $cx and $cx != 4 and $cx != 16 and $cx != 21
1000         or $self->{'parens'})
1001     {
1002         $text = "($text)";
1003         # In a unop, let parent reuse our parens; see maybe_parens_unop
1004         $text = "\cS" . $text if $cx == 16;
1005         return $text;
1006     } else {
1007         return $text;
1008     }
1009 }
1010
1011 # same as above, but get around the `if it looks like a function' rule
1012 sub maybe_parens_unop {
1013     my $self = shift;
1014     my($name, $kid, $cx) = @_;
1015     if ($cx > 16 or $self->{'parens'}) {
1016         $kid =  $self->deparse($kid, 1);
1017         if ($name eq "umask" && $kid =~ /^\d+$/) {
1018             $kid = sprintf("%#o", $kid);
1019         }
1020         return "$name($kid)";
1021     } else {
1022         $kid = $self->deparse($kid, 16);
1023         if ($name eq "umask" && $kid =~ /^\d+$/) {
1024             $kid = sprintf("%#o", $kid);
1025         }
1026         if (substr($kid, 0, 1) eq "\cS") {
1027             # use kid's parens
1028             return $name . substr($kid, 1);
1029         } elsif (substr($kid, 0, 1) eq "(") {
1030             # avoid looks-like-a-function trap with extra parens
1031             # (`+' can lead to ambiguities)
1032             return "$name(" . $kid  . ")";
1033         } else {
1034             return "$name $kid";
1035         }
1036     }
1037 }
1038
1039 sub maybe_parens_func {
1040     my $self = shift;
1041     my($func, $text, $cx, $prec) = @_;
1042     if ($prec <= $cx or substr($text, 0, 1) eq "(" or $self->{'parens'}) {
1043         return "$func($text)";
1044     } else {
1045         return "$func $text";
1046     }
1047 }
1048
1049 sub maybe_local {
1050     my $self = shift;
1051     my($op, $cx, $text) = @_;
1052     my $our_intro = ($op->name =~ /^(gv|rv2)[ash]v$/) ? OPpOUR_INTRO : 0;
1053     if ($op->private & (OPpLVAL_INTRO|$our_intro)
1054         and not $self->{'avoid_local'}{$$op}) {
1055         my $our_local = ($op->private & OPpLVAL_INTRO) ? "local" : "our";
1056         if( $our_local eq 'our' ) {
1057             if ( $text !~ /^\W(\w+::)*\w+\z/
1058              and !utf8::decode($text) || $text !~ /^\W(\w+::)*\w+\z/
1059             ) {
1060                 die "Unexpected our($text)\n";
1061             }
1062             $text =~ s/(\w+::)+//;
1063         }
1064         if (want_scalar($op)) {
1065             return "$our_local $text";
1066         } else {
1067             return $self->maybe_parens_func("$our_local", $text, $cx, 16);
1068         }
1069     } else {
1070         return $text;
1071     }
1072 }
1073
1074 sub maybe_targmy {
1075     my $self = shift;
1076     my($op, $cx, $func, @args) = @_;
1077     if ($op->private & OPpTARGET_MY) {
1078         my $var = $self->padname($op->targ);
1079         my $val = $func->($self, $op, 7, @args);
1080         return $self->maybe_parens("$var = $val", $cx, 7);
1081     } else {
1082         return $func->($self, $op, $cx, @args);
1083     }
1084 }
1085
1086 sub padname_sv {
1087     my $self = shift;
1088     my $targ = shift;
1089     return $self->{'curcv'}->PADLIST->ARRAYelt(0)->ARRAYelt($targ);
1090 }
1091
1092 sub maybe_my {
1093     my $self = shift;
1094     my($op, $cx, $text) = @_;
1095     if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {
1096         my $my = $op->private & OPpPAD_STATE ? "state" : "my";
1097         if (want_scalar($op)) {
1098             return "$my $text";
1099         } else {
1100             return $self->maybe_parens_func($my, $text, $cx, 16);
1101         }
1102     } else {
1103         return $text;
1104     }
1105 }
1106
1107 # The following OPs don't have functions:
1108
1109 # pp_padany -- does not exist after parsing
1110
1111 sub AUTOLOAD {
1112     if ($AUTOLOAD =~ s/^.*::pp_//) {
1113         warn "unexpected OP_".uc $AUTOLOAD;
1114         return "XXX";
1115     } else {
1116         die "Undefined subroutine $AUTOLOAD called";
1117     }
1118 }
1119
1120 sub DESTROY {}  #       Do not AUTOLOAD
1121
1122 # $root should be the op which represents the root of whatever
1123 # we're sequencing here. If it's undefined, then we don't append
1124 # any subroutine declarations to the deparsed ops, otherwise we
1125 # append appropriate declarations.
1126 sub lineseq {
1127     my($self, $root, @ops) = @_;
1128     my($expr, @exprs);
1129
1130     my $out_cop = $self->{'curcop'};
1131     my $out_seq = defined($out_cop) ? $out_cop->cop_seq : undef;
1132     my $limit_seq;
1133     if (defined $root) {
1134         $limit_seq = $out_seq;
1135         my $nseq;
1136         $nseq = $self->find_scope_st($root->sibling) if ${$root->sibling};
1137         $limit_seq = $nseq if !defined($limit_seq)
1138                            or defined($nseq) && $nseq < $limit_seq;
1139     }
1140     $limit_seq = $self->{'limit_seq'}
1141         if defined($self->{'limit_seq'})
1142         && (!defined($limit_seq) || $self->{'limit_seq'} < $limit_seq);
1143     local $self->{'limit_seq'} = $limit_seq;
1144
1145     $self->walk_lineseq($root, \@ops,
1146                        sub { push @exprs, $_[0]} );
1147
1148     my $body = join(";\n", grep {length} @exprs);
1149     my $subs = "";
1150     if (defined $root && defined $limit_seq && !$self->{'in_format'}) {
1151         $subs = join "\n", $self->seq_subs($limit_seq);
1152     }
1153     return join(";\n", grep {length} $body, $subs);
1154 }
1155
1156 sub scopeop {
1157     my($real_block, $self, $op, $cx) = @_;
1158     my $kid;
1159     my @kids;
1160
1161     local(@$self{qw'curstash warnings hints hinthash'})
1162                 = @$self{qw'curstash warnings hints hinthash'} if $real_block;
1163     if ($real_block) {
1164         $kid = $op->first->sibling; # skip enter
1165         if (is_miniwhile($kid)) {
1166             my $top = $kid->first;
1167             my $name = $top->name;
1168             if ($name eq "and") {
1169                 $name = "while";
1170             } elsif ($name eq "or") {
1171                 $name = "until";
1172             } else { # no conditional -> while 1 or until 0
1173                 return $self->deparse($top->first, 1) . " while 1";
1174             }
1175             my $cond = $top->first;
1176             my $body = $cond->sibling->first; # skip lineseq
1177             $cond = $self->deparse($cond, 1);
1178             $body = $self->deparse($body, 1);
1179             return "$body $name $cond";
1180         }
1181     } else {
1182         $kid = $op->first;
1183     }
1184     for (; !null($kid); $kid = $kid->sibling) {
1185         push @kids, $kid;
1186     }
1187     if ($cx > 0) { # inside an expression, (a do {} while for lineseq)
1188         return "do {\n\t" . $self->lineseq($op, @kids) . "\n\b}";
1189     } else {
1190         my $lineseq = $self->lineseq($op, @kids);
1191         return (length ($lineseq) ? "$lineseq;" : "");
1192     }
1193 }
1194
1195 sub pp_scope { scopeop(0, @_); }
1196 sub pp_lineseq { scopeop(0, @_); }
1197 sub pp_leave { scopeop(1, @_); }
1198
1199 # This is a special case of scopeop and lineseq, for the case of the
1200 # main_root. The difference is that we print the output statements as
1201 # soon as we get them, for the sake of impatient users.
1202 sub deparse_root {
1203     my $self = shift;
1204     my($op) = @_;
1205     local(@$self{qw'curstash warnings hints hinthash'})
1206       = @$self{qw'curstash warnings hints hinthash'};
1207     my @kids;
1208     return if null $op->first; # Can happen, e.g., for Bytecode without -k
1209     for (my $kid = $op->first->sibling; !null($kid); $kid = $kid->sibling) {
1210         push @kids, $kid;
1211     }
1212     $self->walk_lineseq($op, \@kids,
1213                         sub { print $self->indent($_[0].';');
1214                               print "\n" unless $_[1] == $#kids;
1215                           });
1216 }
1217
1218 sub walk_lineseq {
1219     my ($self, $op, $kids, $callback) = @_;
1220     my @kids = @$kids;
1221     for (my $i = 0; $i < @kids; $i++) {
1222         my $expr = "";
1223         if (is_state $kids[$i]) {
1224             $expr = $self->deparse($kids[$i++], 0);
1225             if ($i > $#kids) {
1226                 $callback->($expr, $i);
1227                 last;
1228             }
1229         }
1230         if (is_for_loop($kids[$i])) {
1231             $callback->($expr . $self->for_loop($kids[$i], 0),
1232                 $i += $kids[$i]->sibling->name eq "unstack" ? 2 : 1);
1233             next;
1234         }
1235         $expr .= $self->deparse($kids[$i], (@kids != 1)/2);
1236         $expr =~ s/;\n?\z//;
1237         $callback->($expr, $i);
1238     }
1239 }
1240
1241 # The BEGIN {} is used here because otherwise this code isn't executed
1242 # when you run B::Deparse on itself.
1243 my %globalnames;
1244 BEGIN { map($globalnames{$_}++, "SIG", "STDIN", "STDOUT", "STDERR", "INC",
1245             "ENV", "ARGV", "ARGVOUT", "_"); }
1246
1247 sub gv_name {
1248     my $self = shift;
1249     my $gv = shift;
1250 Carp::confess() unless ref($gv) eq "B::GV";
1251     my $stash = $gv->STASH->NAME;
1252     my $name = $gv->SAFENAME;
1253     if ($stash eq 'main' && $name =~ /^::/) {
1254         $stash = '::';
1255     }
1256     elsif (($stash eq 'main' && $globalnames{$name})
1257         or ($stash eq $self->{'curstash'} && !$globalnames{$name}
1258             && ($stash eq 'main' || $name !~ /::/))
1259         or $name =~ /^[^A-Za-z_:]/)
1260     {
1261         $stash = "";
1262     } else {
1263         $stash = $stash . "::";
1264     }
1265     if ($name =~ /^(\^..|{)/) {
1266         $name = "{$name}";       # ${^WARNING_BITS}, etc and ${
1267     }
1268     return $stash . $name;
1269 }
1270
1271 # Return the name to use for a stash variable.
1272 # If a lexical with the same name is in scope, it may need to be
1273 # fully-qualified.
1274 sub stash_variable {
1275     my ($self, $prefix, $name) = @_;
1276
1277     return "$prefix$name" if $name =~ /::/;
1278
1279     unless ($prefix eq '$' || $prefix eq '@' || #'
1280             $prefix eq '%' || $prefix eq '$#') {
1281         return "$prefix$name";
1282     }
1283
1284     my $v = ($prefix eq '$#' ? '@' : $prefix) . $name;
1285     return $prefix .$self->{'curstash'}.'::'. $name if $self->lex_in_scope($v);
1286     return "$prefix$name";
1287 }
1288
1289 sub lex_in_scope {
1290     my ($self, $name) = @_;
1291     $self->populate_curcvlex() if !defined $self->{'curcvlex'};
1292
1293     return 0 if !defined($self->{'curcop'});
1294     my $seq = $self->{'curcop'}->cop_seq;
1295     return 0 if !exists $self->{'curcvlex'}{$name};
1296     for my $a (@{$self->{'curcvlex'}{$name}}) {
1297         my ($st, $en) = @$a;
1298         return 1 if $seq > $st && $seq <= $en;
1299     }
1300     return 0;
1301 }
1302
1303 sub populate_curcvlex {
1304     my $self = shift;
1305     for (my $cv = $self->{'curcv'}; class($cv) eq "CV"; $cv = $cv->OUTSIDE) {
1306         my $padlist = $cv->PADLIST;
1307         # an undef CV still in lexical chain
1308         next if class($padlist) eq "SPECIAL";
1309         my @padlist = $padlist->ARRAY;
1310         my @ns = $padlist[0]->ARRAY;
1311
1312         for (my $i=0; $i<@ns; ++$i) {
1313             next if class($ns[$i]) eq "SPECIAL";
1314             next if $ns[$i]->FLAGS & SVpad_OUR;  # Skip "our" vars
1315             if (class($ns[$i]) eq "PV") {
1316                 # Probably that pesky lexical @_
1317                 next;
1318             }
1319             my $name = $ns[$i]->PVX;
1320             my ($seq_st, $seq_en) =
1321                 ($ns[$i]->FLAGS & SVf_FAKE)
1322                     ? (0, 999999)
1323                     : ($ns[$i]->COP_SEQ_RANGE_LOW, $ns[$i]->COP_SEQ_RANGE_HIGH);
1324
1325             push @{$self->{'curcvlex'}{$name}}, [$seq_st, $seq_en];
1326         }
1327     }
1328 }
1329
1330 sub find_scope_st { ((find_scope(@_))[0]); }
1331 sub find_scope_en { ((find_scope(@_))[1]); }
1332
1333 # Recurses down the tree, looking for pad variable introductions and COPs
1334 sub find_scope {
1335     my ($self, $op, $scope_st, $scope_en) = @_;
1336     carp("Undefined op in find_scope") if !defined $op;
1337     return ($scope_st, $scope_en) unless $op->flags & OPf_KIDS;
1338
1339     my @queue = ($op);
1340     while(my $op = shift @queue ) {
1341         for (my $o=$op->first; $$o; $o=$o->sibling) {
1342             if ($o->name =~ /^pad.v$/ && $o->private & OPpLVAL_INTRO) {
1343                 my $s = int($self->padname_sv($o->targ)->COP_SEQ_RANGE_LOW);
1344                 my $e = $self->padname_sv($o->targ)->COP_SEQ_RANGE_HIGH;
1345                 $scope_st = $s if !defined($scope_st) || $s < $scope_st;
1346                 $scope_en = $e if !defined($scope_en) || $e > $scope_en;
1347                 return ($scope_st, $scope_en);
1348             }
1349             elsif (is_state($o)) {
1350                 my $c = $o->cop_seq;
1351                 $scope_st = $c if !defined($scope_st) || $c < $scope_st;
1352                 $scope_en = $c if !defined($scope_en) || $c > $scope_en;
1353                 return ($scope_st, $scope_en);
1354             }
1355             elsif ($o->flags & OPf_KIDS) {
1356                 unshift (@queue, $o);
1357             }
1358         }
1359     }
1360
1361     return ($scope_st, $scope_en);
1362 }
1363
1364 # Returns a list of subs which should be inserted before the COP
1365 sub cop_subs {
1366     my ($self, $op, $out_seq) = @_;
1367     my $seq = $op->cop_seq;
1368     # If we have nephews, then our sequence number indicates
1369     # the cop_seq of the end of some sort of scope.
1370     if (class($op->sibling) ne "NULL" && $op->sibling->flags & OPf_KIDS
1371         and my $nseq = $self->find_scope_st($op->sibling) ) {
1372         $seq = $nseq;
1373     }
1374     $seq = $out_seq if defined($out_seq) && $out_seq < $seq;
1375     return $self->seq_subs($seq);
1376 }
1377
1378 sub seq_subs {
1379     my ($self, $seq) = @_;
1380     my @text;
1381 #push @text, "# ($seq)\n";
1382
1383     return "" if !defined $seq;
1384     while (scalar(@{$self->{'subs_todo'}})
1385            and $seq > $self->{'subs_todo'}[0][0]) {
1386         push @text, $self->next_todo;
1387     }
1388     return @text;
1389 }
1390
1391 # Notice how subs and formats are inserted between statements here;
1392 # also $[ assignments and pragmas.
1393 sub pp_nextstate {
1394     my $self = shift;
1395     my($op, $cx) = @_;
1396     $self->{'curcop'} = $op;
1397     my @text;
1398     push @text, $self->cop_subs($op);
1399     my $stash = $op->stashpv;
1400     if ($stash ne $self->{'curstash'}) {
1401         push @text, "package $stash;\n";
1402         $self->{'curstash'} = $stash;
1403     }
1404
1405     if ($self->{'arybase'} != $op->arybase) {
1406         push @text, '$[ = '. $op->arybase .";\n";
1407         $self->{'arybase'} = $op->arybase;
1408     }
1409
1410     my $warnings = $op->warnings;
1411     my $warning_bits;
1412     if ($warnings->isa("B::SPECIAL") && $$warnings == 4) {
1413         $warning_bits = $warnings::Bits{"all"} & WARN_MASK;
1414     }
1415     elsif ($warnings->isa("B::SPECIAL") && $$warnings == 5) {
1416         $warning_bits = $warnings::NONE;
1417     }
1418     elsif ($warnings->isa("B::SPECIAL")) {
1419         $warning_bits = undef;
1420     }
1421     else {
1422         $warning_bits = $warnings->PV & WARN_MASK;
1423     }
1424
1425     if (defined ($warning_bits) and
1426        !defined($self->{warnings}) || $self->{'warnings'} ne $warning_bits) {
1427         push @text, declare_warnings($self->{'warnings'}, $warning_bits);
1428         $self->{'warnings'} = $warning_bits;
1429     }
1430
1431     my $hints = $] < 5.008009 ? $op->private : $op->hints;
1432     if ($self->{'hints'} != $hints) {
1433         push @text, declare_hints($self->{'hints'}, $hints);
1434         $self->{'hints'} = $hints;
1435     }
1436
1437     # hack to check that the hint hash hasn't changed
1438     if ($] > 5.009 &&
1439         "@{[sort %{$self->{'hinthash'} || {}}]}"
1440         ne "@{[sort %{$op->hints_hash->HASH || {}}]}") {
1441         push @text, declare_hinthash($self->{'hinthash'}, $op->hints_hash->HASH, $self->{indent_size});
1442         $self->{'hinthash'} = $op->hints_hash->HASH;
1443     }
1444
1445     # This should go after of any branches that add statements, to
1446     # increase the chances that it refers to the same line it did in
1447     # the original program.
1448     if ($self->{'linenums'}) {
1449         push @text, "\f#line " . $op->line .
1450           ' "' . $op->file, qq'"\n';
1451     }
1452
1453     push @text, $op->label . ": " if $op->label;
1454
1455     return join("", @text);
1456 }
1457
1458 sub declare_warnings {
1459     my ($from, $to) = @_;
1460     if (($to & WARN_MASK) eq (warnings::bits("all") & WARN_MASK)) {
1461         return "use warnings;\n";
1462     }
1463     elsif (($to & WARN_MASK) eq ("\0"x length($to) & WARN_MASK)) {
1464         return "no warnings;\n";
1465     }
1466     return "BEGIN {\${^WARNING_BITS} = ".perlstring($to)."}\n";
1467 }
1468
1469 sub declare_hints {
1470     my ($from, $to) = @_;
1471     my $use = $to   & ~$from;
1472     my $no  = $from & ~$to;
1473     my $decls = "";
1474     for my $pragma (hint_pragmas($use)) {
1475         $decls .= "use $pragma;\n";
1476     }
1477     for my $pragma (hint_pragmas($no)) {
1478         $decls .= "no $pragma;\n";
1479     }
1480     return $decls;
1481 }
1482
1483 # Internal implementation hints that the core sets automatically, so don't need
1484 # (or want) to be passed back to the user
1485 my %ignored_hints = (
1486     'open<' => 1,
1487     'open>' => 1,
1488     ':'     => 1,
1489 );
1490
1491 sub declare_hinthash {
1492     my ($from, $to, $indent) = @_;
1493     my @decls;
1494     for my $key (keys %$to) {
1495         next if $ignored_hints{$key};
1496         if (!defined $from->{$key} or $from->{$key} ne $to->{$key}) {
1497             push @decls, qq(\$^H{'$key'} = q($to->{$key}););
1498         }
1499     }
1500     for my $key (keys %$from) {
1501         next if $ignored_hints{$key};
1502         if (!exists $to->{$key}) {
1503             push @decls, qq(delete \$^H{'$key'};);
1504         }
1505     }
1506     @decls or return '';
1507     return join("\n" . (" " x $indent), "BEGIN {", @decls) . "\n}\n";
1508 }
1509
1510 sub hint_pragmas {
1511     my ($bits) = @_;
1512     my @pragmas;
1513     push @pragmas, "integer" if $bits & 0x1;
1514     push @pragmas, "strict 'refs'" if $bits & 0x2;
1515     push @pragmas, "bytes" if $bits & 0x8;
1516     return @pragmas;
1517 }
1518
1519 sub pp_dbstate { pp_nextstate(@_) }
1520 sub pp_setstate { pp_nextstate(@_) }
1521
1522 sub pp_unstack { return "" } # see also leaveloop
1523
1524 sub baseop {
1525     my $self = shift;
1526     my($op, $cx, $name) = @_;
1527     return $name;
1528 }
1529
1530 sub pp_stub {
1531     my $self = shift;
1532     my($op, $cx, $name) = @_;
1533     if ($cx >= 1) {
1534         return "()";
1535     }
1536     else {
1537         return "();";
1538     }
1539 }
1540 sub pp_wantarray { baseop(@_, "wantarray") }
1541 sub pp_fork { baseop(@_, "fork") }
1542 sub pp_wait { maybe_targmy(@_, \&baseop, "wait") }
1543 sub pp_getppid { maybe_targmy(@_, \&baseop, "getppid") }
1544 sub pp_time { maybe_targmy(@_, \&baseop, "time") }
1545 sub pp_tms { baseop(@_, "times") }
1546 sub pp_ghostent { baseop(@_, "gethostent") }
1547 sub pp_gnetent { baseop(@_, "getnetent") }
1548 sub pp_gprotoent { baseop(@_, "getprotoent") }
1549 sub pp_gservent { baseop(@_, "getservent") }
1550 sub pp_ehostent { baseop(@_, "endhostent") }
1551 sub pp_enetent { baseop(@_, "endnetent") }
1552 sub pp_eprotoent { baseop(@_, "endprotoent") }
1553 sub pp_eservent { baseop(@_, "endservent") }
1554 sub pp_gpwent { baseop(@_, "getpwent") }
1555 sub pp_spwent { baseop(@_, "setpwent") }
1556 sub pp_epwent { baseop(@_, "endpwent") }
1557 sub pp_ggrent { baseop(@_, "getgrent") }
1558 sub pp_sgrent { baseop(@_, "setgrent") }
1559 sub pp_egrent { baseop(@_, "endgrent") }
1560 sub pp_getlogin { baseop(@_, "getlogin") }
1561
1562 sub POSTFIX () { 1 }
1563
1564 # I couldn't think of a good short name, but this is the category of
1565 # symbolic unary operators with interesting precedence
1566
1567 sub pfixop {
1568     my $self = shift;
1569     my($op, $cx, $name, $prec, $flags) = (@_, 0);
1570     my $kid = $op->first;
1571     $kid = $self->deparse($kid, $prec);
1572     return $self->maybe_parens(($flags & POSTFIX) ? "$kid$name" : "$name$kid",
1573                                $cx, $prec);
1574 }
1575
1576 sub pp_preinc { pfixop(@_, "++", 23) }
1577 sub pp_predec { pfixop(@_, "--", 23) }
1578 sub pp_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
1579 sub pp_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
1580 sub pp_i_preinc { pfixop(@_, "++", 23) }
1581 sub pp_i_predec { pfixop(@_, "--", 23) }
1582 sub pp_i_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
1583 sub pp_i_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
1584 sub pp_complement { maybe_targmy(@_, \&pfixop, "~", 21) }
1585
1586 sub pp_negate { maybe_targmy(@_, \&real_negate) }
1587 sub real_negate {
1588     my $self = shift;
1589     my($op, $cx) = @_;
1590     if ($op->first->name =~ /^(i_)?negate$/) {
1591         # avoid --$x
1592         $self->pfixop($op, $cx, "-", 21.5);
1593     } else {
1594         $self->pfixop($op, $cx, "-", 21);       
1595     }
1596 }
1597 sub pp_i_negate { pp_negate(@_) }
1598
1599 sub pp_not {
1600     my $self = shift;
1601     my($op, $cx) = @_;
1602     if ($cx <= 4) {
1603         $self->pfixop($op, $cx, "not ", 4);
1604     } else {
1605         $self->pfixop($op, $cx, "!", 21);       
1606     }
1607 }
1608
1609 sub unop {
1610     my $self = shift;
1611     my($op, $cx, $name) = @_;
1612     my $kid;
1613     if ($op->flags & OPf_KIDS) {
1614         $kid = $op->first;
1615         if (not $name) {
1616             # this deals with 'boolkeys' right now
1617             return $self->deparse($kid,$cx);
1618         }
1619         my $builtinname = $name;
1620         $builtinname =~ /^CORE::/ or $builtinname = "CORE::$name";
1621         if (defined prototype($builtinname)
1622            && prototype($builtinname) =~ /^;?\*/
1623            && $kid->name eq "rv2gv") {
1624             $kid = $kid->first;
1625         }
1626
1627         return $self->maybe_parens_unop($name, $kid, $cx);
1628     } else {
1629         return $name .  ($op->flags & OPf_SPECIAL ? "()" : "");
1630     }
1631 }
1632
1633 sub pp_chop { maybe_targmy(@_, \&unop, "chop") }
1634 sub pp_chomp { maybe_targmy(@_, \&unop, "chomp") }
1635 sub pp_schop { maybe_targmy(@_, \&unop, "chop") }
1636 sub pp_schomp { maybe_targmy(@_, \&unop, "chomp") }
1637 sub pp_defined { unop(@_, "defined") }
1638 sub pp_undef { unop(@_, "undef") }
1639 sub pp_study { unop(@_, "study") }
1640 sub pp_ref { unop(@_, "ref") }
1641 sub pp_pos { maybe_local(@_, unop(@_, "pos")) }
1642
1643 sub pp_sin { maybe_targmy(@_, \&unop, "sin") }
1644 sub pp_cos { maybe_targmy(@_, \&unop, "cos") }
1645 sub pp_rand { maybe_targmy(@_, \&unop, "rand") }
1646 sub pp_srand { unop(@_, "srand") }
1647 sub pp_exp { maybe_targmy(@_, \&unop, "exp") }
1648 sub pp_log { maybe_targmy(@_, \&unop, "log") }
1649 sub pp_sqrt { maybe_targmy(@_, \&unop, "sqrt") }
1650 sub pp_int { maybe_targmy(@_, \&unop, "int") }
1651 sub pp_hex { maybe_targmy(@_, \&unop, "hex") }
1652 sub pp_oct { maybe_targmy(@_, \&unop, "oct") }
1653 sub pp_abs { maybe_targmy(@_, \&unop, "abs") }
1654
1655 sub pp_length { maybe_targmy(@_, \&unop, "length") }
1656 sub pp_ord { maybe_targmy(@_, \&unop, "ord") }
1657 sub pp_chr { maybe_targmy(@_, \&unop, "chr") }
1658
1659 sub pp_each { unop(@_, "each") }
1660 sub pp_values { unop(@_, "values") }
1661 sub pp_keys { unop(@_, "keys") }
1662 sub pp_boolkeys { 
1663     # no name because its an optimisation op that has no keyword
1664     unop(@_,"");
1665 }
1666 sub pp_aeach { unop(@_, "each") }
1667 sub pp_avalues { unop(@_, "values") }
1668 sub pp_akeys { unop(@_, "keys") }
1669 sub pp_pop { unop(@_, "pop") }
1670 sub pp_shift { unop(@_, "shift") }
1671
1672 sub pp_caller { unop(@_, "caller") }
1673 sub pp_reset { unop(@_, "reset") }
1674 sub pp_exit { unop(@_, "exit") }
1675 sub pp_prototype { unop(@_, "prototype") }
1676
1677 sub pp_close { unop(@_, "close") }
1678 sub pp_fileno { unop(@_, "fileno") }
1679 sub pp_umask { unop(@_, "umask") }
1680 sub pp_untie { unop(@_, "untie") }
1681 sub pp_tied { unop(@_, "tied") }
1682 sub pp_dbmclose { unop(@_, "dbmclose") }
1683 sub pp_getc { unop(@_, "getc") }
1684 sub pp_eof { unop(@_, "eof") }
1685 sub pp_tell { unop(@_, "tell") }
1686 sub pp_getsockname { unop(@_, "getsockname") }
1687 sub pp_getpeername { unop(@_, "getpeername") }
1688
1689 sub pp_chdir { maybe_targmy(@_, \&unop, "chdir") }
1690 sub pp_chroot { maybe_targmy(@_, \&unop, "chroot") }
1691 sub pp_readlink { unop(@_, "readlink") }
1692 sub pp_rmdir { maybe_targmy(@_, \&unop, "rmdir") }
1693 sub pp_readdir { unop(@_, "readdir") }
1694 sub pp_telldir { unop(@_, "telldir") }
1695 sub pp_rewinddir { unop(@_, "rewinddir") }
1696 sub pp_closedir { unop(@_, "closedir") }
1697 sub pp_getpgrp { maybe_targmy(@_, \&unop, "getpgrp") }
1698 sub pp_localtime { unop(@_, "localtime") }
1699 sub pp_gmtime { unop(@_, "gmtime") }
1700 sub pp_alarm { unop(@_, "alarm") }
1701 sub pp_sleep { maybe_targmy(@_, \&unop, "sleep") }
1702
1703 sub pp_dofile { unop(@_, "do") }
1704 sub pp_entereval { unop(@_, "eval") }
1705
1706 sub pp_ghbyname { unop(@_, "gethostbyname") }
1707 sub pp_gnbyname { unop(@_, "getnetbyname") }
1708 sub pp_gpbyname { unop(@_, "getprotobyname") }
1709 sub pp_shostent { unop(@_, "sethostent") }
1710 sub pp_snetent { unop(@_, "setnetent") }
1711 sub pp_sprotoent { unop(@_, "setprotoent") }
1712 sub pp_sservent { unop(@_, "setservent") }
1713 sub pp_gpwnam { unop(@_, "getpwnam") }
1714 sub pp_gpwuid { unop(@_, "getpwuid") }
1715 sub pp_ggrnam { unop(@_, "getgrnam") }
1716 sub pp_ggrgid { unop(@_, "getgrgid") }
1717
1718 sub pp_lock { unop(@_, "lock") }
1719
1720 sub pp_continue { unop(@_, "continue"); }
1721 sub pp_break {
1722     my ($self, $op) = @_;
1723     return "" if $op->flags & OPf_SPECIAL;
1724     unop(@_, "break");
1725 }
1726
1727 sub givwhen {
1728     my $self = shift;
1729     my($op, $cx, $givwhen) = @_;
1730
1731     my $enterop = $op->first;
1732     my ($head, $block);
1733     if ($enterop->flags & OPf_SPECIAL) {
1734         $head = "default";
1735         $block = $self->deparse($enterop->first, 0);
1736     }
1737     else {
1738         my $cond = $enterop->first;
1739         my $cond_str = $self->deparse($cond, 1);
1740         $head = "$givwhen ($cond_str)";
1741         $block = $self->deparse($cond->sibling, 0);
1742     }
1743
1744     return "$head {\n".
1745         "\t$block\n".
1746         "\b}\cK";
1747 }
1748
1749 sub pp_leavegiven { givwhen(@_, "given"); }
1750 sub pp_leavewhen  { givwhen(@_, "when"); }
1751
1752 sub pp_exists {
1753     my $self = shift;
1754     my($op, $cx) = @_;
1755     my $arg;
1756     if ($op->private & OPpEXISTS_SUB) {
1757         # Checking for the existence of a subroutine
1758         return $self->maybe_parens_func("exists",
1759                                 $self->pp_rv2cv($op->first, 16), $cx, 16);
1760     }
1761     if ($op->flags & OPf_SPECIAL) {
1762         # Array element, not hash element
1763         return $self->maybe_parens_func("exists",
1764                                 $self->pp_aelem($op->first, 16), $cx, 16);
1765     }
1766     return $self->maybe_parens_func("exists", $self->pp_helem($op->first, 16),
1767                                     $cx, 16);
1768 }
1769
1770 sub pp_delete {
1771     my $self = shift;
1772     my($op, $cx) = @_;
1773     my $arg;
1774     if ($op->private & OPpSLICE) {
1775         if ($op->flags & OPf_SPECIAL) {
1776             # Deleting from an array, not a hash
1777             return $self->maybe_parens_func("delete",
1778                                         $self->pp_aslice($op->first, 16),
1779                                         $cx, 16);
1780         }
1781         return $self->maybe_parens_func("delete",
1782                                         $self->pp_hslice($op->first, 16),
1783                                         $cx, 16);
1784     } else {
1785         if ($op->flags & OPf_SPECIAL) {
1786             # Deleting from an array, not a hash
1787             return $self->maybe_parens_func("delete",
1788                                         $self->pp_aelem($op->first, 16),
1789                                         $cx, 16);
1790         }
1791         return $self->maybe_parens_func("delete",
1792                                         $self->pp_helem($op->first, 16),
1793                                         $cx, 16);
1794     }
1795 }
1796
1797 sub pp_require {
1798     my $self = shift;
1799     my($op, $cx) = @_;
1800     my $opname = $op->flags & OPf_SPECIAL ? 'CORE::require' : 'require';
1801     if (class($op) eq "UNOP" and $op->first->name eq "const"
1802         and $op->first->private & OPpCONST_BARE)
1803     {
1804         my $name = $self->const_sv($op->first)->PV;
1805         $name =~ s[/][::]g;
1806         $name =~ s/\.pm//g;
1807         return "$opname $name";
1808     } else {    
1809         $self->unop($op, $cx, $op->first->private & OPpCONST_NOVER ? "no" : $opname);
1810     }
1811 }
1812
1813 sub pp_scalar {
1814     my $self = shift;
1815     my($op, $cx) = @_;
1816     my $kid = $op->first;
1817     if (not null $kid->sibling) {
1818         # XXX Was a here-doc
1819         return $self->dquote($op);
1820     }
1821     $self->unop(@_, "scalar");
1822 }
1823
1824
1825 sub padval {
1826     my $self = shift;
1827     my $targ = shift;
1828     return $self->{'curcv'}->PADLIST->ARRAYelt(1)->ARRAYelt($targ);
1829 }
1830
1831 sub anon_hash_or_list {
1832     my $self = shift;
1833     my($op, $cx) = @_;
1834
1835     my($pre, $post) = @{{"anonlist" => ["[","]"],
1836                          "anonhash" => ["{","}"]}->{$op->name}};
1837     my($expr, @exprs);
1838     $op = $op->first->sibling; # skip pushmark
1839     for (; !null($op); $op = $op->sibling) {
1840         $expr = $self->deparse($op, 6);
1841         push @exprs, $expr;
1842     }
1843     if ($pre eq "{" and $cx < 1) {
1844         # Disambiguate that it's not a block
1845         $pre = "+{";
1846     }
1847     return $pre . join(", ", @exprs) . $post;
1848 }
1849
1850 sub pp_anonlist {
1851     my $self = shift;
1852     my ($op, $cx) = @_;
1853     if ($op->flags & OPf_SPECIAL) {
1854         return $self->anon_hash_or_list($op, $cx);
1855     }
1856     warn "Unexpected op pp_" . $op->name() . " without OPf_SPECIAL";
1857     return 'XXX';
1858 }
1859
1860 *pp_anonhash = \&pp_anonlist;
1861
1862 sub pp_refgen {
1863     my $self = shift;   
1864     my($op, $cx) = @_;
1865     my $kid = $op->first;
1866     if ($kid->name eq "null") {
1867         $kid = $kid->first;
1868         if (!null($kid->sibling) and
1869                  $kid->sibling->name eq "anoncode") {
1870             return $self->e_anoncode({ code => $self->padval($kid->sibling->targ) });
1871         } elsif ($kid->name eq "pushmark") {
1872             my $sib_name = $kid->sibling->name;
1873             if ($sib_name =~ /^(pad|rv2)[ah]v$/
1874                 and not $kid->sibling->flags & OPf_REF)
1875             {
1876                 # The @a in \(@a) isn't in ref context, but only when the
1877                 # parens are there.
1878                 return "\\(" . $self->pp_list($op->first) . ")";
1879             } elsif ($sib_name eq 'entersub') {
1880                 my $text = $self->deparse($kid->sibling, 1);
1881                 # Always show parens for \(&func()), but only with -p otherwise
1882                 $text = "($text)" if $self->{'parens'}
1883                                  or $kid->sibling->private & OPpENTERSUB_AMPER;
1884                 return "\\$text";
1885             }
1886         }
1887     }
1888     $self->pfixop($op, $cx, "\\", 20);
1889 }
1890
1891 sub e_anoncode {
1892     my ($self, $info) = @_;
1893     my $text = $self->deparse_sub($info->{code});
1894     return "sub " . $text;
1895 }
1896
1897 sub pp_srefgen { pp_refgen(@_) }
1898
1899 sub pp_readline {
1900     my $self = shift;
1901     my($op, $cx) = @_;
1902     my $kid = $op->first;
1903     $kid = $kid->first if $kid->name eq "rv2gv"; # <$fh>
1904     return "<" . $self->deparse($kid, 1) . ">" if is_scalar($kid);
1905     return $self->unop($op, $cx, "readline");
1906 }
1907
1908 sub pp_rcatline {
1909     my $self = shift;
1910     my($op) = @_;
1911     return "<" . $self->gv_name($self->gv_or_padgv($op)) . ">";
1912 }
1913
1914 # Unary operators that can occur as pseudo-listops inside double quotes
1915 sub dq_unop {
1916     my $self = shift;
1917     my($op, $cx, $name, $prec, $flags) = (@_, 0, 0);
1918     my $kid;
1919     if ($op->flags & OPf_KIDS) {
1920        $kid = $op->first;
1921        # If there's more than one kid, the first is an ex-pushmark.
1922        $kid = $kid->sibling if not null $kid->sibling;
1923        return $self->maybe_parens_unop($name, $kid, $cx);
1924     } else {
1925        return $name .  ($op->flags & OPf_SPECIAL ? "()" : "");
1926     }
1927 }
1928
1929 sub pp_ucfirst { dq_unop(@_, "ucfirst") }
1930 sub pp_lcfirst { dq_unop(@_, "lcfirst") }
1931 sub pp_uc { dq_unop(@_, "uc") }
1932 sub pp_lc { dq_unop(@_, "lc") }
1933 sub pp_quotemeta { maybe_targmy(@_, \&dq_unop, "quotemeta") }
1934
1935 sub loopex {
1936     my $self = shift;
1937     my ($op, $cx, $name) = @_;
1938     if (class($op) eq "PVOP") {
1939         return "$name " . $op->pv;
1940     } elsif (class($op) eq "OP") {
1941         return $name;
1942     } elsif (class($op) eq "UNOP") {
1943         # Note -- loop exits are actually exempt from the
1944         # looks-like-a-func rule, but a few extra parens won't hurt
1945         return $self->maybe_parens_unop($name, $op->first, $cx);
1946     }
1947 }
1948
1949 sub pp_last { loopex(@_, "last") }
1950 sub pp_next { loopex(@_, "next") }
1951 sub pp_redo { loopex(@_, "redo") }
1952 sub pp_goto { loopex(@_, "goto") }
1953 sub pp_dump { loopex(@_, "dump") }
1954
1955 sub ftst {
1956     my $self = shift;
1957     my($op, $cx, $name) = @_;
1958     if (class($op) eq "UNOP") {
1959         # Genuine `-X' filetests are exempt from the LLAFR, but not
1960         # l?stat(); for the sake of clarity, give'em all parens
1961         return $self->maybe_parens_unop($name, $op->first, $cx);
1962     } elsif (class($op) =~ /^(SV|PAD)OP$/) {
1963         return $self->maybe_parens_func($name, $self->pp_gv($op, 1), $cx, 16);
1964     } else { # I don't think baseop filetests ever survive ck_ftst, but...
1965         return $name;
1966     }
1967 }
1968
1969 sub pp_lstat    { ftst(@_, "lstat") }
1970 sub pp_stat     { ftst(@_, "stat") }
1971 sub pp_ftrread  { ftst(@_, "-R") }
1972 sub pp_ftrwrite { ftst(@_, "-W") }
1973 sub pp_ftrexec  { ftst(@_, "-X") }
1974 sub pp_fteread  { ftst(@_, "-r") }
1975 sub pp_ftewrite { ftst(@_, "-w") }
1976 sub pp_fteexec  { ftst(@_, "-x") }
1977 sub pp_ftis     { ftst(@_, "-e") }
1978 sub pp_fteowned { ftst(@_, "-O") }
1979 sub pp_ftrowned { ftst(@_, "-o") }
1980 sub pp_ftzero   { ftst(@_, "-z") }
1981 sub pp_ftsize   { ftst(@_, "-s") }
1982 sub pp_ftmtime  { ftst(@_, "-M") }
1983 sub pp_ftatime  { ftst(@_, "-A") }
1984 sub pp_ftctime  { ftst(@_, "-C") }
1985 sub pp_ftsock   { ftst(@_, "-S") }
1986 sub pp_ftchr    { ftst(@_, "-c") }
1987 sub pp_ftblk    { ftst(@_, "-b") }
1988 sub pp_ftfile   { ftst(@_, "-f") }
1989 sub pp_ftdir    { ftst(@_, "-d") }
1990 sub pp_ftpipe   { ftst(@_, "-p") }
1991 sub pp_ftlink   { ftst(@_, "-l") }
1992 sub pp_ftsuid   { ftst(@_, "-u") }
1993 sub pp_ftsgid   { ftst(@_, "-g") }
1994 sub pp_ftsvtx   { ftst(@_, "-k") }
1995 sub pp_fttty    { ftst(@_, "-t") }
1996 sub pp_fttext   { ftst(@_, "-T") }
1997 sub pp_ftbinary { ftst(@_, "-B") }
1998
1999 sub SWAP_CHILDREN () { 1 }
2000 sub ASSIGN () { 2 } # has OP= variant
2001 sub LIST_CONTEXT () { 4 } # Assignment is in list context
2002
2003 my(%left, %right);
2004
2005 sub assoc_class {
2006     my $op = shift;
2007     my $name = $op->name;
2008     if ($name eq "concat" and $op->first->name eq "concat") {
2009         # avoid spurious `=' -- see comment in pp_concat
2010         return "concat";
2011     }
2012     if ($name eq "null" and class($op) eq "UNOP"
2013         and $op->first->name =~ /^(and|x?or)$/
2014         and null $op->first->sibling)
2015     {
2016         # Like all conditional constructs, OP_ANDs and OP_ORs are topped
2017         # with a null that's used as the common end point of the two
2018         # flows of control. For precedence purposes, ignore it.
2019         # (COND_EXPRs have these too, but we don't bother with
2020         # their associativity).
2021         return assoc_class($op->first);
2022     }
2023     return $name . ($op->flags & OPf_STACKED ? "=" : "");
2024 }
2025
2026 # Left associative operators, like `+', for which
2027 # $a + $b + $c is equivalent to ($a + $b) + $c
2028
2029 BEGIN {
2030     %left = ('multiply' => 19, 'i_multiply' => 19,
2031              'divide' => 19, 'i_divide' => 19,
2032              'modulo' => 19, 'i_modulo' => 19,
2033              'repeat' => 19,
2034              'add' => 18, 'i_add' => 18,
2035              'subtract' => 18, 'i_subtract' => 18,
2036              'concat' => 18,
2037              'left_shift' => 17, 'right_shift' => 17,
2038              'bit_and' => 13,
2039              'bit_or' => 12, 'bit_xor' => 12,
2040              'and' => 3,
2041              'or' => 2, 'xor' => 2,
2042             );
2043 }
2044
2045 sub deparse_binop_left {
2046     my $self = shift;
2047     my($op, $left, $prec) = @_;
2048     if ($left{assoc_class($op)} && $left{assoc_class($left)}
2049         and $left{assoc_class($op)} == $left{assoc_class($left)})
2050     {
2051         return $self->deparse($left, $prec - .00001);
2052     } else {
2053         return $self->deparse($left, $prec);    
2054     }
2055 }
2056
2057 # Right associative operators, like `=', for which
2058 # $a = $b = $c is equivalent to $a = ($b = $c)
2059
2060 BEGIN {
2061     %right = ('pow' => 22,
2062               'sassign=' => 7, 'aassign=' => 7,
2063               'multiply=' => 7, 'i_multiply=' => 7,
2064               'divide=' => 7, 'i_divide=' => 7,
2065               'modulo=' => 7, 'i_modulo=' => 7,
2066               'repeat=' => 7,
2067               'add=' => 7, 'i_add=' => 7,
2068               'subtract=' => 7, 'i_subtract=' => 7,
2069               'concat=' => 7,
2070               'left_shift=' => 7, 'right_shift=' => 7,
2071               'bit_and=' => 7,
2072               'bit_or=' => 7, 'bit_xor=' => 7,
2073               'andassign' => 7,
2074               'orassign' => 7,
2075              );
2076 }
2077
2078 sub deparse_binop_right {
2079     my $self = shift;
2080     my($op, $right, $prec) = @_;
2081     if ($right{assoc_class($op)} && $right{assoc_class($right)}
2082         and $right{assoc_class($op)} == $right{assoc_class($right)})
2083     {
2084         return $self->deparse($right, $prec - .00001);
2085     } else {
2086         return $self->deparse($right, $prec);   
2087     }
2088 }
2089
2090 sub binop {
2091     my $self = shift;
2092     my ($op, $cx, $opname, $prec, $flags) = (@_, 0);
2093     my $left = $op->first;
2094     my $right = $op->last;
2095     my $eq = "";
2096     if ($op->flags & OPf_STACKED && $flags & ASSIGN) {
2097         $eq = "=";
2098         $prec = 7;
2099     }
2100     if ($flags & SWAP_CHILDREN) {
2101         ($left, $right) = ($right, $left);
2102     }
2103     $left = $self->deparse_binop_left($op, $left, $prec);
2104     $left = "($left)" if $flags & LIST_CONTEXT
2105                 && $left !~ /^(my|our|local|)[\@\(]/;
2106     $right = $self->deparse_binop_right($op, $right, $prec);
2107     return $self->maybe_parens("$left $opname$eq $right", $cx, $prec);
2108 }
2109
2110 sub pp_add { maybe_targmy(@_, \&binop, "+", 18, ASSIGN) }
2111 sub pp_multiply { maybe_targmy(@_, \&binop, "*", 19, ASSIGN) }
2112 sub pp_subtract { maybe_targmy(@_, \&binop, "-",18,  ASSIGN) }
2113 sub pp_divide { maybe_targmy(@_, \&binop, "/", 19, ASSIGN) }
2114 sub pp_modulo { maybe_targmy(@_, \&binop, "%", 19, ASSIGN) }
2115 sub pp_i_add { maybe_targmy(@_, \&binop, "+", 18, ASSIGN) }
2116 sub pp_i_multiply { maybe_targmy(@_, \&binop, "*", 19, ASSIGN) }
2117 sub pp_i_subtract { maybe_targmy(@_, \&binop, "-", 18, ASSIGN) }
2118 sub pp_i_divide { maybe_targmy(@_, \&binop, "/", 19, ASSIGN) }
2119 sub pp_i_modulo { maybe_targmy(@_, \&binop, "%", 19, ASSIGN) }
2120 sub pp_pow { maybe_targmy(@_, \&binop, "**", 22, ASSIGN) }
2121
2122 sub pp_left_shift { maybe_targmy(@_, \&binop, "<<", 17, ASSIGN) }
2123 sub pp_right_shift { maybe_targmy(@_, \&binop, ">>", 17, ASSIGN) }
2124 sub pp_bit_and { maybe_targmy(@_, \&binop, "&", 13, ASSIGN) }
2125 sub pp_bit_or { maybe_targmy(@_, \&binop, "|", 12, ASSIGN) }
2126 sub pp_bit_xor { maybe_targmy(@_, \&binop, "^", 12, ASSIGN) }
2127
2128 sub pp_eq { binop(@_, "==", 14) }
2129 sub pp_ne { binop(@_, "!=", 14) }
2130 sub pp_lt { binop(@_, "<", 15) }
2131 sub pp_gt { binop(@_, ">", 15) }
2132 sub pp_ge { binop(@_, ">=", 15) }
2133 sub pp_le { binop(@_, "<=", 15) }
2134 sub pp_ncmp { binop(@_, "<=>", 14) }
2135 sub pp_i_eq { binop(@_, "==", 14) }
2136 sub pp_i_ne { binop(@_, "!=", 14) }
2137 sub pp_i_lt { binop(@_, "<", 15) }
2138 sub pp_i_gt { binop(@_, ">", 15) }
2139 sub pp_i_ge { binop(@_, ">=", 15) }
2140 sub pp_i_le { binop(@_, "<=", 15) }
2141 sub pp_i_ncmp { binop(@_, "<=>", 14) }
2142
2143 sub pp_seq { binop(@_, "eq", 14) }
2144 sub pp_sne { binop(@_, "ne", 14) }
2145 sub pp_slt { binop(@_, "lt", 15) }
2146 sub pp_sgt { binop(@_, "gt", 15) }
2147 sub pp_sge { binop(@_, "ge", 15) }
2148 sub pp_sle { binop(@_, "le", 15) }
2149 sub pp_scmp { binop(@_, "cmp", 14) }
2150
2151 sub pp_sassign { binop(@_, "=", 7, SWAP_CHILDREN) }
2152 sub pp_aassign { binop(@_, "=", 7, SWAP_CHILDREN | LIST_CONTEXT) }
2153
2154 sub pp_smartmatch {
2155     my ($self, $op, $cx) = @_;
2156     if ($op->flags & OPf_SPECIAL) {
2157         return $self->deparse($op->last, $cx);
2158     }
2159     else {
2160         binop(@_, "~~", 14);
2161     }
2162 }
2163
2164 # `.' is special because concats-of-concats are optimized to save copying
2165 # by making all but the first concat stacked. The effect is as if the
2166 # programmer had written `($a . $b) .= $c', except legal.
2167 sub pp_concat { maybe_targmy(@_, \&real_concat) }
2168 sub real_concat {
2169     my $self = shift;
2170     my($op, $cx) = @_;
2171     my $left = $op->first;
2172     my $right = $op->last;
2173     my $eq = "";
2174     my $prec = 18;
2175     if ($op->flags & OPf_STACKED and $op->first->name ne "concat") {
2176         $eq = "=";
2177         $prec = 7;
2178     }
2179     $left = $self->deparse_binop_left($op, $left, $prec);
2180     $right = $self->deparse_binop_right($op, $right, $prec);
2181     return $self->maybe_parens("$left .$eq $right", $cx, $prec);
2182 }
2183
2184 # `x' is weird when the left arg is a list
2185 sub pp_repeat {
2186     my $self = shift;
2187     my($op, $cx) = @_;
2188     my $left = $op->first;
2189     my $right = $op->last;
2190     my $eq = "";
2191     my $prec = 19;
2192     if ($op->flags & OPf_STACKED) {
2193         $eq = "=";
2194         $prec = 7;
2195     }
2196     if (null($right)) { # list repeat; count is inside left-side ex-list
2197         my $kid = $left->first->sibling; # skip pushmark
2198         my @exprs;
2199         for (; !null($kid->sibling); $kid = $kid->sibling) {
2200             push @exprs, $self->deparse($kid, 6);
2201         }
2202         $right = $kid;
2203         $left = "(" . join(", ", @exprs). ")";
2204     } else {
2205         $left = $self->deparse_binop_left($op, $left, $prec);
2206     }
2207     $right = $self->deparse_binop_right($op, $right, $prec);
2208     return $self->maybe_parens("$left x$eq $right", $cx, $prec);
2209 }
2210
2211 sub range {
2212     my $self = shift;
2213     my ($op, $cx, $type) = @_;
2214     my $left = $op->first;
2215     my $right = $left->sibling;
2216     $left = $self->deparse($left, 9);
2217     $right = $self->deparse($right, 9);
2218     return $self->maybe_parens("$left $type $right", $cx, 9);
2219 }
2220
2221 sub pp_flop {
2222     my $self = shift;
2223     my($op, $cx) = @_;
2224     my $flip = $op->first;
2225     my $type = ($flip->flags & OPf_SPECIAL) ? "..." : "..";
2226     return $self->range($flip->first, $cx, $type);
2227 }
2228
2229 # one-line while/until is handled in pp_leave
2230
2231 sub logop {
2232     my $self = shift;
2233     my ($op, $cx, $lowop, $lowprec, $highop, $highprec, $blockname) = @_;
2234     my $left = $op->first;
2235     my $right = $op->first->sibling;
2236     if ($cx < 1 and is_scope($right) and $blockname
2237         and $self->{'expand'} < 7)
2238     { # if ($a) {$b}
2239         $left = $self->deparse($left, 1);
2240         $right = $self->deparse($right, 0);
2241         return "$blockname ($left) {\n\t$right\n\b}\cK";
2242     } elsif ($cx < 1 and $blockname and not $self->{'parens'}
2243              and $self->{'expand'} < 7) { # $b if $a
2244         $right = $self->deparse($right, 1);
2245         $left = $self->deparse($left, 1);
2246         return "$right $blockname $left";
2247     } elsif ($cx > $lowprec and $highop) { # $a && $b
2248         $left = $self->deparse_binop_left($op, $left, $highprec);
2249         $right = $self->deparse_binop_right($op, $right, $highprec);
2250         return $self->maybe_parens("$left $highop $right", $cx, $highprec);
2251     } else { # $a and $b
2252         $left = $self->deparse_binop_left($op, $left, $lowprec);
2253         $right = $self->deparse_binop_right($op, $right, $lowprec);
2254         return $self->maybe_parens("$left $lowop $right", $cx, $lowprec);
2255     }
2256 }
2257
2258 sub pp_and { logop(@_, "and", 3, "&&", 11, "if") }
2259 sub pp_or  { logop(@_, "or",  2, "||", 10, "unless") }
2260 sub pp_dor { logop(@_, "//", 10) }
2261
2262 # xor is syntactically a logop, but it's really a binop (contrary to
2263 # old versions of opcode.pl). Syntax is what matters here.
2264 sub pp_xor { logop(@_, "xor", 2, "",   0,  "") }
2265
2266 sub logassignop {
2267     my $self = shift;
2268     my ($op, $cx, $opname) = @_;
2269     my $left = $op->first;
2270     my $right = $op->first->sibling->first; # skip sassign
2271     $left = $self->deparse($left, 7);
2272     $right = $self->deparse($right, 7);
2273     return $self->maybe_parens("$left $opname $right", $cx, 7);
2274 }
2275
2276 sub pp_andassign { logassignop(@_, "&&=") }
2277 sub pp_orassign  { logassignop(@_, "||=") }
2278 sub pp_dorassign { logassignop(@_, "//=") }
2279
2280 sub listop {
2281     my $self = shift;
2282     my($op, $cx, $name) = @_;
2283     my(@exprs);
2284     my $parens = ($cx >= 5) || $self->{'parens'};
2285     my $kid = $op->first->sibling;
2286     return $name if null $kid;
2287     my $first;
2288     $name = "socketpair" if $name eq "sockpair";
2289     my $proto = prototype("CORE::$name");
2290     if (defined $proto
2291         && $proto =~ /^;?\*/
2292         && $kid->name eq "rv2gv") {
2293         $first = $self->deparse($kid->first, 6);
2294     }
2295     else {
2296         $first = $self->deparse($kid, 6);
2297     }
2298     if ($name eq "chmod" && $first =~ /^\d+$/) {
2299         $first = sprintf("%#o", $first);
2300     }
2301     $first = "+$first" if not $parens and substr($first, 0, 1) eq "(";
2302     push @exprs, $first;
2303     $kid = $kid->sibling;
2304     if (defined $proto && $proto =~ /^\*\*/ && $kid->name eq "rv2gv") {
2305         push @exprs, $self->deparse($kid->first, 6);
2306         $kid = $kid->sibling;
2307     }
2308     for (; !null($kid); $kid = $kid->sibling) {
2309         push @exprs, $self->deparse($kid, 6);
2310     }
2311     if ($name eq "reverse" && ($op->private & OPpREVERSE_INPLACE)) {
2312         return "$exprs[0] = $name" . ($parens ? "($exprs[0])" : " $exprs[0]");
2313     }
2314     if ($parens) {
2315         return "$name(" . join(", ", @exprs) . ")";
2316     } else {
2317         return "$name " . join(", ", @exprs);
2318     }
2319 }
2320
2321 sub pp_bless { listop(@_, "bless") }
2322 sub pp_atan2 { maybe_targmy(@_, \&listop, "atan2") }
2323 sub pp_substr { maybe_local(@_, listop(@_, "substr")) }
2324 sub pp_vec { maybe_local(@_, listop(@_, "vec")) }
2325 sub pp_index { maybe_targmy(@_, \&listop, "index") }
2326 sub pp_rindex { maybe_targmy(@_, \&listop, "rindex") }
2327 sub pp_sprintf { maybe_targmy(@_, \&listop, "sprintf") }
2328 sub pp_formline { listop(@_, "formline") } # see also deparse_format
2329 sub pp_crypt { maybe_targmy(@_, \&listop, "crypt") }
2330 sub pp_unpack { listop(@_, "unpack") }
2331 sub pp_pack { listop(@_, "pack") }
2332 sub pp_join { maybe_targmy(@_, \&listop, "join") }
2333 sub pp_splice { listop(@_, "splice") }
2334 sub pp_push { maybe_targmy(@_, \&listop, "push") }
2335 sub pp_unshift { maybe_targmy(@_, \&listop, "unshift") }
2336 sub pp_reverse { listop(@_, "reverse") }
2337 sub pp_warn { listop(@_, "warn") }
2338 sub pp_die { listop(@_, "die") }
2339 # Actually, return is exempt from the LLAFR (see examples in this very
2340 # module!), but for consistency's sake, ignore that fact
2341 sub pp_return { listop(@_, "return") }
2342 sub pp_open { listop(@_, "open") }
2343 sub pp_pipe_op { listop(@_, "pipe") }
2344 sub pp_tie { listop(@_, "tie") }
2345 sub pp_binmode { listop(@_, "binmode") }
2346 sub pp_dbmopen { listop(@_, "dbmopen") }
2347 sub pp_sselect { listop(@_, "select") }
2348 sub pp_select { listop(@_, "select") }
2349 sub pp_read { listop(@_, "read") }
2350 sub pp_sysopen { listop(@_, "sysopen") }
2351 sub pp_sysseek { listop(@_, "sysseek") }
2352 sub pp_sysread { listop(@_, "sysread") }
2353 sub pp_syswrite { listop(@_, "syswrite") }
2354 sub pp_send { listop(@_, "send") }
2355 sub pp_recv { listop(@_, "recv") }
2356 sub pp_seek { listop(@_, "seek") }
2357 sub pp_fcntl { listop(@_, "fcntl") }
2358 sub pp_ioctl { listop(@_, "ioctl") }
2359 sub pp_flock { maybe_targmy(@_, \&listop, "flock") }
2360 sub pp_socket { listop(@_, "socket") }
2361 sub pp_sockpair { listop(@_, "sockpair") }
2362 sub pp_bind { listop(@_, "bind") }
2363 sub pp_connect { listop(@_, "connect") }
2364 sub pp_listen { listop(@_, "listen") }
2365 sub pp_accept { listop(@_, "accept") }
2366 sub pp_shutdown { listop(@_, "shutdown") }
2367 sub pp_gsockopt { listop(@_, "getsockopt") }
2368 sub pp_ssockopt { listop(@_, "setsockopt") }
2369 sub pp_chown { maybe_targmy(@_, \&listop, "chown") }
2370 sub pp_unlink { maybe_targmy(@_, \&listop, "unlink") }
2371 sub pp_chmod { maybe_targmy(@_, \&listop, "chmod") }
2372 sub pp_utime { maybe_targmy(@_, \&listop, "utime") }
2373 sub pp_rename { maybe_targmy(@_, \&listop, "rename") }
2374 sub pp_link { maybe_targmy(@_, \&listop, "link") }
2375 sub pp_symlink { maybe_targmy(@_, \&listop, "symlink") }
2376 sub pp_mkdir { maybe_targmy(@_, \&listop, "mkdir") }
2377 sub pp_open_dir { listop(@_, "opendir") }
2378 sub pp_seekdir { listop(@_, "seekdir") }
2379 sub pp_waitpid { maybe_targmy(@_, \&listop, "waitpid") }
2380 sub pp_system { maybe_targmy(@_, \&listop, "system") }
2381 sub pp_exec { maybe_targmy(@_, \&listop, "exec") }
2382 sub pp_kill { maybe_targmy(@_, \&listop, "kill") }
2383 sub pp_setpgrp { maybe_targmy(@_, \&listop, "setpgrp") }
2384 sub pp_getpriority { maybe_targmy(@_, \&listop, "getpriority") }
2385 sub pp_setpriority { maybe_targmy(@_, \&listop, "setpriority") }
2386 sub pp_shmget { listop(@_, "shmget") }
2387 sub pp_shmctl { listop(@_, "shmctl") }
2388 sub pp_shmread { listop(@_, "shmread") }
2389 sub pp_shmwrite { listop(@_, "shmwrite") }
2390 sub pp_msgget { listop(@_, "msgget") }
2391 sub pp_msgctl { listop(@_, "msgctl") }
2392 sub pp_msgsnd { listop(@_, "msgsnd") }
2393 sub pp_msgrcv { listop(@_, "msgrcv") }
2394 sub pp_semget { listop(@_, "semget") }
2395 sub pp_semctl { listop(@_, "semctl") }
2396 sub pp_semop { listop(@_, "semop") }
2397 sub pp_ghbyaddr { listop(@_, "gethostbyaddr") }
2398 sub pp_gnbyaddr { listop(@_, "getnetbyaddr") }
2399 sub pp_gpbynumber { listop(@_, "getprotobynumber") }
2400 sub pp_gsbyname { listop(@_, "getservbyname") }
2401 sub pp_gsbyport { listop(@_, "getservbyport") }
2402 sub pp_syscall { listop(@_, "syscall") }
2403
2404 sub pp_glob {
2405     my $self = shift;
2406     my($op, $cx) = @_;
2407     my $text = $self->dq($op->first->sibling);  # skip pushmark
2408     if ($text =~ /^\$?(\w|::|\`)+$/ # could look like a readline
2409         or $text =~ /[<>]/) {
2410         return 'glob(' . single_delim('qq', '"', $text) . ')';
2411     } else {
2412         return '<' . $text . '>';
2413     }
2414 }
2415
2416 # Truncate is special because OPf_SPECIAL makes a bareword first arg
2417 # be a filehandle. This could probably be better fixed in the core
2418 # by moving the GV lookup into ck_truc.
2419
2420 sub pp_truncate {
2421     my $self = shift;
2422     my($op, $cx) = @_;
2423     my(@exprs);
2424     my $parens = ($cx >= 5) || $self->{'parens'};
2425     my $kid = $op->first->sibling;
2426     my $fh;
2427     if ($op->flags & OPf_SPECIAL) {
2428         # $kid is an OP_CONST
2429         $fh = $self->const_sv($kid)->PV;
2430     } else {
2431         $fh = $self->deparse($kid, 6);
2432         $fh = "+$fh" if not $parens and substr($fh, 0, 1) eq "(";
2433     }
2434     my $len = $self->deparse($kid->sibling, 6);
2435     if ($parens) {
2436         return "truncate($fh, $len)";
2437     } else {
2438         return "truncate $fh, $len";
2439     }
2440 }
2441
2442 sub indirop {
2443     my $self = shift;
2444     my($op, $cx, $name) = @_;
2445     my($expr, @exprs);
2446     my $kid = $op->first->sibling;
2447     my $indir = "";
2448     if ($op->flags & OPf_STACKED) {
2449         $indir = $kid;
2450         $indir = $indir->first; # skip rv2gv
2451         if (is_scope($indir)) {
2452             $indir = "{" . $self->deparse($indir, 0) . "}";
2453             $indir = "{;}" if $indir eq "{}";
2454         } elsif ($indir->name eq "const" && $indir->private & OPpCONST_BARE) {
2455             $indir = $self->const_sv($indir)->PV;
2456         } else {
2457             $indir = $self->deparse($indir, 24);
2458         }
2459         $indir = $indir . " ";
2460         $kid = $kid->sibling;
2461     }
2462     if ($name eq "sort" && $op->private & (OPpSORT_NUMERIC | OPpSORT_INTEGER)) {
2463         $indir = ($op->private & OPpSORT_DESCEND) ? '{$b <=> $a} '
2464                                                   : '{$a <=> $b} ';
2465     }
2466     elsif ($name eq "sort" && $op->private & OPpSORT_DESCEND) {
2467         $indir = '{$b cmp $a} ';
2468     }
2469     for (; !null($kid); $kid = $kid->sibling) {
2470         $expr = $self->deparse($kid, 6);
2471         push @exprs, $expr;
2472     }
2473     my $name2 = $name;
2474     if ($name eq "sort" && $op->private & OPpSORT_REVERSE) {
2475         $name2 = 'reverse sort';
2476     }
2477     if ($name eq "sort" && ($op->private & OPpSORT_INPLACE)) {
2478         return "$exprs[0] = $name2 $indir $exprs[0]";
2479     }
2480
2481     my $args = $indir . join(", ", @exprs);
2482     if ($indir ne "" and $name eq "sort") {
2483         # We don't want to say "sort(f 1, 2, 3)", since perl -w will
2484         # give bareword warnings in that case. Therefore if context
2485         # requires, we'll put parens around the outside "(sort f 1, 2,
2486         # 3)". Unfortunately, we'll currently think the parens are
2487         # necessary more often that they really are, because we don't
2488         # distinguish which side of an assignment we're on.
2489         if ($cx >= 5) {
2490             return "($name2 $args)";
2491         } else {
2492             return "$name2 $args";
2493         }
2494     } else {
2495         return $self->maybe_parens_func($name2, $args, $cx, 5);
2496     }
2497
2498 }
2499
2500 sub pp_prtf { indirop(@_, "printf") }
2501 sub pp_print { indirop(@_, "print") }
2502 sub pp_say  { indirop(@_, "say") }
2503 sub pp_sort { indirop(@_, "sort") }
2504
2505 sub mapop {
2506     my $self = shift;
2507     my($op, $cx, $name) = @_;
2508     my($expr, @exprs);
2509     my $kid = $op->first; # this is the (map|grep)start
2510     $kid = $kid->first->sibling; # skip a pushmark
2511     my $code = $kid->first; # skip a null
2512     if (is_scope $code) {
2513         $code = "{" . $self->deparse($code, 0) . "} ";
2514     } else {
2515         $code = $self->deparse($code, 24) . ", ";
2516     }
2517     $kid = $kid->sibling;
2518     for (; !null($kid); $kid = $kid->sibling) {
2519         $expr = $self->deparse($kid, 6);
2520         push @exprs, $expr if defined $expr;
2521     }
2522     return $self->maybe_parens_func($name, $code . join(", ", @exprs), $cx, 5);
2523 }
2524
2525 sub pp_mapwhile { mapop(@_, "map") }
2526 sub pp_grepwhile { mapop(@_, "grep") }
2527 sub pp_mapstart { baseop(@_, "map") }
2528 sub pp_grepstart { baseop(@_, "grep") }
2529
2530 sub pp_list {
2531     my $self = shift;
2532     my($op, $cx) = @_;
2533     my($expr, @exprs);
2534     my $kid = $op->first->sibling; # skip pushmark
2535     my $lop;
2536     my $local = "either"; # could be local(...), my(...), state(...) or our(...)
2537     for ($lop = $kid; !null($lop); $lop = $lop->sibling) {
2538         # This assumes that no other private flags equal 128, and that
2539         # OPs that store things other than flags in their op_private,
2540         # like OP_AELEMFAST, won't be immediate children of a list.
2541         #
2542         # OP_ENTERSUB can break this logic, so check for it.
2543         # I suspect that open and exit can too.
2544
2545         if (!($lop->private & (OPpLVAL_INTRO|OPpOUR_INTRO)
2546                 or $lop->name eq "undef")
2547             or $lop->name eq "entersub"
2548             or $lop->name eq "exit"
2549             or $lop->name eq "open")
2550         {
2551             $local = ""; # or not
2552             last;
2553         }
2554         if ($lop->name =~ /^pad[ash]v$/) {
2555             if ($lop->private & OPpPAD_STATE) { # state()
2556                 ($local = "", last) if $local =~ /^(?:local|our|my)$/;
2557                 $local = "state";
2558             } else { # my()
2559                 ($local = "", last) if $local =~ /^(?:local|our|state)$/;
2560                 $local = "my";
2561             }
2562         } elsif ($lop->name =~ /^(gv|rv2)[ash]v$/
2563                         && $lop->private & OPpOUR_INTRO
2564                 or $lop->name eq "null" && $lop->first->name eq "gvsv"
2565                         && $lop->first->private & OPpOUR_INTRO) { # our()
2566             ($local = "", last) if $local =~ /^(?:my|local|state)$/;
2567             $local = "our";
2568         } elsif ($lop->name ne "undef"
2569                 # specifically avoid the "reverse sort" optimisation,
2570                 # where "reverse" is nullified
2571                 && !($lop->name eq 'sort' && ($lop->flags & OPpSORT_REVERSE)))
2572         {
2573             # local()
2574             ($local = "", last) if $local =~ /^(?:my|our|state)$/;
2575             $local = "local";
2576         }
2577     }
2578     $local = "" if $local eq "either"; # no point if it's all undefs
2579     return $self->deparse($kid, $cx) if null $kid->sibling and not $local;
2580     for (; !null($kid); $kid = $kid->sibling) {
2581         if ($local) {
2582             if (class($kid) eq "UNOP" and $kid->first->name eq "gvsv") {
2583                 $lop = $kid->first;
2584             } else {
2585                 $lop = $kid;
2586             }
2587             $self->{'avoid_local'}{$$lop}++;
2588             $expr = $self->deparse($kid, 6);
2589             delete $self->{'avoid_local'}{$$lop};
2590         } else {
2591             $expr = $self->deparse($kid, 6);
2592         }
2593         push @exprs, $expr;
2594     }
2595     if ($local) {
2596         return "$local(" . join(", ", @exprs) . ")";
2597     } else {
2598         return $self->maybe_parens( join(", ", @exprs), $cx, 6);        
2599     }
2600 }
2601
2602 sub is_ifelse_cont {
2603     my $op = shift;
2604     return ($op->name eq "null" and class($op) eq "UNOP"
2605             and $op->first->name =~ /^(and|cond_expr)$/
2606             and is_scope($op->first->first->sibling));
2607 }
2608
2609 sub pp_cond_expr {
2610     my $self = shift;
2611     my($op, $cx) = @_;
2612     my $cond = $op->first;
2613     my $true = $cond->sibling;
2614     my $false = $true->sibling;
2615     my $cuddle = $self->{'cuddle'};
2616     unless ($cx < 1 and (is_scope($true) and $true->name ne "null") and
2617             (is_scope($false) || is_ifelse_cont($false))
2618             and $self->{'expand'} < 7) {
2619         $cond = $self->deparse($cond, 8);
2620         $true = $self->deparse($true, 6);
2621         $false = $self->deparse($false, 8);
2622         return $self->maybe_parens("$cond ? $true : $false", $cx, 8);
2623     }
2624
2625     $cond = $self->deparse($cond, 1);
2626     $true = $self->deparse($true, 0);
2627     my $head = "if ($cond) {\n\t$true\n\b}";
2628     my @elsifs;
2629     while (!null($false) and is_ifelse_cont($false)) {
2630         my $newop = $false->first;
2631         my $newcond = $newop->first;
2632         my $newtrue = $newcond->sibling;
2633         $false = $newtrue->sibling; # last in chain is OP_AND => no else
2634         if ($newcond->name eq "lineseq")
2635         {
2636             # lineseq to ensure correct line numbers in elsif()
2637             # Bug #37302 fixed by change #33710.
2638             $newcond = $newcond->first->sibling;
2639         }
2640         $newcond = $self->deparse($newcond, 1);
2641         $newtrue = $self->deparse($newtrue, 0);
2642         push @elsifs, "elsif ($newcond) {\n\t$newtrue\n\b}";
2643     }
2644     if (!null($false)) {
2645         $false = $cuddle . "else {\n\t" .
2646           $self->deparse($false, 0) . "\n\b}\cK";
2647     } else {
2648         $false = "\cK";
2649     }
2650     return $head . join($cuddle, "", @elsifs) . $false;
2651 }
2652
2653 sub pp_once {
2654     my ($self, $op, $cx) = @_;
2655     my $cond = $op->first;
2656     my $true = $cond->sibling;
2657
2658     return $self->deparse($true, $cx);
2659 }
2660
2661 sub loop_common {
2662     my $self = shift;
2663     my($op, $cx, $init) = @_;
2664     my $enter = $op->first;
2665     my $kid = $enter->sibling;
2666     local(@$self{qw'curstash warnings hints hinthash'})
2667                 = @$self{qw'curstash warnings hints hinthash'};
2668     my $head = "";
2669     my $bare = 0;
2670     my $body;
2671     my $cond = undef;
2672     if ($kid->name eq "lineseq") { # bare or infinite loop
2673         if ($kid->last->name eq "unstack") { # infinite
2674             $head = "while (1) "; # Can't use for(;;) if there's a continue
2675             $cond = "";
2676         } else {
2677             $bare = 1;
2678         }
2679         $body = $kid;
2680     } elsif ($enter->name eq "enteriter") { # foreach
2681         my $ary = $enter->first->sibling; # first was pushmark
2682         my $var = $ary->sibling;
2683         if ($ary->name eq 'null' and $enter->private & OPpITER_REVERSED) {
2684             # "reverse" was optimised away
2685             $ary = listop($self, $ary->first->sibling, 1, 'reverse');
2686         } elsif ($enter->flags & OPf_STACKED
2687             and not null $ary->first->sibling->sibling)
2688         {
2689             $ary = $self->deparse($ary->first->sibling, 9) . " .. " .
2690               $self->deparse($ary->first->sibling->sibling, 9);
2691         } else {
2692             $ary = $self->deparse($ary, 1);
2693         }
2694         if (null $var) {
2695             if ($enter->flags & OPf_SPECIAL) { # thread special var
2696                 $var = $self->pp_threadsv($enter, 1);
2697             } else { # regular my() variable
2698                 $var = $self->pp_padsv($enter, 1);
2699             }
2700         } elsif ($var->name eq "rv2gv") {
2701             $var = $self->pp_rv2sv($var, 1);
2702             if ($enter->private & OPpOUR_INTRO) {
2703                 # our declarations don't have package names
2704                 $var =~ s/^(.).*::/$1/;
2705                 $var = "our $var";
2706             }
2707         } elsif ($var->name eq "gv") {
2708             $var = "\$" . $self->deparse($var, 1);
2709         }
2710         $body = $kid->first->first->sibling; # skip OP_AND and OP_ITER
2711         if (!is_state $body->first and $body->first->name ne "stub") {
2712             confess unless $var eq '$_';
2713             $body = $body->first;
2714             return $self->deparse($body, 2) . " foreach ($ary)";
2715         }
2716         $head = "foreach $var ($ary) ";
2717     } elsif ($kid->name eq "null") { # while/until
2718         $kid = $kid->first;
2719         my $name = {"and" => "while", "or" => "until"}->{$kid->name};
2720         $cond = $self->deparse($kid->first, 1);
2721         $head = "$name ($cond) ";
2722         $body = $kid->first->sibling;
2723     } elsif ($kid->name eq "stub") { # bare and empty
2724         return "{;}"; # {} could be a hashref
2725     }
2726     # If there isn't a continue block, then the next pointer for the loop
2727     # will point to the unstack, which is kid's last child, except
2728     # in a bare loop, when it will point to the leaveloop. When neither of
2729     # these conditions hold, then the second-to-last child is the continue
2730     # block (or the last in a bare loop).
2731     my $cont_start = $enter->nextop;
2732     my $cont;
2733     if ($$cont_start != $$op && ${$cont_start} != ${$body->last}) {
2734         if ($bare) {
2735             $cont = $body->last;
2736         } else {
2737             $cont = $body->first;
2738             while (!null($cont->sibling->sibling)) {
2739                 $cont = $cont->sibling;
2740             }
2741         }
2742         my $state = $body->first;
2743         my $cuddle = $self->{'cuddle'};
2744         my @states;
2745         for (; $$state != $$cont; $state = $state->sibling) {
2746             push @states, $state;
2747         }
2748         $body = $self->lineseq(undef, @states);
2749         if (defined $cond and not is_scope $cont and $self->{'expand'} < 3) {
2750             $head = "for ($init; $cond; " . $self->deparse($cont, 1) .") ";
2751             $cont = "\cK";
2752         } else {
2753             $cont = $cuddle . "continue {\n\t" .
2754               $self->deparse($cont, 0) . "\n\b}\cK";
2755         }
2756     } else {
2757         return "" if !defined $body;
2758         if (length $init) {
2759             $head = "for ($init; $cond;) ";
2760         }
2761         $cont = "\cK";
2762         $body = $self->deparse($body, 0);
2763     }
2764     $body =~ s/;?$/;\n/;
2765
2766     return $head . "{\n\t" . $body . "\b}" . $cont;
2767 }
2768
2769 sub pp_leaveloop { shift->loop_common(@_, "") }
2770
2771 sub for_loop {
2772     my $self = shift;
2773     my($op, $cx) = @_;
2774     my $init = $self->deparse($op, 1);
2775     my $s = $op->sibling;
2776     my $ll = $s->name eq "unstack" ? $s->sibling : $s->first->sibling;
2777     return $self->loop_common($ll, $cx, $init);
2778 }
2779
2780 sub pp_leavetry {
2781     my $self = shift;
2782     return "eval {\n\t" . $self->pp_leave(@_) . "\n\b}";
2783 }
2784
2785 BEGIN { eval "sub OP_CONST () {" . opnumber("const") . "}" }
2786 BEGIN { eval "sub OP_STRINGIFY () {" . opnumber("stringify") . "}" }
2787 BEGIN { eval "sub OP_RV2SV () {" . opnumber("rv2sv") . "}" }
2788 BEGIN { eval "sub OP_LIST () {" . opnumber("list") . "}" }
2789
2790 sub pp_null {
2791     my $self = shift;
2792     my($op, $cx) = @_;
2793     if (class($op) eq "OP") {
2794         # old value is lost
2795         return $self->{'ex_const'} if $op->targ == OP_CONST;
2796     } elsif ($op->first->name eq "pushmark") {
2797         return $self->pp_list($op, $cx);
2798     } elsif ($op->first->name eq "enter") {
2799         return $self->pp_leave($op, $cx);
2800     } elsif ($op->first->name eq "leave") {
2801         return $self->pp_leave($op->first, $cx);
2802     } elsif ($op->first->name eq "scope") {
2803         return $self->pp_scope($op->first, $cx);
2804     } elsif ($op->targ == OP_STRINGIFY) {
2805         return $self->dquote($op, $cx);
2806     } elsif (!null($op->first->sibling) and
2807              $op->first->sibling->name eq "readline" and
2808              $op->first->sibling->flags & OPf_STACKED) {
2809         return $self->maybe_parens($self->deparse($op->first, 7) . " = "
2810                                    . $self->deparse($op->first->sibling, 7),
2811                                    $cx, 7);
2812     } elsif (!null($op->first->sibling) and
2813              $op->first->sibling->name eq "trans" and
2814              $op->first->sibling->flags & OPf_STACKED) {
2815         return $self->maybe_parens($self->deparse($op->first, 20) . " =~ "
2816                                    . $self->deparse($op->first->sibling, 20),
2817                                    $cx, 20);
2818     } elsif ($op->flags & OPf_SPECIAL && $cx < 1 && !$op->targ) {
2819         return "do {\n\t". $self->deparse($op->first, $cx) ."\n\b};";
2820     } elsif (!null($op->first->sibling) and
2821              $op->first->sibling->name eq "null" and
2822              class($op->first->sibling) eq "UNOP" and
2823              $op->first->sibling->first->flags & OPf_STACKED and
2824              $op->first->sibling->first->name eq "rcatline") {
2825         return $self->maybe_parens($self->deparse($op->first, 18) . " .= "
2826                                    . $self->deparse($op->first->sibling, 18),
2827                                    $cx, 18);
2828     } else {
2829         return $self->deparse($op->first, $cx);
2830     }
2831 }
2832
2833 sub padname {
2834     my $self = shift;
2835     my $targ = shift;
2836     return $self->padname_sv($targ)->PVX;
2837 }
2838
2839 sub padany {
2840     my $self = shift;
2841     my $op = shift;
2842     return substr($self->padname($op->targ), 1); # skip $/@/%
2843 }
2844
2845 sub pp_padsv {
2846     my $self = shift;
2847     my($op, $cx) = @_;
2848     return $self->maybe_my($op, $cx, $self->padname($op->targ));
2849 }
2850
2851 sub pp_padav { pp_padsv(@_) }
2852 sub pp_padhv { pp_padsv(@_) }
2853
2854 my @threadsv_names;
2855
2856 BEGIN {
2857     @threadsv_names = ("_", "1", "2", "3", "4", "5", "6", "7", "8", "9",
2858                        "&", "`", "'", "+", "/", ".", ",", "\\", '"', ";",
2859                        "^", "-", "%", "=", "|", "~", ":", "^A", "^E",
2860                        "!", "@");
2861 }
2862
2863 sub pp_threadsv {
2864     my $self = shift;
2865     my($op, $cx) = @_;
2866     return $self->maybe_local($op, $cx, "\$" .  $threadsv_names[$op->targ]);
2867 }
2868
2869 sub gv_or_padgv {
2870     my $self = shift;
2871     my $op = shift;
2872     if (class($op) eq "PADOP") {
2873         return $self->padval($op->padix);
2874     } else { # class($op) eq "SVOP"
2875         return $op->gv;
2876     }
2877 }
2878
2879 sub pp_gvsv {
2880     my $self = shift;
2881     my($op, $cx) = @_;
2882     my $gv = $self->gv_or_padgv($op);
2883     return $self->maybe_local($op, $cx, $self->stash_variable("\$",
2884                                  $self->gv_name($gv)));
2885 }
2886
2887 sub pp_gv {
2888     my $self = shift;
2889     my($op, $cx) = @_;
2890     my $gv = $self->gv_or_padgv($op);
2891     return $self->gv_name($gv);
2892 }
2893
2894 sub pp_aelemfast {
2895     my $self = shift;
2896     my($op, $cx) = @_;
2897     my $name;
2898     if ($op->flags & OPf_SPECIAL) { # optimised PADAV
2899         $name = $self->padname($op->targ);
2900         $name =~ s/^@/\$/;
2901     }
2902     else {
2903         my $gv = $self->gv_or_padgv($op);
2904         $name = $self->gv_name($gv);
2905         $name = $self->{'curstash'}."::$name"
2906             if $name !~ /::/ && $self->lex_in_scope('@'.$name);
2907         $name = '$' . $name;
2908     }
2909
2910     return $name . "[" .  ($op->private + $self->{'arybase'}) . "]";
2911 }
2912
2913 sub rv2x {
2914     my $self = shift;
2915     my($op, $cx, $type) = @_;
2916
2917     if (class($op) eq 'NULL' || !$op->can("first")) {
2918         carp("Unexpected op in pp_rv2x");
2919         return 'XXX';
2920     }
2921     my $kid = $op->first;
2922     if ($kid->name eq "gv") {
2923         return $self->stash_variable($type, $self->deparse($kid, 0));
2924     } elsif (is_scalar $kid) {
2925         my $str = $self->deparse($kid, 0);
2926         if ($str =~ /^\$([^\w\d])\z/) {
2927             # "$$+" isn't a legal way to write the scalar dereference
2928             # of $+, since the lexer can't tell you aren't trying to
2929             # do something like "$$ + 1" to get one more than your
2930             # PID. Either "${$+}" or "$${+}" are workable
2931             # disambiguations, but if the programmer did the former,
2932             # they'd be in the "else" clause below rather than here.
2933             # It's not clear if this should somehow be unified with
2934             # the code in dq and re_dq that also adds lexer
2935             # disambiguation braces.
2936             $str = '$' . "{$1}"; #'
2937         }
2938         return $type . $str;
2939     } else {
2940         return $type . "{" . $self->deparse($kid, 0) . "}";
2941     }
2942 }
2943
2944 sub pp_rv2sv { maybe_local(@_, rv2x(@_, "\$")) }
2945 sub pp_rv2hv { maybe_local(@_, rv2x(@_, "%")) }
2946 sub pp_rv2gv { maybe_local(@_, rv2x(@_, "*")) }
2947
2948 # skip rv2av
2949 sub pp_av2arylen {
2950     my $self = shift;
2951     my($op, $cx) = @_;
2952     if ($op->first->name eq "padav") {
2953         return $self->maybe_local($op, $cx, '$#' . $self->padany($op->first));
2954     } else {
2955         return $self->maybe_local($op, $cx,
2956                                   $self->rv2x($op->first, $cx, '$#'));
2957     }
2958 }
2959
2960 # skip down to the old, ex-rv2cv
2961 sub pp_rv2cv {
2962     my ($self, $op, $cx) = @_;
2963     if (!null($op->first) && $op->first->name eq 'null' &&
2964         $op->first->targ eq OP_LIST)
2965     {
2966         return $self->rv2x($op->first->first->sibling, $cx, "&")
2967     }
2968     else {
2969         return $self->rv2x($op, $cx, "")
2970     }
2971 }
2972
2973 sub list_const {
2974     my $self = shift;
2975     my($cx, @list) = @_;
2976     my @a = map $self->const($_, 6), @list;
2977     if (@a == 0) {
2978         return "()";
2979     } elsif (@a == 1) {
2980         return $a[0];
2981     } elsif ( @a > 2 and !grep(!/^-?\d+$/, @a)) {
2982         # collapse (-1,0,1,2) into (-1..2)
2983         my ($s, $e) = @a[0,-1];
2984         my $i = $s;
2985         return $self->maybe_parens("$s..$e", $cx, 9)
2986           unless grep $i++ != $_, @a;
2987     }
2988     return $self->maybe_parens(join(", ", @a), $cx, 6);
2989 }
2990
2991 sub pp_rv2av {
2992     my $self = shift;
2993     my($op, $cx) = @_;
2994     my $kid = $op->first;
2995     if ($kid->name eq "const") { # constant list
2996         my $av = $self->const_sv($kid);
2997         return $self->list_const($cx, $av->ARRAY);
2998     } else {
2999         return $self->maybe_local($op, $cx, $self->rv2x($op, $cx, "\@"));
3000     }
3001  }
3002
3003 sub is_subscriptable {
3004     my $op = shift;
3005     if ($op->name =~ /^[ahg]elem/) {
3006         return 1;
3007     } elsif ($op->name eq "entersub") {
3008         my $kid = $op->first;
3009         return 0 unless null $kid->sibling;
3010         $kid = $kid->first;
3011         $kid = $kid->sibling until null $kid->sibling;
3012         return 0 if is_scope($kid);
3013         $kid = $kid->first;
3014         return 0 if $kid->name eq "gv";
3015         return 0 if is_scalar($kid);
3016         return is_subscriptable($kid);  
3017     } else {
3018         return 0;
3019     }
3020 }
3021
3022 sub elem_or_slice_array_name
3023 {
3024     my $self = shift;
3025     my ($array, $left, $padname, $allow_arrow) = @_;
3026
3027     if ($array->name eq $padname) {
3028         return $self->padany($array);
3029     } elsif (is_scope($array)) { # ${expr}[0]
3030         return "{" . $self->deparse($array, 0) . "}";
3031     } elsif ($array->name eq "gv") {
3032         $array = $self->gv_name($self->gv_or_padgv($array));
3033         if ($array !~ /::/) {
3034             my $prefix = ($left eq '[' ? '@' : '%');
3035             $array = $self->{curstash}.'::'.$array
3036                 if $self->lex_in_scope($prefix . $array);
3037         }
3038         return $array;
3039     } elsif (!$allow_arrow || is_scalar $array) { # $x[0], $$x[0], ...
3040         return $self->deparse($array, 24);
3041     } else {
3042         return undef;
3043     }
3044 }
3045
3046 sub elem_or_slice_single_index
3047 {
3048     my $self = shift;
3049     my ($idx) = @_;
3050
3051     $idx = $self->deparse($idx, 1);
3052
3053     # Outer parens in an array index will confuse perl
3054     # if we're interpolating in a regular expression, i.e.
3055     # /$x$foo[(-1)]/ is *not* the same as /$x$foo[-1]/
3056     #
3057     # If $self->{parens}, then an initial '(' will
3058     # definitely be paired with a final ')'. If
3059     # !$self->{parens}, the misleading parens won't
3060     # have been added in the first place.
3061     #
3062     # [You might think that we could get "(...)...(...)"
3063     # where the initial and final parens do not match
3064     # each other. But we can't, because the above would
3065     # only happen if there's an infix binop between the
3066     # two pairs of parens, and *that* means that the whole
3067     # expression would be parenthesized as well.]
3068     #
3069     $idx =~ s/^\((.*)\)$/$1/ if $self->{'parens'};
3070
3071     # Hash-element braces will autoquote a bareword inside themselves.
3072     # We need to make sure that C<$hash{warn()}> doesn't come out as
3073     # C<$hash{warn}>, which has a quite different meaning. Currently
3074     # B::Deparse will always quote strings, even if the string was a
3075     # bareword in the original (i.e. the OPpCONST_BARE flag is ignored
3076     # for constant strings.) So we can cheat slightly here - if we see
3077     # a bareword, we know that it is supposed to be a function call.
3078     #
3079     $idx =~ s/^([A-Za-z_]\w*)$/$1()/;
3080
3081     return $idx;
3082 }
3083
3084 sub elem {
3085     my $self = shift;
3086     my ($op, $cx, $left, $right, $padname) = @_;
3087     my($array, $idx) = ($op->first, $op->first->sibling);
3088
3089     $idx = $self->elem_or_slice_single_index($idx);
3090
3091     unless ($array->name eq $padname) { # Maybe this has been fixed     
3092         $array = $array->first; # skip rv2av (or ex-rv2av in _53+)
3093     }
3094     if (my $array_name=$self->elem_or_slice_array_name
3095             ($array, $left, $padname, 1)) {
3096         return "\$" . $array_name . $left . $idx . $right;
3097     } else {
3098         # $x[20][3]{hi} or expr->[20]
3099         my $arrow = is_subscriptable($array) ? "" : "->";
3100         return $self->deparse($array, 24) . $arrow . $left . $idx . $right;
3101     }
3102
3103 }
3104
3105 sub pp_aelem { maybe_local(@_, elem(@_, "[", "]", "padav")) }
3106 sub pp_helem { maybe_local(@_, elem(@_, "{", "}", "padhv")) }
3107
3108 sub pp_gelem {
3109     my $self = shift;
3110     my($op, $cx) = @_;
3111     my($glob, $part) = ($op->first, $op->last);
3112     $glob = $glob->first; # skip rv2gv
3113     $glob = $glob->first if $glob->name eq "rv2gv"; # this one's a bug
3114     my $scope = is_scope($glob);
3115     $glob = $self->deparse($glob, 0);
3116     $part = $self->deparse($part, 1);
3117     return "*" . ($scope ? "{$glob}" : $glob) . "{$part}";
3118 }
3119
3120 sub slice {
3121     my $self = shift;
3122     my ($op, $cx, $left, $right, $regname, $padname) = @_;
3123     my $last;
3124     my(@elems, $kid, $array, $list);
3125     if (class($op) eq "LISTOP") {
3126         $last = $op->last;
3127     } else { # ex-hslice inside delete()
3128         for ($kid = $op->first; !null $kid->sibling; $kid = $kid->sibling) {}
3129         $last = $kid;
3130     }
3131     $array = $last;
3132     $array = $array->first
3133         if $array->name eq $regname or $array->name eq "null";
3134     $array = $self->elem_or_slice_array_name($array,$left,$padname,0);
3135     $kid = $op->first->sibling; # skip pushmark
3136     if ($kid->name eq "list") {
3137         $kid = $kid->first->sibling; # skip list, pushmark
3138         for (; !null $kid; $kid = $kid->sibling) {
3139             push @elems, $self->deparse($kid, 6);
3140         }
3141         $list = join(", ", @elems);
3142     } else {
3143         $list = $self->elem_or_slice_single_index($kid);
3144     }
3145     return "\@" . $array . $left . $list . $right;
3146 }
3147
3148 sub pp_aslice { maybe_local(@_, slice(@_, "[", "]", "rv2av", "padav")) }
3149 sub pp_hslice { maybe_local(@_, slice(@_, "{", "}", "rv2hv", "padhv")) }
3150
3151 sub pp_lslice {
3152     my $self = shift;
3153     my($op, $cx) = @_;
3154     my $idx = $op->first;
3155     my $list = $op->last;
3156     my(@elems, $kid);
3157     $list = $self->deparse($list, 1);
3158     $idx = $self->deparse($idx, 1);
3159     return "($list)" . "[$idx]";
3160 }
3161
3162 sub want_scalar {
3163     my $op = shift;
3164     return ($op->flags & OPf_WANT) == OPf_WANT_SCALAR;
3165 }
3166
3167 sub want_list {
3168     my $op = shift;
3169     return ($op->flags & OPf_WANT) == OPf_WANT_LIST;
3170 }
3171
3172 sub _method {
3173     my $self = shift;
3174     my($op, $cx) = @_;
3175     my $kid = $op->first->sibling; # skip pushmark
3176     my($meth, $obj, @exprs);
3177     if ($kid->name eq "list" and want_list $kid) {
3178         # When an indirect object isn't a bareword but the args are in
3179         # parens, the parens aren't part of the method syntax (the LLAFR
3180         # doesn't apply), but they make a list with OPf_PARENS set that
3181         # doesn't get flattened by the append_elem that adds the method,
3182         # making a (object, arg1, arg2, ...) list where the object
3183         # usually is. This can be distinguished from
3184         # `($obj, $arg1, $arg2)->meth()' (which is legal if $arg2 is an
3185         # object) because in the later the list is in scalar context
3186         # as the left side of -> always is, while in the former
3187         # the list is in list context as method arguments always are.
3188         # (Good thing there aren't method prototypes!)
3189         $meth = $kid->sibling;
3190         $kid = $kid->first->sibling; # skip pushmark
3191         $obj = $kid;
3192         $kid = $kid->sibling;
3193         for (; not null $kid; $kid = $kid->sibling) {
3194             push @exprs, $kid;
3195         }
3196     } else {
3197         $obj = $kid;
3198         $kid = $kid->sibling;
3199         for (; !null ($kid->sibling) && $kid->name ne "method_named";
3200               $kid = $kid->sibling) {
3201             push @exprs, $kid
3202         }
3203         $meth = $kid;
3204     }
3205
3206     if ($meth->name eq "method_named") {
3207         $meth = $self->const_sv($meth)->PV;
3208     } else {
3209         $meth = $meth->first;
3210         if ($meth->name eq "const") {
3211             # As of 5.005_58, this case is probably obsoleted by the
3212             # method_named case above
3213             $meth = $self->const_sv($meth)->PV; # needs to be bare
3214         }
3215     }
3216
3217     return { method => $meth, variable_method => ref($meth),
3218              object => $obj, args => \@exprs  };
3219 }
3220
3221 # compat function only
3222 sub method {
3223     my $self = shift;
3224     my $info = $self->_method(@_);
3225     return $self->e_method( $self->_method(@_) );
3226 }
3227
3228 sub e_method {
3229     my ($self, $info) = @_;
3230     my $obj = $self->deparse($info->{object}, 24);
3231
3232     my $meth = $info->{method};
3233     $meth = $self->deparse($meth, 1) if $info->{variable_method};
3234     my $args = join(", ", map { $self->deparse($_, 6) } @{$info->{args}} );
3235     my $kid = $obj . "->" . $meth;
3236     if (length $args) {
3237         return $kid . "(" . $args . ")"; # parens mandatory
3238     } else {
3239         return $kid;
3240     }
3241 }
3242
3243 # returns "&" if the prototype doesn't match the args,
3244 # or ("", $args_after_prototype_demunging) if it does.
3245 sub check_proto {
3246     my $self = shift;
3247     return "&" if $self->{'noproto'};
3248     my($proto, @args) = @_;
3249     my($arg, $real);
3250     my $doneok = 0;
3251     my @reals;
3252     # An unbackslashed @ or % gobbles up the rest of the args
3253     1 while $proto =~ s/(?<!\\)([@%])[^\]]+$/$1/;
3254     while ($proto) {
3255         $proto =~ s/^(\\?[\$\@&%*_]|\\\[[\$\@&%*]+\]|;)//;
3256         my $chr = $1;
3257         if ($chr eq "") {
3258             return "&" if @args;
3259         } elsif ($chr eq ";") {
3260             $doneok = 1;
3261         } elsif ($chr eq "@" or $chr eq "%") {
3262             push @reals, map($self->deparse($_, 6), @args);
3263             @args = ();
3264         } else {
3265             $arg = shift @args;
3266             last unless $arg;
3267             if ($chr eq "\$" || $chr eq "_") {
3268                 if (want_scalar $arg) {
3269                     push @reals, $self->deparse($arg, 6);
3270                 } else {
3271                     return "&";
3272                 }
3273             } elsif ($chr eq "&") {
3274                 if ($arg->name =~ /^(s?refgen|undef)$/) {
3275                     push @reals, $self->deparse($arg, 6);
3276                 } else {
3277                     return "&";
3278                 }
3279             } elsif ($chr eq "*") {
3280                 if ($arg->name =~ /^s?refgen$/
3281                     and $arg->first->first->name eq "rv2gv")
3282                   {
3283                       $real = $arg->first->first; # skip refgen, null
3284                       if ($real->first->name eq "gv") {
3285                           push @reals, $self->deparse($real, 6);
3286                       } else {
3287                           push @reals, $self->deparse($real->first, 6);
3288                       }
3289                   } else {
3290                       return "&";
3291                   }
3292             } elsif (substr($chr, 0, 1) eq "\\") {
3293                 $chr =~ tr/\\[]//d;
3294                 if ($arg->name =~ /^s?refgen$/ and
3295                     !null($real = $arg->first) and
3296                     ($chr =~ /\$/ && is_scalar($real->first)
3297                      or ($chr =~ /@/
3298                          && class($real->first->sibling) ne 'NULL'
3299                          && $real->first->sibling->name
3300                          =~ /^(rv2|pad)av$/)
3301                      or ($chr =~ /%/
3302                          && class($real->first->sibling) ne 'NULL'
3303                          && $real->first->sibling->name
3304                          =~ /^(rv2|pad)hv$/)
3305                      #or ($chr =~ /&/ # This doesn't work
3306                      #   && $real->first->name eq "rv2cv")
3307                      or ($chr =~ /\*/
3308                          && $real->first->name eq "rv2gv")))
3309                   {
3310                       push @reals, $self->deparse($real, 6);
3311                   } else {
3312                       return "&";
3313                   }
3314             }
3315        }
3316     }
3317     return "&" if $proto and !$doneok; # too few args and no `;'
3318     return "&" if @args;               # too many args
3319     return ("", join ", ", @reals);
3320 }
3321
3322 sub pp_entersub {
3323     my $self = shift;
3324     my($op, $cx) = @_;
3325     return $self->e_method($self->_method($op, $cx))
3326         unless null $op->first->sibling;
3327     my $prefix = "";
3328     my $amper = "";
3329     my($kid, @exprs);
3330     if ($op->flags & OPf_SPECIAL && !($op->flags & OPf_MOD)) {
3331         $prefix = "do ";
3332     } elsif ($op->private & OPpENTERSUB_AMPER) {
3333         $amper = "&";
3334     }
3335     $kid = $op->first;
3336     $kid = $kid->first->sibling; # skip ex-list, pushmark
3337     for (; not null $kid->sibling; $kid = $kid->sibling) {
3338         push @exprs, $kid;
3339     }
3340     my $simple = 0;
3341     my $proto = undef;
3342     if (is_scope($kid)) {
3343         $amper = "&";
3344         $kid = "{" . $self->deparse($kid, 0) . "}";
3345     } elsif ($kid->first->name eq "gv") {
3346         my $gv = $self->gv_or_padgv($kid->first);
3347         if (class($gv->CV) ne "SPECIAL") {
3348             $proto = $gv->CV->PV if $gv->CV->FLAGS & SVf_POK;
3349         }
3350         $simple = 1; # only calls of named functions can be prototyped
3351         $kid = $self->deparse($kid, 24);
3352         if (!$amper) {
3353             if ($kid eq 'main::') {
3354                 $kid = '::';
3355             } elsif ($kid !~ /^(?:\w|::)(?:[\w\d]|::(?!\z))*\z/) {
3356                 $kid = single_delim("q", "'", $kid) . '->';
3357             }
3358         }
3359     } elsif (is_scalar ($kid->first) && $kid->first->name ne 'rv2cv') {
3360         $amper = "&";
3361         $kid = $self->deparse($kid, 24);
3362     } else {
3363         $prefix = "";
3364         my $arrow = is_subscriptable($kid->first) ? "" : "->";
3365         $kid = $self->deparse($kid, 24) . $arrow;
3366     }
3367
3368     # Doesn't matter how many prototypes there are, if
3369     # they haven't happened yet!
3370     my $declared;
3371     {
3372         no strict 'refs';
3373         no warnings 'uninitialized';
3374         $declared = exists $self->{'subs_declared'}{$kid}
3375             || (
3376                  defined &{ ${$self->{'curstash'}."::"}{$kid} }
3377                  && !exists
3378                      $self->{'subs_deparsed'}{$self->{'curstash'}."::".$kid}
3379                  && defined prototype $self->{'curstash'}."::".$kid
3380                );
3381         if (!$declared && defined($proto)) {
3382             # Avoid "too early to check prototype" warning
3383             ($amper, $proto) = ('&');
3384         }
3385     }
3386
3387     my $args;
3388     if ($declared and defined $proto and not $amper) {
3389         ($amper, $args) = $self->check_proto($proto, @exprs);
3390         if ($amper eq "&") {
3391             $args = join(", ", map($self->deparse($_, 6), @exprs));
3392         }
3393     } else {
3394         $args = join(", ", map($self->deparse($_, 6), @exprs));
3395     }
3396     if ($prefix or $amper) {
3397         if ($op->flags & OPf_STACKED) {
3398             return $prefix . $amper . $kid . "(" . $args . ")";
3399         } else {
3400             return $prefix . $amper. $kid;
3401         }
3402     } else {
3403         # glob() invocations can be translated into calls of
3404         # CORE::GLOBAL::glob with a second parameter, a number.
3405         # Reverse this.
3406         if ($kid eq "CORE::GLOBAL::glob") {
3407             $kid = "glob";
3408             $args =~ s/\s*,[^,]+$//;
3409         }
3410
3411         # It's a syntax error to call CORE::GLOBAL::foo without a prefix,
3412         # so it must have been translated from a keyword call. Translate
3413         # it back.
3414         $kid =~ s/^CORE::GLOBAL:://;
3415
3416         my $dproto = defined($proto) ? $proto : "undefined";
3417         if (!$declared) {
3418             return "$kid(" . $args . ")";
3419         } elsif ($dproto eq "") {
3420             return $kid;
3421         } elsif ($dproto eq "\$" and is_scalar($exprs[0])) {
3422             # is_scalar is an excessively conservative test here:
3423             # really, we should be comparing to the precedence of the
3424             # top operator of $exprs[0] (ala unop()), but that would
3425             # take some major code restructuring to do right.
3426             return $self->maybe_parens_func($kid, $args, $cx, 16);
3427         } elsif ($dproto ne '$' and defined($proto) || $simple) { #'
3428             return $self->maybe_parens_func($kid, $args, $cx, 5);
3429         } else {
3430             return "$kid(" . $args . ")";
3431         }
3432     }
3433 }
3434
3435 sub pp_enterwrite { unop(@_, "write") }
3436
3437 # escape things that cause interpolation in double quotes,
3438 # but not character escapes
3439 sub uninterp {
3440     my($str) = @_;
3441     $str =~ s/(^|\G|[^\\])((?:\\\\)*)([\$\@]|\\[uUlLQE])/$1$2\\$3/g;
3442     return $str;
3443 }
3444
3445 {
3446 my $bal;
3447 BEGIN {
3448     use re "eval";
3449     # Matches any string which is balanced with respect to {braces}
3450     $bal = qr(
3451       (?:
3452         [^\\{}]
3453       | \\\\
3454       | \\[{}]
3455       | \{(??{$bal})\}
3456       )*
3457     )x;
3458 }
3459
3460 # the same, but treat $|, $), $( and $ at the end of the string differently
3461 sub re_uninterp {
3462     my($str) = @_;
3463
3464     $str =~ s/
3465           ( ^|\G                  # $1
3466           | [^\\]
3467           )
3468
3469           (                       # $2
3470             (?:\\\\)*
3471           )
3472
3473           (                       # $3
3474             (\(\?\??\{$bal\}\))   # $4
3475           | [\$\@]
3476             (?!\||\)|\(|$)
3477           | \\[uUlLQE]
3478           )
3479
3480         /defined($4) && length($4) ? "$1$2$4" : "$1$2\\$3"/xeg;
3481
3482     return $str;
3483 }
3484
3485 # This is for regular expressions with the /x modifier
3486 # We have to leave comments unmangled.
3487 sub re_uninterp_extended {
3488     my($str) = @_;
3489
3490     $str =~ s/
3491           ( ^|\G                  # $1
3492           | [^\\]
3493           )
3494
3495           (                       # $2
3496             (?:\\\\)*
3497           )
3498
3499           (                       # $3
3500             ( \(\?\??\{$bal\}\)   # $4  (skip over (?{}) and (??{}) blocks)
3501             | \#[^\n]*            #     (skip over comments)
3502             )
3503           | [\$\@]
3504             (?!\||\)|\(|$|\s)
3505           | \\[uUlLQE]
3506           )
3507
3508         /defined($4) && length($4) ? "$1$2$4" : "$1$2\\$3"/xeg;
3509
3510     return $str;
3511 }
3512 }
3513
3514 my %unctrl = # portable to to EBCDIC
3515     (
3516      "\c@" => '\c@',    # unused
3517      "\cA" => '\cA',
3518      "\cB" => '\cB',
3519      "\cC" => '\cC',
3520      "\cD" => '\cD',
3521      "\cE" => '\cE',
3522      "\cF" => '\cF',
3523      "\cG" => '\cG',
3524      "\cH" => '\cH',
3525      "\cI" => '\cI',
3526      "\cJ" => '\cJ',
3527      "\cK" => '\cK',
3528      "\cL" => '\cL',
3529      "\cM" => '\cM',
3530      "\cN" => '\cN',
3531      "\cO" => '\cO',
3532      "\cP" => '\cP',
3533      "\cQ" => '\cQ',
3534      "\cR" => '\cR',
3535      "\cS" => '\cS',
3536      "\cT" => '\cT',
3537      "\cU" => '\cU',
3538      "\cV" => '\cV',
3539      "\cW" => '\cW',
3540      "\cX" => '\cX',
3541      "\cY" => '\cY',
3542      "\cZ" => '\cZ',
3543      "\c[" => '\c[',    # unused
3544      "\c\\" => '\c\\',  # unused
3545      "\c]" => '\c]',    # unused
3546      "\c_" => '\c_',    # unused
3547     );
3548
3549 # character escapes, but not delimiters that might need to be escaped
3550 sub escape_str { # ASCII, UTF8
3551     my($str) = @_;
3552     $str =~ s/(.)/ord($1) > 255 ? sprintf("\\x{%x}", ord($1)) : $1/eg;
3553     $str =~ s/\a/\\a/g;
3554 #    $str =~ s/\cH/\\b/g; # \b means something different in a regex
3555     $str =~ s/\t/\\t/g;
3556     $str =~ s/\n/\\n/g;
3557     $str =~ s/\e/\\e/g;
3558     $str =~ s/\f/\\f/g;
3559     $str =~ s/\r/\\r/g;
3560     $str =~ s/([\cA-\cZ])/$unctrl{$1}/ge;
3561     $str =~ s/([[:^print:]])/sprintf("\\%03o", ord($1))/ge;
3562     return $str;
3563 }
3564
3565 # For regexes with the /x modifier.
3566 # Leave whitespace unmangled.
3567 sub escape_extended_re {
3568     my($str) = @_;
3569     $str =~ s/(.)/ord($1) > 255 ? sprintf("\\x{%x}", ord($1)) : $1/eg;
3570     $str =~ s/([[:^print:]])/
3571         ($1 =~ y! \t\n!!) ? $1 : sprintf("\\%03o", ord($1))/ge;
3572     $str =~ s/\n/\n\f/g;
3573     return $str;
3574 }
3575
3576 # Don't do this for regexen
3577 sub unback {
3578     my($str) = @_;
3579     $str =~ s/\\/\\\\/g;
3580     return $str;
3581 }
3582
3583 # Remove backslashes which precede literal control characters,
3584 # to avoid creating ambiguity when we escape the latter.
3585 sub re_unback {
3586     my($str) = @_;
3587
3588     # the insane complexity here is due to the behaviour of "\c\"
3589     $str =~ s/(^|[^\\]|\\c\\)(?<!\\c)\\(\\\\)*(?=[[:^print:]])/$1$2/g;
3590     return $str;
3591 }
3592
3593 sub balanced_delim {
3594     my($str) = @_;
3595     my @str = split //, $str;
3596     my($ar, $open, $close, $fail, $c, $cnt, $last_bs);
3597     for $ar (['[',']'], ['(',')'], ['<','>'], ['{','}']) {
3598         ($open, $close) = @$ar;
3599         $fail = 0; $cnt = 0; $last_bs = 0;
3600         for $c (@str) {
3601             if ($c eq $open) {
3602                 $fail = 1 if $last_bs;
3603                 $cnt++;
3604             } elsif ($c eq $close) {
3605                 $fail = 1 if $last_bs;
3606                 $cnt--;
3607                 if ($cnt < 0) {
3608                     # qq()() isn't ")("
3609                     $fail = 1;
3610                     last;
3611                 }
3612             }
3613             $last_bs = $c eq '\\';
3614         }
3615         $fail = 1 if $cnt != 0;
3616         return ($open, "$open$str$close") if not $fail;
3617     }
3618     return ("", $str);
3619 }
3620
3621 sub single_delim {
3622     my($q, $default, $str) = @_;
3623     return "$default$str$default" if $default and index($str, $default) == -1;
3624     if ($q ne 'qr') {
3625         (my $succeed, $str) = balanced_delim($str);
3626         return "$q$str" if $succeed;
3627     }
3628     for my $delim ('/', '"', '#') {
3629         return "$q$delim" . $str . $delim if index($str, $delim) == -1;
3630     }
3631     if ($default) {
3632         $str =~ s/$default/\\$default/g;
3633         return "$default$str$default";
3634     } else {
3635         $str =~ s[/][\\/]g;
3636         return "$q/$str/";
3637     }
3638 }
3639
3640 my $max_prec;
3641 BEGIN { $max_prec = int(0.999 + 8*length(pack("F", 42))*log(2)/log(10)); }
3642
3643 # Split a floating point number into an integer mantissa and a binary
3644 # exponent. Assumes you've already made sure the number isn't zero or
3645 # some weird infinity or NaN.
3646 sub split_float {
3647     my($f) = @_;
3648     my $exponent = 0;
3649     if ($f == int($f)) {
3650         while ($f % 2 == 0) {
3651             $f /= 2;
3652             $exponent++;
3653         }
3654     } else {
3655         while ($f != int($f)) {
3656             $f *= 2;
3657             $exponent--;
3658         }
3659     }
3660     my $mantissa = sprintf("%.0f", $f);
3661     return ($mantissa, $exponent);
3662 }
3663
3664 sub const {
3665     my $self = shift;
3666     my($sv, $cx) = @_;
3667     if ($self->{'use_dumper'}) {
3668         return $self->const_dumper($sv, $cx);
3669     }
3670     if (class($sv) eq "SPECIAL") {
3671         # sv_undef, sv_yes, sv_no
3672         return ('undef', '1', $self->maybe_parens("!1", $cx, 21))[$$sv-1];
3673     }
3674     if (class($sv) eq "NULL") {
3675        return 'undef';
3676     }
3677     # convert a version object into the "v1.2.3" string in its V magic
3678     if ($sv->FLAGS & SVs_RMG) {
3679         for (my $mg = $sv->MAGIC; $mg; $mg = $mg->MOREMAGIC) {
3680             return $mg->PTR if $mg->TYPE eq 'V';
3681         }
3682     }
3683
3684     if ($sv->FLAGS & SVf_IOK) {
3685         my $str = $sv->int_value;
3686         $str = $self->maybe_parens($str, $cx, 21) if $str < 0;
3687         return $str;
3688     } elsif ($sv->FLAGS & SVf_NOK) {
3689         my $nv = $sv->NV;
3690         if ($nv == 0) {
3691             if (pack("F", $nv) eq pack("F", 0)) {
3692                 # positive zero
3693                 return "0";
3694             } else {
3695                 # negative zero
3696                 return $self->maybe_parens("-.0", $cx, 21);
3697             }
3698         } elsif (1/$nv == 0) {
3699             if ($nv > 0) {
3700                 # positive infinity
3701                 return $self->maybe_parens("9**9**9", $cx, 22);
3702             } else {
3703                 # negative infinity
3704                 return $self->maybe_parens("-9**9**9", $cx, 21);
3705             }
3706         } elsif ($nv != $nv) {
3707             # NaN
3708             if (pack("F", $nv) eq pack("F", sin(9**9**9))) {
3709                 # the normal kind
3710                 return "sin(9**9**9)";
3711             } elsif (pack("F", $nv) eq pack("F", -sin(9**9**9))) {
3712                 # the inverted kind
3713                 return $self->maybe_parens("-sin(9**9**9)", $cx, 21);
3714             } else {
3715                 # some other kind
3716                 my $hex = unpack("h*", pack("F", $nv));
3717                 return qq'unpack("F", pack("h*", "$hex"))';
3718             }
3719         }
3720         # first, try the default stringification
3721         my $str = "$nv";
3722         if ($str != $nv) {
3723             # failing that, try using more precision
3724             $str = sprintf("%.${max_prec}g", $nv);
3725 #           if (pack("F", $str) ne pack("F", $nv)) {
3726             if ($str != $nv) {
3727                 # not representable in decimal with whatever sprintf()
3728                 # and atof() Perl is using here.
3729                 my($mant, $exp) = split_float($nv);
3730                 return $self->maybe_parens("$mant * 2**$exp", $cx, 19);
3731             }
3732         }
3733         $str = $self->maybe_parens($str, $cx, 21) if $nv < 0;
3734         return $str;
3735     } elsif ($sv->FLAGS & SVf_ROK && $sv->can("RV")) {
3736         my $ref = $sv->RV;
3737         if (class($ref) eq "AV") {
3738             return "[" . $self->list_const(2, $ref->ARRAY) . "]";
3739         } elsif (class($ref) eq "HV") {
3740             my %hash = $ref->ARRAY;
3741             my @elts;
3742             for my $k (sort keys %hash) {
3743                 push @elts, "$k => " . $self->const($hash{$k}, 6);
3744             }
3745             return "{" . join(", ", @elts) . "}";
3746         } elsif (class($ref) eq "CV") {
3747             return "sub " . $self->deparse_sub($ref);
3748         }
3749         if ($ref->FLAGS & SVs_SMG) {
3750             for (my $mg = $ref->MAGIC; $mg; $mg = $mg->MOREMAGIC) {
3751                 if ($mg->TYPE eq 'r') {
3752                     my $re = re_uninterp(escape_str(re_unback($mg->precomp)));
3753                     return single_delim("qr", "", $re);
3754                 }
3755             }
3756         }
3757         
3758         return $self->maybe_parens("\\" . $self->const($ref, 20), $cx, 20);
3759     } elsif ($sv->FLAGS & SVf_POK) {
3760         my $str = $sv->PV;
3761         if ($str =~ /[[:^print:]]/) {
3762             return single_delim("qq", '"', uninterp escape_str unback $str);
3763         } else {
3764             return single_delim("q", "'", unback $str);
3765         }
3766     } else {
3767         return "undef";
3768     }
3769 }
3770
3771 sub const_dumper {
3772     my $self = shift;
3773     my($sv, $cx) = @_;
3774     my $ref = $sv->object_2svref();
3775     my $dumper = Data::Dumper->new([$$ref], ['$v']);
3776     $dumper->Purity(1)->Terse(1)->Deparse(1)->Indent(0)->Useqq(1)->Sortkeys(1);
3777     my $str = $dumper->Dump();
3778     if ($str =~ /^\$v/) {
3779         return '${my ' . $str . ' \$v}';
3780     } else {
3781         return $str;
3782     }
3783 }
3784
3785 sub const_sv {
3786     my $self = shift;
3787     my $op = shift;
3788     my $sv = $op->sv;
3789     # the constant could be in the pad (under useithreads)
3790     $sv = $self->padval($op->targ) unless $$sv;
3791     return $sv;
3792 }
3793
3794 sub pp_const {
3795     my $self = shift;
3796     my($op, $cx) = @_;
3797     if ($op->private & OPpCONST_ARYBASE) {
3798         return '$[';
3799     }
3800 #    if ($op->private & OPpCONST_BARE) { # trouble with `=>' autoquoting
3801 #       return $self->const_sv($op)->PV;
3802 #    }
3803     my $sv = $self->const_sv($op);
3804     return $self->const($sv, $cx);
3805 }
3806
3807 sub dq {
3808     my $self = shift;
3809     my $op = shift;
3810     my $type = $op->name;
3811     if ($type eq "const") {
3812         return '$[' if $op->private & OPpCONST_ARYBASE;
3813         return uninterp(escape_str(unback($self->const_sv($op)->as_string)));
3814     } elsif ($type eq "concat") {
3815         my $first = $self->dq($op->first);
3816         my $last  = $self->dq($op->last);
3817
3818         # Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]", "$foo\::bar"
3819         ($last =~ /^[A-Z\\\^\[\]_?]/ &&
3820             $first =~ s/([\$@])\^$/${1}{^}/)  # "${^}W" etc
3821             || ($last =~ /^[:'{\[\w_]/ && #'
3822                 $first =~ s/([\$@])([A-Za-z_]\w*)$/${1}{$2}/);
3823
3824         return $first . $last;
3825     } elsif ($type eq "uc") {
3826         return '\U' . $self->dq($op->first->sibling) . '\E';
3827     } elsif ($type eq "lc") {
3828         return '\L' . $self->dq($op->first->sibling) . '\E';
3829     } elsif ($type eq "ucfirst") {
3830         return '\u' . $self->dq($op->first->sibling);
3831     } elsif ($type eq "lcfirst") {
3832         return '\l' . $self->dq($op->first->sibling);
3833     } elsif ($type eq "quotemeta") {
3834         return '\Q' . $self->dq($op->first->sibling) . '\E';
3835     } elsif ($type eq "join") {
3836         return $self->deparse($op->last, 26); # was join($", @ary)
3837     } else {
3838         return $self->deparse($op, 26);
3839     }
3840 }
3841
3842 sub pp_backtick {
3843     my $self = shift;
3844     my($op, $cx) = @_;
3845     # skip pushmark if it exists (readpipe() vs ``)
3846     my $child = $op->first->sibling->isa('B::NULL')
3847         ? $op->first : $op->first->sibling;
3848     return single_delim("qx", '`', $self->dq($child));
3849 }
3850
3851 sub dquote {
3852     my $self = shift;
3853     my($op, $cx) = @_;
3854     my $kid = $op->first->sibling; # skip ex-stringify, pushmark
3855     return $self->deparse($kid, $cx) if $self->{'unquote'};
3856     $self->maybe_targmy($kid, $cx,
3857                         sub {single_delim("qq", '"', $self->dq($_[1]))});
3858 }
3859
3860 # OP_STRINGIFY is a listop, but it only ever has one arg
3861 sub pp_stringify { maybe_targmy(@_, \&dquote) }
3862
3863 # tr/// and s/// (and tr[][], tr[]//, tr###, etc)
3864 # note that tr(from)/to/ is OK, but not tr/from/(to)
3865 sub double_delim {
3866     my($from, $to) = @_;
3867     my($succeed, $delim);
3868     if ($from !~ m[/] and $to !~ m[/]) {
3869         return "/$from/$to/";
3870     } elsif (($succeed, $from) = balanced_delim($from) and $succeed) {
3871         if (($succeed, $to) = balanced_delim($to) and $succeed) {
3872             return "$from$to";
3873         } else {
3874             for $delim ('/', '"', '#') { # note no `'' -- s''' is special
3875                 return "$from$delim$to$delim" if index($to, $delim) == -1;
3876             }
3877             $to =~ s[/][\\/]g;
3878             return "$from/$to/";
3879         }
3880     } else {
3881         for $delim ('/', '"', '#') { # note no '
3882             return "$delim$from$delim$to$delim"
3883                 if index($to . $from, $delim) == -1;
3884         }
3885         $from =~ s[/][\\/]g;
3886         $to =~ s[/][\\/]g;
3887         return "/$from/$to/";   
3888     }
3889 }
3890
3891 # Only used by tr///, so backslashes hyphens
3892 sub pchr { # ASCII
3893     my($n) = @_;
3894     if ($n == ord '\\') {
3895         return '\\\\';
3896     } elsif ($n == ord "-") {
3897         return "\\-";
3898     } elsif ($n >= ord(' ') and $n <= ord('~')) {
3899         return chr($n);
3900     } elsif ($n == ord "\a") {
3901         return '\\a';
3902     } elsif ($n == ord "\b") {
3903         return '\\b';
3904     } elsif ($n == ord "\t") {
3905         return '\\t';
3906     } elsif ($n == ord "\n") {
3907         return '\\n';
3908     } elsif ($n == ord "\e") {
3909         return '\\e';
3910     } elsif ($n == ord "\f") {
3911         return '\\f';
3912     } elsif ($n == ord "\r") {
3913         return '\\r';
3914     } elsif ($n >= ord("\cA") and $n <= ord("\cZ")) {
3915         return '\\c' . chr(ord("@") + $n);
3916     } else {
3917 #       return '\x' . sprintf("%02x", $n);
3918         return '\\' . sprintf("%03o", $n);
3919     }
3920 }
3921
3922 sub collapse {
3923     my(@chars) = @_;
3924     my($str, $c, $tr) = ("");
3925     for ($c = 0; $c < @chars; $c++) {
3926         $tr = $chars[$c];
3927         $str .= pchr($tr);
3928         if ($c <= $#chars - 2 and $chars[$c + 1] == $tr + 1 and
3929             $chars[$c + 2] == $tr + 2)
3930         {
3931             for (; $c <= $#chars-1 and $chars[$c + 1] == $chars[$c] + 1; $c++)
3932               {}
3933             $str .= "-";
3934             $str .= pchr($chars[$c]);
3935         }
3936     }
3937     return $str;
3938 }
3939
3940 sub tr_decode_byte {
3941     my($table, $flags) = @_;
3942     my(@table) = unpack("s*", $table);
3943     splice @table, 0x100, 1;   # Number of subsequent elements
3944     my($c, $tr, @from, @to, @delfrom, $delhyphen);
3945     if ($table[ord "-"] != -1 and
3946         $table[ord("-") - 1] == -1 || $table[ord("-") + 1] == -1)
3947     {
3948         $tr = $table[ord "-"];
3949         $table[ord "-"] = -1;
3950         if ($tr >= 0) {
3951             @from = ord("-");
3952             @to = $tr;
3953         } else { # -2 ==> delete
3954             $delhyphen = 1;
3955         }
3956     }
3957     for ($c = 0; $c < @table; $c++) {
3958         $tr = $table[$c];
3959         if ($tr >= 0) {
3960             push @from, $c; push @to, $tr;
3961         } elsif ($tr == -2) {
3962             push @delfrom, $c;
3963         }
3964     }
3965     @from = (@from, @delfrom);
3966     if ($flags & OPpTRANS_COMPLEMENT) {
3967         my @newfrom = ();
3968         my %from;
3969         @from{@from} = (1) x @from;
3970         for ($c = 0; $c < 256; $c++) {
3971             push @newfrom, $c unless $from{$c};
3972         }
3973         @from = @newfrom;
3974     }
3975     unless ($flags & OPpTRANS_DELETE || !@to) {
3976         pop @to while $#to and $to[$#to] == $to[$#to -1];
3977     }
3978     my($from, $to);
3979     $from = collapse(@from);
3980     $to = collapse(@to);
3981     $from .= "-" if $delhyphen;
3982     return ($from, $to);
3983 }
3984
3985 sub tr_chr {
3986     my $x = shift;
3987     if ($x == ord "-") {
3988         return "\\-";
3989     } elsif ($x == ord "\\") {
3990         return "\\\\";
3991     } else {
3992         return chr $x;
3993     }
3994 }
3995
3996 # XXX This doesn't yet handle all cases correctly either
3997
3998 sub tr_decode_utf8 {
3999     my($swash_hv, $flags) = @_;
4000     my %swash = $swash_hv->ARRAY;
4001     my $final = undef;
4002     $final = $swash{'FINAL'}->IV if exists $swash{'FINAL'};
4003     my $none = $swash{"NONE"}->IV;
4004     my $extra = $none + 1;
4005     my(@from, @delfrom, @to);
4006     my $line;
4007     foreach $line (split /\n/, $swash{'LIST'}->PV) {
4008         my($min, $max, $result) = split(/\t/, $line);
4009         $min = hex $min;
4010         if (length $max) {
4011             $max = hex $max;
4012         } else {
4013             $max = $min;
4014         }
4015         $result = hex $result;
4016         if ($result == $extra) {
4017             push @delfrom, [$min, $max];
4018         } else {
4019             push @from, [$min, $max];
4020             push @to, [$result, $result + $max - $min];
4021         }
4022     }
4023     for my $i (0 .. $#from) {
4024         if ($from[$i][0] == ord '-') {
4025             unshift @from, splice(@from, $i, 1);
4026             unshift @to, splice(@to, $i, 1);
4027             last;
4028         } elsif ($from[$i][1] == ord '-') {
4029             $from[$i][1]--;
4030             $to[$i][1]--;
4031             unshift @from, ord '-';
4032             unshift @to, ord '-';
4033             last;
4034         }
4035     }
4036     for my $i (0 .. $#delfrom) {
4037         if ($delfrom[$i][0] == ord '-') {
4038             push @delfrom, splice(@delfrom, $i, 1);
4039             last;
4040         } elsif ($delfrom[$i][1] == ord '-') {
4041             $delfrom[$i][1]--;
4042             push @delfrom, ord '-';
4043             last;
4044         }
4045     }
4046     if (defined $final and $to[$#to][1] != $final) {
4047         push @to, [$final, $final];
4048     }
4049     push @from, @delfrom;
4050     if ($flags & OPpTRANS_COMPLEMENT) {
4051         my @newfrom;
4052         my $next = 0;
4053         for my $i (0 .. $#from) {
4054             push @newfrom, [$next, $from[$i][0] - 1];
4055             $next = $from[$i][1] + 1;
4056         }
4057         @from = ();
4058         for my $range (@newfrom) {
4059             if ($range->[0] <= $range->[1]) {
4060                 push @from, $range;
4061             }
4062         }
4063     }
4064     my($from, $to, $diff);
4065     for my $chunk (@from) {
4066         $diff = $chunk->[1] - $chunk->[0];
4067         if ($diff > 1) {
4068             $from .= tr_chr($chunk->[0]) . "-" . tr_chr($chunk->[1]);
4069         } elsif ($diff == 1) {
4070             $from .= tr_chr($chunk->[0]) . tr_chr($chunk->[1]);
4071         } else {
4072             $from .= tr_chr($chunk->[0]);
4073         }
4074     }
4075     for my $chunk (@to) {
4076         $diff = $chunk->[1] - $chunk->[0];
4077         if ($diff > 1) {
4078             $to .= tr_chr($chunk->[0]) . "-" . tr_chr($chunk->[1]);
4079         } elsif ($diff == 1) {
4080             $to .= tr_chr($chunk->[0]) . tr_chr($chunk->[1]);
4081         } else {
4082             $to .= tr_chr($chunk->[0]);
4083         }
4084     }
4085     #$final = sprintf("%04x", $final) if defined $final;
4086     #$none = sprintf("%04x", $none) if defined $none;
4087     #$extra = sprintf("%04x", $extra) if defined $extra;
4088     #print STDERR "final: $final\n none: $none\nextra: $extra\n";
4089     #print STDERR $swash{'LIST'}->PV;
4090     return (escape_str($from), escape_str($to));
4091 }
4092
4093 sub pp_trans {
4094     my $self = shift;
4095     my($op, $cx) = @_;
4096     my($from, $to);
4097     if (class($op) eq "PVOP") {
4098         ($from, $to) = tr_decode_byte($op->pv, $op->private);
4099     } else { # class($op) eq "SVOP"
4100         ($from, $to) = tr_decode_utf8($op->sv->RV, $op->private);
4101     }
4102     my $flags = "";
4103     $flags .= "c" if $op->private & OPpTRANS_COMPLEMENT;
4104     $flags .= "d" if $op->private & OPpTRANS_DELETE;
4105     $to = "" if $from eq $to and $flags eq "";
4106     $flags .= "s" if $op->private & OPpTRANS_SQUASH;
4107     return "tr" . double_delim($from, $to) . $flags;
4108 }
4109
4110 sub re_dq_disambiguate {
4111     my ($first, $last) = @_;
4112     # Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]"
4113     ($last =~ /^[A-Z\\\^\[\]_?]/ &&
4114         $first =~ s/([\$@])\^$/${1}{^}/)  # "${^}W" etc
4115         || ($last =~ /^[{\[\w_]/ &&
4116             $first =~ s/([\$@])([A-Za-z_]\w*)$/${1}{$2}/);
4117     return $first . $last;
4118 }
4119
4120 # Like dq(), but different
4121 sub re_dq {
4122     my $self = shift;
4123     my ($op, $extended) = @_;
4124
4125     my $type = $op->name;
4126     if ($type eq "const") {
4127         return '$[' if $op->private & OPpCONST_ARYBASE;
4128         my $unbacked = re_unback($self->const_sv($op)->as_string);
4129         return re_uninterp_extended(escape_extended_re($unbacked))
4130             if $extended;
4131         return re_uninterp(escape_str($unbacked));
4132     } elsif ($type eq "concat") {
4133         my $first = $self->re_dq($op->first, $extended);
4134         my $last  = $self->re_dq($op->last,  $extended);
4135         return re_dq_disambiguate($first, $last);
4136     } elsif ($type eq "uc") {
4137         return '\U' . $self->re_dq($op->first->sibling, $extended) . '\E';
4138     } elsif ($type eq "lc") {
4139         return '\L' . $self->re_dq($op->first->sibling, $extended) . '\E';
4140     } elsif ($type eq "ucfirst") {
4141         return '\u' . $self->re_dq($op->first->sibling, $extended);
4142     } elsif ($type eq "lcfirst") {
4143         return '\l' . $self->re_dq($op->first->sibling, $extended);
4144     } elsif ($type eq "quotemeta") {
4145         return '\Q' . $self->re_dq($op->first->sibling, $extended) . '\E';
4146     } elsif ($type eq "join") {
4147         return $self->deparse($op->last, 26); # was join($", @ary)
4148     } else {
4149         return $self->deparse($op, 26);
4150     }
4151 }
4152
4153 sub pure_string {
4154     my ($self, $op) = @_;
4155     return 0 if null $op;
4156     my $type = $op->name;
4157
4158     if ($type eq 'const') {
4159         return 1;
4160     }
4161     elsif ($type =~ /^[ul]c(first)?$/ || $type eq 'quotemeta') {
4162         return $self->pure_string($op->first->sibling);
4163     }
4164     elsif ($type eq 'join') {
4165         my $join_op = $op->first->sibling;  # Skip pushmark
4166         return 0 unless $join_op->name eq 'null' && $join_op->targ eq OP_RV2SV;
4167
4168         my $gvop = $join_op->first;
4169         return 0 unless $gvop->name eq 'gvsv';
4170         return 0 unless '"' eq $self->gv_name($self->gv_or_padgv($gvop));
4171
4172         return 0 unless ${$join_op->sibling} eq ${$op->last};
4173         return 0 unless $op->last->name =~ /^(?:[ah]slice|(?:rv2|pad)av)$/;
4174     }
4175     elsif ($type eq 'concat') {
4176         return $self->pure_string($op->first)
4177             && $self->pure_string($op->last);
4178     }
4179     elsif (is_scalar($op) || $type =~ /^[ah]elem$/) {
4180         return 1;
4181     }
4182     elsif ($type eq "null" and $op->can('first') and not null $op->first and
4183            $op->first->name eq "null" and $op->first->can('first')
4184            and not null $op->first->first and
4185            $op->first->first->name eq "aelemfast") {
4186         return 1;
4187     }
4188     else {
4189         return 0;
4190     }
4191
4192     return 1;
4193 }
4194
4195 sub regcomp {
4196     my $self = shift;
4197     my($op, $cx, $extended) = @_;
4198     my $kid = $op->first;
4199     $kid = $kid->first if $kid->name eq "regcmaybe";
4200     $kid = $kid->first if $kid->name eq "regcreset";
4201     if ($kid->name eq "null" and !null($kid->first)
4202         and $kid->first->name eq 'pushmark')
4203     {
4204         my $str = '';
4205         $kid = $kid->first->sibling;
4206         while (!null($kid)) {
4207             my $first = $str;
4208             my $last = $self->re_dq($kid, $extended);
4209             $str = re_dq_disambiguate($first, $last);
4210             $kid = $kid->sibling;
4211         }
4212         return $str, 1;
4213     }
4214
4215     return ($self->re_dq($kid, $extended), 1) if $self->pure_string($kid);
4216     return ($self->deparse($kid, $cx), 0);
4217 }
4218
4219 sub pp_regcomp {
4220     my ($self, $op, $cx) = @_;
4221     return (($self->regcomp($op, $cx, 0))[0]);
4222 }
4223
4224 # osmic acid -- see osmium tetroxide
4225
4226 my %matchwords;
4227 map($matchwords{join "", sort split //, $_} = $_, 'cig', 'cog', 'cos', 'cogs',
4228     'cox', 'go', 'is', 'ism', 'iso', 'mig', 'mix', 'osmic', 'ox', 'sic',
4229     'sig', 'six', 'smog', 'so', 'soc', 'sog', 'xi');
4230
4231 sub matchop {
4232     my $self = shift;
4233     my($op, $cx, $name, $delim) = @_;
4234     my $kid = $op->first;
4235     my ($binop, $var, $re) = ("", "", "");
4236     if ($op->flags & OPf_STACKED) {
4237         $binop = 1;
4238         $var = $self->deparse($kid, 20);
4239         $kid = $kid->sibling;
4240     }
4241     my $quote = 1;
4242     my $extended = ($op->pmflags & PMf_EXTENDED);
4243     my $rhs_bound_to_defsv;
4244     if (null $kid) {
4245         my $unbacked = re_unback($op->precomp);
4246         if ($extended) {
4247             $re = re_uninterp_extended(escape_extended_re($unbacked));
4248         } else {
4249             $re = re_uninterp(escape_str(re_unback($op->precomp)));
4250         }
4251     } elsif ($kid->name ne 'regcomp') {
4252         carp("found ".$kid->name." where regcomp expected");
4253     } else {
4254         ($re, $quote) = $self->regcomp($kid, 21, $extended);
4255         $rhs_bound_to_defsv = 1 if $kid->first->first->flags & OPf_SPECIAL;
4256     }
4257     my $flags = "";
4258     $flags .= "c" if $op->pmflags & PMf_CONTINUE;
4259     $flags .= "g" if $op->pmflags & PMf_GLOBAL;
4260     $flags .= "i" if $op->pmflags & PMf_FOLD;
4261     $flags .= "m" if $op->pmflags & PMf_MULTILINE;
4262     $flags .= "o" if $op->pmflags & PMf_KEEP;
4263     $flags .= "s" if $op->pmflags & PMf_SINGLELINE;
4264     $flags .= "x" if $op->pmflags & PMf_EXTENDED;
4265     $flags = $matchwords{$flags} if $matchwords{$flags};
4266     if ($op->pmflags & PMf_ONCE) { # only one kind of delimiter works here
4267         $re =~ s/\?/\\?/g;
4268         $re = "?$re?";
4269     } elsif ($quote) {
4270         $re = single_delim($name, $delim, $re);
4271     }
4272     $re = $re . $flags if $quote;
4273     if ($binop) {
4274         return
4275          $self->maybe_parens(
4276           $rhs_bound_to_defsv
4277            ? "$var =~ (\$_ =~ $re)"
4278            : "$var =~ $re",
4279           $cx, 20
4280          );
4281     } else {
4282         return $re;
4283     }
4284 }
4285
4286 sub pp_match { matchop(@_, "m", "/") }
4287 sub pp_pushre { matchop(@_, "m", "/") }
4288 sub pp_qr { matchop(@_, "qr", "") }
4289
4290 sub pp_split {
4291     my $self = shift;
4292     my($op, $cx) = @_;
4293     my($kid, @exprs, $ary, $expr);
4294     $kid = $op->first;
4295
4296     # For our kid (an OP_PUSHRE), pmreplroot is never actually the
4297     # root of a replacement; it's either empty, or abused to point to
4298     # the GV for an array we split into (an optimization to save
4299     # assignment overhead). Depending on whether we're using ithreads,
4300     # this OP* holds either a GV* or a PADOFFSET. Luckily, B.xs
4301     # figures out for us which it is.
4302     my $replroot = $kid->pmreplroot;
4303     my $gv = 0;
4304     if (ref($replroot) eq "B::GV") {
4305         $gv = $replroot;
4306     } elsif (!ref($replroot) and $replroot > 0) {
4307         $gv = $self->padval($replroot);
4308     }
4309     $ary = $self->stash_variable('@', $self->gv_name($gv)) if $gv;
4310
4311     for (; !null($kid); $kid = $kid->sibling) {
4312         push @exprs, $self->deparse($kid, 6);
4313     }
4314
4315     # handle special case of split(), and split(' ') that compiles to /\s+/
4316     # Under 5.10, the reflags may be undef if the split regexp isn't a constant
4317     $kid = $op->first;
4318     if ( $kid->flags & OPf_SPECIAL
4319          and ( $] < 5.009 ? $kid->pmflags & PMf_SKIPWHITE()
4320               : ($kid->reflags || 0) & RXf_SKIPWHITE() ) ) {
4321         $exprs[0] = "' '";
4322     }
4323
4324     $expr = "split(" . join(", ", @exprs) . ")";
4325     if ($ary) {
4326         return $self->maybe_parens("$ary = $expr", $cx, 7);
4327     } else {
4328         return $expr;
4329     }
4330 }
4331
4332 # oxime -- any of various compounds obtained chiefly by the action of
4333 # hydroxylamine on aldehydes and ketones and characterized by the
4334 # bivalent grouping C=NOH [Webster's Tenth]
4335
4336 my %substwords;
4337 map($substwords{join "", sort split //, $_} = $_, 'ego', 'egoism', 'em',
4338     'es', 'ex', 'exes', 'gee', 'go', 'goes', 'ie', 'ism', 'iso', 'me',
4339     'meese', 'meso', 'mig', 'mix', 'os', 'ox', 'oxime', 'see', 'seem',
4340     'seg', 'sex', 'sig', 'six', 'smog', 'sog', 'some', 'xi',
4341     'sir', 'rise', 'smore', 'more', 'seer', 'rome', 'gore', 'grim', 'grime',
4342     'or', 'rose', 'rosie');
4343
4344 sub pp_subst {
4345     my $self = shift;
4346     my($op, $cx) = @_;
4347     my $kid = $op->first;
4348     my($binop, $var, $re, $repl) = ("", "", "", "");
4349     if ($op->flags & OPf_STACKED) {
4350         $binop = 1;
4351         $var = $self->deparse($kid, 20);
4352         $kid = $kid->sibling;
4353     }
4354     my $flags = "";
4355     if (null($op->pmreplroot)) {
4356         $repl = $self->dq($kid);
4357         $kid = $kid->sibling;
4358     } else {
4359         $repl = $op->pmreplroot->first; # skip substcont
4360         while ($repl->name eq "entereval") {
4361             $repl = $repl->first;
4362             $flags .= "e";
4363         }
4364         if ($op->pmflags & PMf_EVAL) {
4365             $repl = $self->deparse($repl->first, 0);
4366         } else {
4367             $repl = $self->dq($repl);   
4368         }
4369     }
4370     my $extended = ($op->pmflags & PMf_EXTENDED);
4371     if (null $kid) {
4372         my $unbacked = re_unback($op->precomp);