xref: /openbsd-src/gnu/usr.bin/perl/lib/B/Deparse.pm (revision 53555c846a0a6f917dbd0a191f826da995ab1c42)
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
10package B::Deparse 1.74;
11use strict;
12use Carp;
13use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
14	 OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
15	 OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL OPf_MOD OPf_PARENS
16	 OPpLVAL_INTRO OPpOUR_INTRO OPpENTERSUB_AMPER OPpSLICE OPpKVSLICE
17         OPpCONST_BARE OPpEMPTYAVHV_IS_HV
18	 OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY
19	 OPpEXISTS_SUB OPpSORT_NUMERIC OPpSORT_INTEGER OPpREPEAT_DOLIST
20	 OPpSORT_REVERSE OPpMULTIDEREF_EXISTS OPpMULTIDEREF_DELETE
21         OPpSPLIT_ASSIGN OPpSPLIT_LEX
22         OPpPADHV_ISKEYS OPpRV2HV_ISKEYS
23         OPpCONCAT_NESTED
24         OPpMULTICONCAT_APPEND OPpMULTICONCAT_STRINGIFY OPpMULTICONCAT_FAKE
25         OPpTRUEBOOL OPpINDEX_BOOLNEG OPpDEFER_FINALLY
26         OPpARG_IF_UNDEF OPpARG_IF_FALSE
27	 SVf_IOK SVf_NOK SVf_ROK SVf_POK SVf_FAKE SVs_RMG SVs_SMG
28	 SVs_PADTMP
29         CVf_NOWARN_AMBIGUOUS CVf_LVALUE
30	 PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE
31	 PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED PMf_EXTENDED_MORE
32	 PADNAMEf_OUTER PADNAMEf_OUR PADNAMEf_TYPED
33        MDEREF_reload
34        MDEREF_AV_pop_rv2av_aelem
35        MDEREF_AV_gvsv_vivify_rv2av_aelem
36        MDEREF_AV_padsv_vivify_rv2av_aelem
37        MDEREF_AV_vivify_rv2av_aelem
38        MDEREF_AV_padav_aelem
39        MDEREF_AV_gvav_aelem
40        MDEREF_HV_pop_rv2hv_helem
41        MDEREF_HV_gvsv_vivify_rv2hv_helem
42        MDEREF_HV_padsv_vivify_rv2hv_helem
43        MDEREF_HV_vivify_rv2hv_helem
44        MDEREF_HV_padhv_helem
45        MDEREF_HV_gvhv_helem
46        MDEREF_ACTION_MASK
47        MDEREF_INDEX_none
48        MDEREF_INDEX_const
49        MDEREF_INDEX_padsv
50        MDEREF_INDEX_gvsv
51        MDEREF_INDEX_MASK
52        MDEREF_FLAG_last
53        MDEREF_MASK
54        MDEREF_SHIFT
55    );
56
57our $AUTOLOAD;
58use warnings ();
59require feature;
60
61use Config;
62
63BEGIN {
64    # List version-specific constants here.
65    # Easiest way to keep this code portable between version looks to
66    # be to fake up a dummy constant that will never actually be true.
67    foreach (qw(OPpSORT_INPLACE OPpSORT_DESCEND OPpITER_REVERSED OPpCONST_NOVER
68		OPpPAD_STATE PMf_SKIPWHITE RXf_SKIPWHITE
69		PMf_CHARSET PMf_KEEPCOPY PMf_NOCAPTURE CVf_ANONCONST
70		CVf_LOCKED OPpREVERSE_INPLACE OPpSUBSTR_REPL_FIRST
71		PMf_NONDESTRUCT OPpEVAL_BYTES
72		OPpLVREF_TYPE OPpLVREF_SV OPpLVREF_AV OPpLVREF_HV
73		OPpLVREF_CV OPpLVREF_ELEM SVpad_STATE)) {
74	eval { B->import($_) };
75	no strict 'refs';
76	*{$_} = sub () {0} unless *{$_}{CODE};
77    }
78}
79
80# Todo:
81#  (See also BUGS section at the end of this file)
82#
83# - finish tr/// changes
84# - add option for even more parens (generalize \&foo change)
85# - left/right context
86# - copy comments (look at real text with $^P?)
87# - avoid semis in one-statement blocks
88# - associativity of &&=, ||=, ?:
89# - ',' => '=>' (auto-unquote?)
90# - break long lines ("\r" as discretionary break?)
91# - configurable syntax highlighting: ANSI color, HTML, TeX, etc.
92# - more style options: brace style, hex vs. octal, quotes, ...
93# - print big ints as hex/octal instead of decimal (heuristic?)
94# - handle 'my $x if 0'?
95# - version using op_next instead of op_first/sibling?
96# - avoid string copies (pass arrays, one big join?)
97# - here-docs?
98
99# Current test.deparse failures
100# comp/hints 6 - location of BEGIN blocks wrt. block openings
101# run/switchI 1 - missing -I switches entirely
102#    perl -Ifoo -e 'print @INC'
103# op/caller 2 - warning mask propagates backwards before warnings::register
104#    'use warnings; BEGIN {${^WARNING_BITS} eq "U"x12;} use warnings::register'
105# op/getpid 2 - can't assign to shared my() declaration (threads only)
106#    'my $x : shared = 5'
107# op/override 7 - parens on overridden require change v-string interpretation
108#    'BEGIN{*CORE::GLOBAL::require=sub {}} require v5.6'
109#    c.f. 'BEGIN { *f = sub {0} }; f 2'
110# op/pat 774 - losing Unicode-ness of Latin1-only strings
111#    'use charnames ":short"; $x="\N{latin:a with acute}"'
112# op/recurse 12 - missing parens on recursive call makes it look like method
113#    'sub f { f($x) }'
114# op/subst 90 - inconsistent handling of utf8 under "use utf8"
115# op/taint 29 - "use re 'taint'" deparsed in the wrong place wrt. block open
116# op/tiehandle compile - "use strict" deparsed in the wrong place
117# uni/tr_ several
118# ext/B/t/xref 11 - line numbers when we add newlines to one-line subs
119# ext/Data/Dumper/t/dumper compile
120# ext/DB_file/several
121# ext/Encode/several
122# ext/Ernno/Errno warnings
123# ext/IO/lib/IO/t/io_sel 23
124# ext/PerlIO/t/encoding compile
125# ext/POSIX/t/posix 6
126# ext/Socket/Socket 8
127# ext/Storable/t/croak compile
128# lib/Attribute/Handlers/t/multi compile
129# lib/bignum/ several
130# lib/charnames 35
131# lib/constant 32
132# lib/English 40
133# lib/ExtUtils/t/bytes 4
134# lib/File/DosGlob compile
135# lib/Filter/Simple/t/data 1
136# lib/Math/BigInt/t/constant 1
137# lib/Net/t/config Deparse-warning
138# lib/overload compile
139# lib/Switch/ several
140# lib/Symbol 4
141# lib/Test/Simple several
142# lib/Term/Complete
143# lib/Tie/File/t/29_downcopy 5
144# lib/vars 22
145
146# Object fields:
147#
148# in_coderef2text:
149# True when deparsing via $deparse->coderef2text; false when deparsing the
150# main program.
151#
152# avoid_local:
153# (local($a), local($b)) and local($a, $b) have the same internal
154# representation but the short form looks better. We notice we can
155# use a large-scale local when checking the list, but need to prevent
156# individual locals too. This hash holds the addresses of OPs that
157# have already had their local-ness accounted for. The same thing
158# is done with my().
159#
160# curcv:
161# CV for current sub (or main program) being deparsed
162#
163# curcvlex:
164# Cached hash of lexical variables for curcv: keys are
165# names prefixed with "m" or "o" (representing my/our), and
166# each value is an array with two elements indicating the cop_seq
167# of scopes in which a var of that name is valid and a third ele-
168# ment referencing the pad name.
169#
170# curcop:
171# COP for statement being deparsed
172#
173# curstash:
174# name of the current package for deparsed code
175#
176# subs_todo:
177# array of [cop_seq, CV, is_format?, name] for subs and formats we still
178# want to deparse.  The fourth element is a pad name thingy for lexical
179# subs or a string for special blocks.  For other subs, it is undef.  For
180# lexical subs, CV may be undef, indicating a stub declaration.
181#
182# protos_todo:
183# as above, but [name, prototype] for subs that never got a GV
184#
185# subs_done, forms_done:
186# keys are addresses of GVs for subs and formats we've already
187# deparsed (or at least put into subs_todo)
188#
189# subs_declared
190# keys are names of subs for which we've printed declarations.
191# That means we can omit parentheses from the arguments. It also means we
192# need to put CORE:: on core functions of the same name.
193#
194# in_subst_repl
195# True when deparsing the replacement part of a substitution.
196#
197# in_refgen
198# True when deparsing the argument to \.
199#
200# parens: -p
201# linenums: -l
202# unquote: -q
203# cuddle: ' ' or '\n', depending on -sC
204# indent_size: -si
205# use_tabs: -sT
206# ex_const: -sv
207
208# A little explanation of how precedence contexts and associativity
209# work:
210#
211# deparse() calls each per-op subroutine with an argument $cx (short
212# for context, but not the same as the cx* in the perl core), which is
213# a number describing the op's parents in terms of precedence, whether
214# they're inside an expression or at statement level, etc.  (see
215# chart below). When ops with children call deparse on them, they pass
216# along their precedence. Fractional values are used to implement
217# associativity ('($x + $y) + $z' => '$x + $y + $y') and related
218# parentheses hacks. The major disadvantage of this scheme is that
219# it doesn't know about right sides and left sides, so say if you
220# assign a listop to a variable, it can't tell it's allowed to leave
221# the parens off the listop.
222
223# Precedences:
224# 26             [TODO] inside interpolation context ("")
225# 25 left        terms and list operators (leftward)
226# 24 left        ->
227# 23 nonassoc    ++ --
228# 22 right       **
229# 21 right       ! ~ \ and unary + and -
230# 20 left        =~ !~
231# 19 left        * / % x
232# 18 left        + - .
233# 17 left        << >>
234# 16 nonassoc    named unary operators
235# 15 nonassoc    < > <= >= lt gt le ge
236# 14 nonassoc    == != <=> eq ne cmp
237# 13 left        &
238# 12 left        | ^
239# 11 left        &&
240# 10 left        ||
241#  9 nonassoc    ..  ...
242#  8 right       ?:
243#  7 right       = += -= *= etc.
244#  6 left        , =>
245#  5 nonassoc    list operators (rightward)
246#  4 right       not
247#  3 left        and
248#  2 left        or xor
249#  1             statement modifiers
250#  0.5           statements, but still print scopes as do { ... }
251#  0             statement level
252# -1             format body
253
254# Nonprinting characters with special meaning:
255# \cS - steal parens (see maybe_parens_unop)
256# \n - newline and indent
257# \t - increase indent
258# \b - decrease indent ('outdent')
259# \f - flush left (no indent)
260# \cK - kill following semicolon, if any
261
262# Semicolon handling:
263#  - Individual statements are not deparsed with trailing semicolons.
264#    (If necessary, \cK is tacked on to the end.)
265#  - Whatever code joins statements together or emits them (lineseq,
266#    scopeop, deparse_root) is responsible for adding semicolons where
267#    necessary.
268#  - use statements are deparsed with trailing semicolons because they are
269#    immediately concatenated with the following statement.
270#  - indent() removes semicolons wherever it sees \cK.
271
272
273BEGIN { for (qw[ const stringify rv2sv list glob pushmark null aelem
274		 kvaslice kvhslice padsv argcheck
275                 nextstate dbstate rv2av rv2hv helem pushdefer leavetrycatch
276                 custom ]) {
277    eval "sub OP_\U$_ () { " . opnumber($_) . "}"
278}}
279
280# _pessimise_walk(): recursively walk the optree of a sub,
281# possibly undoing optimisations along the way.
282
283sub DEBUG { 0 }
284use if DEBUG, 'Data::Dumper';
285
286sub _pessimise_walk {
287    my ($self, $startop) = @_;
288
289    return unless $$startop;
290    my ($op, $prevop);
291    for ($op = $startop; $$op; $prevop = $op, $op = $op->sibling) {
292	my $ppname = $op->name;
293
294	# pessimisations start here
295
296	if ($ppname eq "padrange") {
297	    # remove PADRANGE:
298	    # the original optimisation either (1) changed this:
299	    #    pushmark -> (various pad and list and null ops) -> the_rest
300	    # or (2), for the = @_ case, changed this:
301	    #    pushmark -> gv[_] -> rv2av -> (pad stuff)       -> the_rest
302	    # into this:
303	    #    padrange ----------------------------------------> the_rest
304	    # so we just need to convert the padrange back into a
305	    # pushmark, and in case (1), set its op_next to op_sibling,
306	    # which is the head of the original chain of optimised-away
307	    # pad ops, or for (2), set it to sibling->first, which is
308	    # the original gv[_].
309
310	    $B::overlay->{$$op} = {
311		    type => OP_PUSHMARK,
312		    name => 'pushmark',
313		    private => ($op->private & OPpLVAL_INTRO),
314	    };
315	}
316
317	# pessimisations end here
318
319	if (class($op) eq 'PMOP') {
320	    if (ref($op->pmreplroot)
321                && ${$op->pmreplroot}
322                && $op->pmreplroot->isa( 'B::OP' ))
323            {
324                $self-> _pessimise_walk($op->pmreplroot);
325            }
326
327            # pessimise any /(?{...})/ code blocks
328            my ($re, $cv);
329            my $code_list = $op->code_list;
330            if ($$code_list) {
331                $self->_pessimise_walk($code_list);
332            }
333            elsif (${$re = $op->pmregexp} && ${$cv = $re->qr_anoncv}) {
334                $code_list = $cv->ROOT      # leavesub
335                               ->first      #   qr
336                               ->code_list; #     list
337                $self->_pessimise_walk($code_list);
338            }
339        }
340
341	if ($op->flags & OPf_KIDS) {
342	    $self-> _pessimise_walk($op->first);
343	}
344
345    }
346}
347
348
349# _pessimise_walk_exe(): recursively walk the op_next chain of a sub,
350# possibly undoing optimisations along the way.
351
352sub _pessimise_walk_exe {
353    my ($self, $startop, $visited) = @_;
354
355    no warnings 'recursion';
356
357    return unless $$startop;
358    return if $visited->{$$startop};
359    my ($op, $prevop);
360    for ($op = $startop; $$op; $prevop = $op, $op = $op->next) {
361	last if $visited->{$$op};
362	$visited->{$$op} = 1;
363	my $ppname = $op->name;
364	if ($ppname =~
365	    /^((and|d?or)(assign)?|(map|grep)while|range|cond_expr|once)$/
366	    # entertry is also a logop, but its op_other invariably points
367	    # into the same chain as the main execution path, so we skip it
368	) {
369	    $self->_pessimise_walk_exe($op->other, $visited);
370	}
371	elsif ($ppname eq "subst") {
372	    $self->_pessimise_walk_exe($op->pmreplstart, $visited);
373	}
374	elsif ($ppname =~ /^(enter(loop|iter))$/) {
375	    # redoop and nextop will already be covered by the main block
376	    # of the loop
377	    $self->_pessimise_walk_exe($op->lastop, $visited);
378	}
379
380	# pessimisations start here
381    }
382}
383
384# Go through an optree and "remove" some optimisations by using an
385# overlay to selectively modify or un-null some ops. Deparsing in the
386# absence of those optimisations is then easier.
387#
388# Note that older optimisations are not removed, as Deparse was already
389# written to recognise them before the pessimise/overlay system was added.
390
391sub pessimise {
392    my ($self, $root, $start) = @_;
393
394    no warnings 'recursion';
395    # walk tree in root-to-branch order
396    $self->_pessimise_walk($root);
397
398    my %visited;
399    # walk tree in execution order
400    $self->_pessimise_walk_exe($start, \%visited);
401}
402
403
404sub null {
405    my $op = shift;
406    return class($op) eq "NULL";
407}
408
409
410# Add a CV to the list of subs that still need deparsing.
411
412sub todo {
413    my $self = shift;
414    my($cv, $is_form, $name) = @_;
415    my $cvfile = $cv->FILE//'';
416    return unless ($cvfile eq $0 || exists $self->{files}{$cvfile});
417    my $seq;
418    if ($cv->OUTSIDE_SEQ) {
419	$seq = $cv->OUTSIDE_SEQ;
420    } elsif (!null($cv->START) and is_state($cv->START)) {
421	$seq = $cv->START->cop_seq;
422    } else {
423	$seq = 0;
424    }
425    my $stash = $cv->STASH;
426    if (class($stash) eq 'HV') {
427        $self->{packs}{$stash->NAME}++;
428    }
429    push @{$self->{'subs_todo'}}, [$seq, $cv, $is_form, $name];
430}
431
432
433# Pop the next sub from the todo list and deparse it
434
435sub next_todo {
436    my $self = shift;
437    my $ent = shift @{$self->{'subs_todo'}};
438    my ($seq, $cv, $is_form, $name) = @$ent;
439
440    # any 'use strict; package foo' that should come before the sub
441    # declaration to sync with the first COP of the sub
442    my $pragmata = '';
443    if ($cv and !null($cv->START) and is_state($cv->START))  {
444        $pragmata = $self->pragmata($cv->START);
445    }
446
447    if (ref $name) { # lexical sub
448	# emit the sub.
449	my @text;
450	my $flags = $name->FLAGS;
451        my $category =
452	    !$cv || $seq <= $name->COP_SEQ_RANGE_LOW
453		? $self->keyword($flags & PADNAMEf_OUR
454				    ? "our"
455				    : $flags & SVpad_STATE
456					? "state"
457					: "my") . " "
458		: "";
459
460        # Skip lexical 'state' subs imported from the builtin::
461        # package, since they are created automatically by
462        #     use builtin "foo"
463        if ($cv && $category =~  /\bstate\b/) {
464            my $globname;
465            my $gv = $cv->GV;
466            if (
467                   $gv
468                && defined (($globname = $gv->object_2svref))
469                && $$globname =~ /^\*builtin::/
470            ) {
471                return '';
472            }
473        }
474
475	push @text, $category;
476
477	# XXX We would do $self->keyword("sub"), but ‘my CORE::sub’
478	#     doesn’t work and ‘my sub’ ignores a &sub in scope.  I.e.,
479	#     we have a core bug here.
480	push @text, "sub " . substr $name->PVX, 1;
481	if ($cv) {
482	    # my sub foo { }
483	    push @text,  " " . $self->deparse_sub($cv);
484	    $text[-1] =~ s/ ;$/;/;
485	}
486	else {
487	    # my sub foo;
488	    push @text, ";\n";
489	}
490	return $pragmata . join "", @text;
491    }
492
493    my $gv = $cv->GV;
494    $name //= $self->gv_name($gv);
495    if ($is_form) {
496	return $pragmata . $self->keyword("format") . " $name =\n"
497	    . $self->deparse_format($cv). "\n";
498    } else {
499	my $use_dec;
500	if ($name eq "BEGIN") {
501	    $use_dec = $self->begin_is_use($cv);
502	    if (defined ($use_dec) and $self->{'expand'} < 5) {
503		return $pragmata if 0 == length($use_dec);
504
505                #  XXX bit of a hack: Test::More's use_ok() method
506                #  builds a fake use statement which deparses as, e.g.
507                #      use Net::Ping (@{$args[0];});
508                #  As well as being superfluous (the use_ok() is deparsed
509                #  too) and ugly, it fails under use strict and otherwise
510                #  makes use of a lexical var that's not in scope.
511                #  So strip it out.
512                return $pragmata
513                        if $use_dec =~
514                            m/
515                                \A
516                                use \s \S+ \s \(\@\{
517                                (
518                                    \s*\#line\ \d+\ \".*"\s*
519                                )?
520                                \$args\[0\];\}\);
521                                \n
522                                \Z
523                            /x;
524
525		$use_dec =~ s/^(use|no)\b/$self->keyword($1)/e;
526	    }
527	}
528	my $l = '';
529	if ($self->{'linenums'}) {
530	    my $line = $gv->LINE;
531	    my $file = $gv->FILE;
532	    $l = "\n\f#line $line \"$file\"\n";
533	}
534	my $p = '';
535	my $stash;
536	if (class($cv->STASH) ne "SPECIAL") {
537	    $stash = $cv->STASH->NAME;
538	    if ($stash ne $self->{'curstash'}) {
539		$p = $self->keyword("package") . " $stash;\n";
540		$name = "$self->{'curstash'}::$name" unless $name =~ /::/;
541		$self->{'curstash'} = $stash;
542	    }
543	}
544	if ($use_dec) {
545	    return "$pragmata$p$l$use_dec";
546	}
547        if ( $name !~ /::/ and $self->lex_in_scope("&$name")
548                            || $self->lex_in_scope("&$name", 1) )
549        {
550            $name = "$self->{'curstash'}::$name";
551        } elsif (defined $stash) {
552            $name =~ s/^\Q$stash\E::(?!\z|.*::)//;
553        }
554	my $ret = "$pragmata${p}${l}" . $self->keyword("sub") . " $name "
555	      . $self->deparse_sub($cv);
556	$self->{'subs_declared'}{$name} = 1;
557	return $ret;
558    }
559}
560
561
562# Return a "use" declaration for this BEGIN block, if appropriate
563sub begin_is_use {
564    my ($self, $cv) = @_;
565    my $root = $cv->ROOT;
566    local @$self{qw'curcv curcvlex'} = ($cv);
567    local $B::overlay = {};
568    $self->pessimise($root, $cv->START);
569#require B::Debug;
570#B::walkoptree($cv->ROOT, "debug");
571    my $lineseq = $root->first;
572    return if $lineseq->name ne "lineseq";
573
574    my $req_op = $lineseq->first->sibling;
575    return if $req_op->name ne "require";
576
577    # maybe it's C<require expr> rather than C<require 'foo'>
578    return if ($req_op->first->name ne 'const');
579
580    my $module;
581    if ($req_op->first->private & OPpCONST_BARE) {
582	# Actually it should always be a bareword
583	$module = $self->const_sv($req_op->first)->PV;
584	$module =~ s[/][::]g;
585	$module =~ s/.pm$//;
586    }
587    else {
588	$module = $self->const($self->const_sv($req_op->first), 6);
589    }
590
591    my $version;
592    my $version_op = $req_op->sibling;
593    return if class($version_op) eq "NULL";
594    if ($version_op->name eq "lineseq") {
595	# We have a version parameter; skip nextstate & pushmark
596	my $constop = $version_op->first->next->next;
597
598	return unless $self->const_sv($constop)->PV eq $module;
599	$constop = $constop->sibling;
600	$version = $self->const_sv($constop);
601	if (class($version) eq "IV") {
602	    $version = $version->int_value;
603	} elsif (class($version) eq "NV") {
604	    $version = $version->NV;
605	} elsif (class($version) ne "PVMG") {
606	    # Includes PVIV and PVNV
607	    $version = $version->PV;
608	} else {
609	    # version specified as a v-string
610	    $version = 'v'.join '.', map ord, split //, $version->PV;
611	}
612	$constop = $constop->sibling;
613	return if $constop->name ne "method_named";
614	return if $self->meth_sv($constop)->PV ne "VERSION";
615    }
616
617    $lineseq = $version_op->sibling;
618    return if $lineseq->name ne "lineseq";
619    my $entersub = $lineseq->first->sibling;
620    if ($entersub->name eq "stub") {
621	return "use $module $version ();\n" if defined $version;
622	return "use $module ();\n";
623    }
624    return if $entersub->name ne "entersub";
625
626    # See if there are import arguments
627    my $args = '';
628
629    my $svop = $entersub->first->sibling; # Skip over pushmark
630    return unless $self->const_sv($svop)->PV eq $module;
631
632    # Pull out the arguments
633    for ($svop=$svop->sibling; index($svop->name, "method_") != 0;
634		$svop = $svop->sibling) {
635	$args .= ", " if length($args);
636	$args .= $self->deparse($svop, 6);
637    }
638
639    my $use = 'use';
640    my $method_named = $svop;
641    return if $method_named->name ne "method_named";
642    my $method_name = $self->meth_sv($method_named)->PV;
643
644    if ($method_name eq "unimport") {
645	$use = 'no';
646    }
647
648    # Certain pragmas are dealt with using hint bits,
649    # so we ignore them here
650    if ($module eq 'strict' || $module eq 'integer'
651	|| $module eq 'bytes' || $module eq 'warnings'
652	|| $module eq 'feature') {
653	return "";
654    }
655
656    if (defined $version && length $args) {
657	return "$use $module $version ($args);\n";
658    } elsif (defined $version) {
659	return "$use $module $version;\n";
660    } elsif (length $args) {
661	return "$use $module ($args);\n";
662    } else {
663	return "$use $module;\n";
664    }
665}
666
667sub stash_subs {
668    my ($self, $pack, $seen) = @_;
669    my (@ret, $stash);
670    if (!defined $pack) {
671	$pack = '';
672	$stash = \%::;
673    }
674    else {
675	$pack =~ s/(::)?$/::/;
676	no strict 'refs';
677	$stash = \%{"main::$pack"};
678    }
679    return
680	if ($seen ||= {})->{
681	    $INC{"overload.pm"} ? overload::StrVal($stash) : $stash
682	   }++;
683    my $stashobj = svref_2object($stash);
684    my %stash = $stashobj->ARRAY;
685    while (my ($key, $val) = each %stash) {
686	my $flags = $val->FLAGS;
687	if ($flags & SVf_ROK) {
688	    # A reference.  Dump this if it is a reference to a CV.  If it
689	    # is a constant acting as a proxy for a full subroutine, then
690	    # we may or may not have to dump it.  If some form of perl-
691	    # space visible code must have created it, be it a use
692	    # statement, or some direct symbol-table manipulation code that
693	    # we will deparse, then we don’t want to dump it.  If it is the
694	    # result of a declaration like sub f () { 42 } then we *do*
695	    # want to dump it.  The only way to distinguish these seems
696	    # to be the SVs_PADTMP flag on the constant, which is admit-
697	    # tedly a hack.
698	    my $class = class(my $referent = $val->RV);
699	    if ($class eq "CV") {
700		$self->todo($referent, 0);
701	    } elsif (
702		$class !~ /^(AV|HV|CV|FM|IO|SPECIAL)\z/
703		# A more robust way to write that would be this, but B does
704		# not provide the SVt_ constants:
705		# ($referent->FLAGS & B::SVTYPEMASK) < B::SVt_PVAV
706		and $referent->FLAGS & SVs_PADTMP
707	    ) {
708		push @{$self->{'protos_todo'}}, [$pack . $key, $val];
709	    }
710	} elsif ($flags & (SVf_POK|SVf_IOK)) {
711	    # Just a prototype. As an ugly but fairly effective way
712	    # to find out if it belongs here is to see if the AUTOLOAD
713	    # (if any) for the stash was defined in one of our files.
714	    my $A = $stash{"AUTOLOAD"};
715	    if (defined ($A) && class($A) eq "GV" && defined($A->CV)
716		&& class($A->CV) eq "CV") {
717		my $AF = $A->FILE;
718		next unless $AF eq $0 || exists $self->{'files'}{$AF};
719	    }
720	    push @{$self->{'protos_todo'}},
721		 [$pack . $key, $flags & SVf_POK ? $val->PV: undef];
722	} elsif (class($val) eq "GV") {
723	    if (class(my $cv = $val->CV) ne "SPECIAL") {
724		next if $self->{'subs_done'}{$$val}++;
725
726                # Ignore imposters (aliases etc)
727                my $name = $cv->NAME_HEK;
728                if(defined $name) {
729                    # avoid using $cv->GV here because if the $val GV is
730                    # an alias, CvGV() could upgrade the real stash entry
731                    # from an RV to a GV
732                    next unless $name eq $key;
733                    next unless $$stashobj == ${$cv->STASH};
734                }
735                else {
736                   next if $$val != ${$cv->GV};
737                }
738
739		$self->todo($cv, 0);
740	    }
741	    if (class(my $cv = $val->FORM) ne "SPECIAL") {
742		next if $self->{'forms_done'}{$$val}++;
743		next if $$val != ${$cv->GV};   # Ignore imposters
744		$self->todo($cv, 1);
745	    }
746	    if (class($val->HV) ne "SPECIAL" && $key =~ /::$/) {
747		$self->stash_subs($pack . $key, $seen);
748	    }
749	}
750    }
751}
752
753sub print_protos {
754    my $self = shift;
755    my $ar;
756    my @ret;
757    foreach $ar (@{$self->{'protos_todo'}}) {
758	if (ref $ar->[1]) {
759	    # Only print a constant if it occurs in the same package as a
760	    # dumped sub.  This is not perfect, but a heuristic that will
761	    # hopefully work most of the time.  Ideally we would use
762	    # CvFILE, but a constant stub has no CvFILE.
763	    my $pack = ($ar->[0] =~ /(.*)::/)[0];
764	    next if $pack and !$self->{packs}{$pack}
765	}
766	my $body = defined $ar->[1]
767		? ref $ar->[1]
768		    ? " () {\n    " . $self->const($ar->[1]->RV,0) . ";\n}"
769		    : " (". $ar->[1] . ");"
770		: ";";
771	push @ret, "sub " . $ar->[0] .  "$body\n";
772    }
773    delete $self->{'protos_todo'};
774    return @ret;
775}
776
777sub style_opts {
778    my $self = shift;
779    my $opts = shift;
780    my $opt;
781    while (length($opt = substr($opts, 0, 1))) {
782	if ($opt eq "C") {
783	    $self->{'cuddle'} = " ";
784	    $opts = substr($opts, 1);
785	} elsif ($opt eq "i") {
786	    $opts =~ s/^i(\d+)//;
787	    $self->{'indent_size'} = $1;
788	} elsif ($opt eq "T") {
789	    $self->{'use_tabs'} = 1;
790	    $opts = substr($opts, 1);
791	} elsif ($opt eq "v") {
792	    $opts =~ s/^v([^.]*)(.|$)//;
793	    $self->{'ex_const'} = $1;
794	}
795    }
796}
797
798sub new {
799    my $class = shift;
800    my $self = bless {}, $class;
801    $self->{'cuddle'} = "\n";
802    $self->{'curcop'} = undef;
803    $self->{'curstash'} = "main";
804    $self->{'ex_const'} = "'???'";
805    $self->{'expand'} = 0;
806    $self->{'files'} = {};
807    $self->{'packs'} = {};
808    $self->{'indent_size'} = 4;
809    $self->{'linenums'} = 0;
810    $self->{'parens'} = 0;
811    $self->{'subs_todo'} = [];
812    $self->{'unquote'} = 0;
813    $self->{'use_dumper'} = 0;
814    $self->{'use_tabs'} = 0;
815
816    $self->{'ambient_warnings'} = undef; # Assume no lexical warnings
817    $self->{'ambient_hints'} = 0;
818    $self->{'ambient_hinthash'} = undef;
819    $self->init();
820
821    while (my $arg = shift @_) {
822	if ($arg eq "-d") {
823	    $self->{'use_dumper'} = 1;
824	    require Data::Dumper;
825	} elsif ($arg =~ /^-f(.*)/) {
826	    $self->{'files'}{$1} = 1;
827	} elsif ($arg eq "-l") {
828	    $self->{'linenums'} = 1;
829	} elsif ($arg eq "-p") {
830	    $self->{'parens'} = 1;
831	} elsif ($arg eq "-P") {
832	    $self->{'noproto'} = 1;
833	} elsif ($arg eq "-q") {
834	    $self->{'unquote'} = 1;
835	} elsif (substr($arg, 0, 2) eq "-s") {
836	    $self->style_opts(substr $arg, 2);
837	} elsif ($arg =~ /^-x(\d)$/) {
838	    $self->{'expand'} = $1;
839	}
840    }
841    return $self;
842}
843
844
845# Initialise the contextual information, either from
846# defaults provided with the ambient_pragmas method,
847# or from perl's own defaults otherwise.
848sub init {
849    my $self = shift;
850
851    $self->{'warnings'} = $self->{'ambient_warnings'};
852    $self->{'hints'}    = $self->{'ambient_hints'};
853    $self->{'hinthash'} = $self->{'ambient_hinthash'};
854
855    # also a convenient place to clear out subs_declared
856    delete $self->{'subs_declared'};
857}
858
859sub compile {
860    my(@args) = @_;
861    return sub {
862	my $self = B::Deparse->new(@args);
863	# First deparse command-line args
864	if (defined $^I) { # deparse -i
865	    print q(BEGIN { $^I = ).perlstring($^I).qq(; }\n);
866	}
867	if ($^W) { # deparse -w
868	    print qq(BEGIN { \$^W = $^W; }\n);
869	}
870	if ($/ ne "\n" or defined $O::savebackslash) { # deparse -l and -0
871	    my $fs = perlstring($/) || 'undef';
872	    my $bs = perlstring($O::savebackslash) || 'undef';
873	    print qq(BEGIN { \$/ = $fs; \$\\ = $bs; }\n);
874	}
875	my @BEGINs  = B::begin_av->isa("B::AV") ? B::begin_av->ARRAY : ();
876	my @UNITCHECKs = B::unitcheck_av->isa("B::AV")
877	    ? B::unitcheck_av->ARRAY
878	    : ();
879	my @CHECKs  = B::check_av->isa("B::AV") ? B::check_av->ARRAY : ();
880	my @INITs   = B::init_av->isa("B::AV") ? B::init_av->ARRAY : ();
881	my @ENDs    = B::end_av->isa("B::AV") ? B::end_av->ARRAY : ();
882	my @names = qw(BEGIN UNITCHECK CHECK INIT END);
883	my @blocks = \(@BEGINs, @UNITCHECKs, @CHECKs, @INITs, @ENDs);
884	while (@names) {
885	    my ($name, $blocks) = (shift @names, shift @blocks);
886	    for my $block (@$blocks) {
887		$self->todo($block, 0, $name);
888	    }
889	}
890	$self->stash_subs();
891	local($SIG{"__DIE__"}) =
892	  sub {
893	      if ($self->{'curcop'}) {
894		  my $cop = $self->{'curcop'};
895		  my($line, $file) = ($cop->line, $cop->file);
896		  print STDERR "While deparsing $file near line $line,\n";
897	      }
898	    };
899	$self->{'curcv'} = main_cv;
900	$self->{'curcvlex'} = undef;
901	print $self->print_protos;
902	@{$self->{'subs_todo'}} =
903	  sort {$a->[0] <=> $b->[0]} @{$self->{'subs_todo'}};
904	my $root = main_root;
905	local $B::overlay = {};
906	unless (null $root) {
907	    $self->pad_subs($self->{'curcv'});
908	    # Check for a stub-followed-by-ex-cop, resulting from a program
909	    # consisting solely of sub declarations.  For backward-compati-
910	    # bility (and sane output) we don’t want to emit the stub.
911	    #   leave
912	    #     enter
913	    #     stub
914	    #     ex-nextstate (or ex-dbstate)
915	    my $kid;
916	    if ( $root->name eq 'leave'
917	     and ($kid = $root->first)->name eq 'enter'
918	     and !null($kid = $kid->sibling) and $kid->name eq 'stub'
919	     and !null($kid = $kid->sibling) and $kid->name eq 'null'
920	     and class($kid) eq 'COP' and null $kid->sibling )
921	    {
922		# ignore
923	    } else {
924		$self->pessimise($root, main_start);
925		print $self->indent($self->deparse_root($root)), "\n";
926	    }
927	}
928	my @text;
929	while (scalar(@{$self->{'subs_todo'}})) {
930	    push @text, $self->next_todo;
931	}
932	print $self->indent(join("", @text)), "\n" if @text;
933
934	# Print __DATA__ section, if necessary
935	no strict 'refs';
936	my $laststash = defined $self->{'curcop'}
937	    ? $self->{'curcop'}->stash->NAME : $self->{'curstash'};
938	if (defined *{$laststash."::DATA"}{IO}) {
939	    print $self->keyword("package") . " $laststash;\n"
940		unless $laststash eq $self->{'curstash'};
941	    print $self->keyword("__DATA__") . "\n";
942	    print readline(*{$laststash."::DATA"});
943	}
944    }
945}
946
947sub coderef2text {
948    my $self = shift;
949    my $sub = shift;
950    croak "Usage: ->coderef2text(CODEREF)" unless UNIVERSAL::isa($sub, "CODE");
951
952    $self->init();
953    local $self->{in_coderef2text} = 1;
954    return $self->indent($self->deparse_sub(svref_2object($sub)));
955}
956
957my %strict_bits = do {
958    local $^H;
959    map +($_ => strict::bits($_)), qw/refs subs vars/
960};
961
962sub ambient_pragmas {
963    my $self = shift;
964    my ($hint_bits, $warning_bits, $hinthash) = (0);
965
966    while (@_ > 1) {
967	my $name = shift();
968	my $val  = shift();
969
970	if ($name eq 'strict') {
971	    require strict;
972
973	    if ($val eq 'none') {
974		$hint_bits &= $strict_bits{$_} for qw/refs subs vars/;
975		next();
976	    }
977
978	    my @names;
979	    if ($val eq "all") {
980		@names = qw/refs subs vars/;
981	    }
982	    elsif (ref $val) {
983		@names = @$val;
984	    }
985	    else {
986		@names = split' ', $val;
987	    }
988	    $hint_bits |= $strict_bits{$_} for @names;
989	}
990
991	elsif ($name eq 'integer'
992	    || $name eq 'bytes'
993	    || $name eq 'utf8') {
994	    require "$name.pm";
995	    if ($val) {
996		$hint_bits |= ${$::{"${name}::"}{"hint_bits"}};
997	    }
998	    else {
999		$hint_bits &= ~${$::{"${name}::"}{"hint_bits"}};
1000	    }
1001	}
1002
1003	elsif ($name eq 're') {
1004	    require re;
1005	    if ($val eq 'none') {
1006		$hint_bits &= ~re::bits(qw/taint eval/);
1007		next();
1008	    }
1009
1010	    my @names;
1011	    if ($val eq 'all') {
1012		@names = qw/taint eval/;
1013	    }
1014	    elsif (ref $val) {
1015		@names = @$val;
1016	    }
1017	    else {
1018		@names = split' ',$val;
1019	    }
1020	    $hint_bits |= re::bits(@names);
1021	}
1022
1023	elsif ($name eq 'warnings') {
1024	    if ($val eq 'none') {
1025		$warning_bits = $warnings::NONE;
1026		next();
1027	    }
1028
1029	    my @names;
1030	    if (ref $val) {
1031		@names = @$val;
1032	    }
1033	    else {
1034		@names = split/\s+/, $val;
1035	    }
1036
1037	    $warning_bits = $warnings::NONE if !defined ($warning_bits);
1038	    $warning_bits |= warnings::bits(@names);
1039	}
1040
1041	elsif ($name eq 'warning_bits') {
1042	    $warning_bits = $val;
1043	}
1044
1045	elsif ($name eq 'hint_bits') {
1046	    $hint_bits = $val;
1047	}
1048
1049	elsif ($name eq '%^H') {
1050	    $hinthash = $val;
1051	}
1052
1053	else {
1054	    croak "Unknown pragma type: $name";
1055	}
1056    }
1057    if (@_) {
1058	croak "The ambient_pragmas method expects an even number of args";
1059    }
1060
1061    $self->{'ambient_warnings'} = $warning_bits;
1062    $self->{'ambient_hints'} = $hint_bits;
1063    $self->{'ambient_hinthash'} = $hinthash;
1064}
1065
1066# This method is the inner loop, so try to keep it simple
1067sub deparse {
1068    my $self = shift;
1069    my($op, $cx) = @_;
1070
1071    Carp::confess("Null op in deparse") if !defined($op)
1072					|| class($op) eq "NULL";
1073    my $meth = "pp_" . $op->name;
1074    return $self->$meth($op, $cx);
1075}
1076
1077sub indent {
1078    my $self = shift;
1079    my $txt = shift;
1080    # \cK also swallows a preceding line break when followed by a
1081    # semicolon.
1082    $txt =~ s/\n\cK;//g;
1083    my @lines = split(/\n/, $txt);
1084    my $leader = "";
1085    my $level = 0;
1086    my $line;
1087    for $line (@lines) {
1088	my $cmd = substr($line, 0, 1);
1089	if ($cmd eq "\t" or $cmd eq "\b") {
1090	    $level += ($cmd eq "\t" ? 1 : -1) * $self->{'indent_size'};
1091	    if ($self->{'use_tabs'}) {
1092		$leader = "\t" x ($level / 8) . " " x ($level % 8);
1093	    } else {
1094		$leader = " " x $level;
1095	    }
1096	    $line = substr($line, 1);
1097	}
1098	if (index($line, "\f") > 0) {
1099		$line =~ s/\f/\n/;
1100	}
1101	if (substr($line, 0, 1) eq "\f") {
1102	    $line = substr($line, 1); # no indent
1103	} else {
1104	    $line = $leader . $line;
1105	}
1106	$line =~ s/\cK;?//g;
1107    }
1108    return join("\n", @lines);
1109}
1110
1111sub pad_subs {
1112    my ($self, $cv) = @_;
1113    my $padlist = $cv->PADLIST;
1114    my @names = $padlist->ARRAYelt(0)->ARRAY;
1115    my @values = $padlist->ARRAYelt(1)->ARRAY;
1116    my @todo;
1117  PADENTRY:
1118    for my $ix (0.. $#names) { for $_ ($names[$ix]) {
1119	next if class($_) eq "SPECIAL";
1120	my $name = $_->PVX;
1121	if (defined $name && $name =~ /^&./) {
1122	    my $low = $_->COP_SEQ_RANGE_LOW;
1123	    my $flags = $_->FLAGS;
1124	    my $outer = $flags & PADNAMEf_OUTER;
1125	    if ($flags & PADNAMEf_OUR) {
1126		push @todo, [$low, undef, 0, $_]
1127		          # [seq, no cv, not format, padname]
1128		    unless $outer;
1129		next;
1130	    }
1131	    my $protocv = $flags & SVpad_STATE
1132		? $values[$ix]
1133		: $_->PROTOCV;
1134	    if (class ($protocv) ne 'CV') {
1135		my $flags = $flags;
1136		my $cv = $cv;
1137		my $name = $_;
1138		while ($flags & PADNAMEf_OUTER && class ($protocv) ne 'CV')
1139		{
1140		    $cv = $cv->OUTSIDE;
1141		    next PADENTRY if class($cv) eq 'SPECIAL'; # XXX freed?
1142		    my $padlist = $cv->PADLIST;
1143		    my $ix = $name->PARENT_PAD_INDEX;
1144		    $name = $padlist->NAMES->ARRAYelt($ix);
1145		    $flags = $name->FLAGS;
1146		    $protocv = $flags & SVpad_STATE
1147			? $padlist->ARRAYelt(1)->ARRAYelt($ix)
1148			: $name->PROTOCV;
1149		}
1150	    }
1151	    my $defined_in_this_sub = ${$protocv->OUTSIDE} == $$cv || do {
1152		my $other = $protocv->PADLIST;
1153		$$other && $other->outid == $padlist->id;
1154	    };
1155	    if ($flags & PADNAMEf_OUTER) {
1156		next unless $defined_in_this_sub;
1157		push @todo, [$protocv->OUTSIDE_SEQ, $protocv, 0, $_];
1158		next;
1159	    }
1160	    my $outseq = $protocv->OUTSIDE_SEQ;
1161	    if ($outseq <= $low) {
1162		# defined before its name is visible, so it’s gotta be
1163		# declared and defined at once: my sub foo { ... }
1164		push @todo, [$low, $protocv, 0, $_];
1165	    }
1166	    else {
1167		# declared and defined separately: my sub f; sub f { ... }
1168		push @todo, [$low, undef, 0, $_];
1169		push @todo, [$outseq, $protocv, 0, $_]
1170		    if $defined_in_this_sub;
1171	    }
1172	}
1173    }}
1174    @{$self->{'subs_todo'}} =
1175	sort {$a->[0] <=> $b->[0]} @{$self->{'subs_todo'}}, @todo
1176}
1177
1178
1179# deparse_argops(): deparse, if possible, a sequence of argcheck + argelem
1180# ops into a subroutine signature. If successful, return the first op
1181# following the signature ops plus the signature string; else return the
1182# empty list.
1183#
1184# Normally a bunch of argelem ops will have been generated by the
1185# signature parsing, but it's possible that ops have been added manually
1186# or altered. In this case we return "()" and fall back to general
1187# deparsing of the individual sigelems as 'my $x = $_[N]' etc.
1188#
1189# We're only called if the top is an ex-argcheck, which is a placeholder
1190# indicating a signature subtree.
1191#
1192# Return a signature string, or an empty list if no deparseable as a
1193# signature
1194
1195sub deparse_argops {
1196    my ($self, $topop, $cv) = @_;
1197
1198    my @sig;
1199
1200
1201    $topop = $topop->first;
1202    return unless $$topop and $topop->name eq 'lineseq';
1203
1204
1205    # last op should be nextstate
1206    my $last = $topop->last;
1207    return unless $$last
1208                    and (   _op_is_or_was($last, OP_NEXTSTATE)
1209                         or _op_is_or_was($last, OP_DBSTATE));
1210
1211    # first OP_NEXTSTATE
1212
1213    my $o = $topop->first;
1214    return unless $$o;
1215    return if $o->label;
1216
1217    # OP_ARGCHECK
1218
1219    $o = $o->sibling;
1220    return unless $$o and $o->name eq 'argcheck';
1221
1222    my ($params, $opt_params, $slurpy) = $o->aux_list($cv);
1223    my $mandatory = $params - $opt_params;
1224    my $seen_slurpy = 0;
1225    my $last_ix = -1;
1226
1227    # keep looking for valid nextstate + argelem pairs, terminated
1228    # by a final nextstate
1229
1230    while (1) {
1231        $o = $o->sibling;
1232        return unless $$o;
1233
1234        # skip trailing nextstate
1235        last if $$o == $$last;
1236
1237        # OP_NEXTSTATE
1238        return unless $o->name =~ /^(next|db)state$/;
1239        return if $o->label;
1240
1241        # OP_ARGELEM
1242        $o = $o->sibling;
1243        last unless $$o;
1244
1245        if ($o->name eq 'argelem') {
1246            my $ix  = $o->string($cv);
1247            while (++$last_ix < $ix) {
1248                push @sig, $last_ix <  $mandatory ? '$' : '$=';
1249            }
1250            my $var = $self->padname($o->targ);
1251            if ($var =~ /^[@%]/) {
1252                return if $seen_slurpy;
1253                $seen_slurpy = 1;
1254                return if $ix != $params or !$slurpy
1255                            or substr($var,0,1) ne $slurpy;
1256            }
1257            else {
1258                return if $ix >= $params;
1259            }
1260            if ($o->flags & OPf_KIDS) {
1261                my $kid = $o->first;
1262                return unless $$kid and $kid->name eq 'argdefelem';
1263                my $def = $self->deparse($kid->first, 7);
1264                $def = "($def)" if $kid->first->flags & OPf_PARENS;
1265                my $assign = "=";
1266                $assign = "//=" if $kid->private & OPpARG_IF_UNDEF;
1267                $assign = "||=" if $kid->private & OPpARG_IF_FALSE;
1268                $var .= " $assign $def";
1269            }
1270            push @sig, $var;
1271        }
1272        elsif ($o->name eq 'null'
1273               and ($o->flags & OPf_KIDS)
1274               and $o->first->name eq 'argdefelem')
1275        {
1276            # special case - a void context default expression: $ = expr
1277
1278            my $defop = $o->first;
1279            my $ix = $defop->targ;
1280            while (++$last_ix < $ix) {
1281                push @sig, $last_ix <  $mandatory ? '$' : '$=';
1282            }
1283            return if $last_ix >= $params
1284                    or $last_ix < $mandatory;
1285            my $def = $self->deparse($defop->first, 7);
1286            $def = "($def)" if $defop->first->flags & OPf_PARENS;
1287            push @sig, '$ = ' . $def;
1288        }
1289        else {
1290            return;
1291        }
1292
1293    }
1294
1295    while (++$last_ix < $params) {
1296        push @sig, $last_ix <  $mandatory ? '$' : '$=';
1297    }
1298    push @sig, $slurpy if $slurpy and !$seen_slurpy;
1299
1300    return (join(', ', @sig));
1301}
1302
1303
1304# Deparse a sub. Returns everything except the 'sub foo',
1305# e.g.  ($$) : method { ...; }
1306# or    : prototype($$) lvalue ($a, $b) { ...; };
1307
1308sub deparse_sub {
1309    my $self = shift;
1310    my $cv = shift;
1311    my @attrs;
1312    my $proto;
1313    my $sig;
1314
1315Carp::confess("NULL in deparse_sub") if !defined($cv) || $cv->isa("B::NULL");
1316Carp::confess("SPECIAL in deparse_sub") if $cv->isa("B::SPECIAL");
1317    local $self->{'curcop'} = $self->{'curcop'};
1318
1319    my $has_sig = $self->feature_enabled('signatures');
1320    if ($cv->FLAGS & SVf_POK) {
1321	my $myproto = $cv->PV;
1322	if ($has_sig) {
1323            push @attrs, "prototype($myproto)";
1324        }
1325        else {
1326            $proto = $myproto;
1327        }
1328    }
1329    if ($cv->CvFLAGS & (CVf_NOWARN_AMBIGUOUS|CVf_LOCKED|CVf_LVALUE|CVf_ANONCONST)) {
1330        push @attrs, "lvalue" if $cv->CvFLAGS & CVf_LVALUE;
1331        push @attrs, "method" if $cv->CvFLAGS & CVf_NOWARN_AMBIGUOUS;
1332        push @attrs, "const"  if $cv->CvFLAGS & CVf_ANONCONST;
1333    }
1334
1335    local($self->{'curcv'}) = $cv;
1336    local($self->{'curcvlex'});
1337    local(@$self{qw'curstash warnings hints hinthash'})
1338		= @$self{qw'curstash warnings hints hinthash'};
1339    my $body;
1340    my $root = $cv->ROOT;
1341    local $B::overlay = {};
1342    if (not null $root) {
1343	$self->pad_subs($cv);
1344	$self->pessimise($root, $cv->START);
1345	my $lineseq = $root->first;
1346
1347        # stub sub may have single op rather than list of ops
1348        my $is_list = ($lineseq->name eq "lineseq");
1349        my $firstop = $is_list ? $lineseq->first : $lineseq;
1350
1351        # Try to deparse first subtree as a signature if possible.
1352        # Top of signature subtree has an ex-argcheck as a placeholder
1353        if (    $has_sig
1354            and $$firstop
1355            and $firstop->name eq 'null'
1356            and $firstop->targ == OP_ARGCHECK
1357        ) {
1358            my ($mysig) = $self->deparse_argops($firstop, $cv);
1359            if (defined $mysig) {
1360                $sig = $mysig;
1361                $firstop = $is_list ? $firstop->sibling : undef;
1362            }
1363        }
1364
1365        if ($is_list && $firstop) {
1366            my @ops;
1367	    for (my $o = $firstop; $$o; $o=$o->sibling) {
1368		push @ops, $o;
1369	    }
1370	    $body = $self->lineseq(undef, 0, @ops).";";
1371            if (!$has_sig and $ops[-1]->name =~ /^(next|db)state$/) {
1372                # this handles void context in
1373                #   use feature signatures; sub ($=1) {}
1374                $body .= "\n()";
1375            }
1376	    my $scope_en = $self->find_scope_en($lineseq);
1377	    if (defined $scope_en) {
1378		my $subs = join"", $self->seq_subs($scope_en);
1379		$body .= ";\n$subs" if length($subs);
1380	    }
1381	}
1382	elsif ($firstop) {
1383	    $body = $self->deparse($root->first, 0);
1384	}
1385        else {
1386            $body = ';'; # stub sub
1387        }
1388
1389        my $l = '';
1390        if ($self->{'linenums'}) {
1391            # a glob's gp_line is set from the line containing a
1392            # sub's closing '}' if the CV is the first use of the GV.
1393            # So make sure the linenum is set correctly for '}'
1394            my $gv = $cv->GV;
1395            my $line = $gv->LINE;
1396            my $file = $gv->FILE;
1397            $l = "\f#line $line \"$file\"\n";
1398        }
1399        $body = "{\n\t$body\n$l\b}";
1400    }
1401    else {
1402	my $sv = $cv->const_sv;
1403	if ($$sv) {
1404	    # uh-oh. inlinable sub... format it differently
1405	    $body = "{ " . $self->const($sv, 0) . " }\n";
1406	} else { # XSUB? (or just a declaration)
1407	    $body = ';'
1408	}
1409    }
1410    $proto = defined $proto ? "($proto) " : "";
1411    $sig   = defined $sig   ? "($sig) "   : "";
1412    my $attrs = '';
1413    $attrs = ': ' . join('', map "$_ ", @attrs) if @attrs;
1414    return "$proto$attrs$sig$body\n";
1415}
1416
1417sub deparse_format {
1418    my $self = shift;
1419    my $form = shift;
1420    my @text;
1421    local($self->{'curcv'}) = $form;
1422    local($self->{'curcvlex'});
1423    local($self->{'in_format'}) = 1;
1424    local(@$self{qw'curstash warnings hints hinthash'})
1425		= @$self{qw'curstash warnings hints hinthash'};
1426    my $op = $form->ROOT;
1427    local $B::overlay = {};
1428    $self->pessimise($op, $form->START);
1429    my $kid;
1430    return "\f." if $op->first->name eq 'stub'
1431                || $op->first->name eq 'nextstate';
1432    $op = $op->first->first; # skip leavewrite, lineseq
1433    while (not null $op) {
1434	$op = $op->sibling; # skip nextstate
1435	my @exprs;
1436	$kid = $op->first->sibling; # skip pushmark
1437	push @text, "\f".$self->const_sv($kid)->PV;
1438	$kid = $kid->sibling;
1439	for (; not null $kid; $kid = $kid->sibling) {
1440	    push @exprs, $self->deparse($kid, -1);
1441	    $exprs[-1] =~ s/;\z//;
1442	}
1443	push @text, "\f".join(", ", @exprs)."\n" if @exprs;
1444	$op = $op->sibling;
1445    }
1446    return join("", @text) . "\f.";
1447}
1448
1449sub is_scope {
1450    my $op = shift;
1451    return $op->name eq "leave" || $op->name eq "scope"
1452      || $op->name eq "lineseq"
1453	|| ($op->name eq "null" && class($op) eq "UNOP"
1454	    && (is_scope($op->first) || $op->first->name eq "enter"));
1455}
1456
1457sub is_state {
1458    my $name = $_[0]->name;
1459    return $name eq "nextstate" || $name eq "dbstate" || $name eq "setstate";
1460}
1461
1462sub is_miniwhile { # check for one-line loop ('foo() while $y--')
1463    my $op = shift;
1464    return (!null($op) and null($op->sibling)
1465	    and $op->name eq "null" and class($op) eq "UNOP"
1466	    and (($op->first->name =~ /^(and|or)$/
1467		  and $op->first->first->sibling->name eq "lineseq")
1468		 or ($op->first->name eq "lineseq"
1469		     and not null $op->first->first->sibling
1470		     and $op->first->first->sibling->name eq "unstack")
1471		 ));
1472}
1473
1474# Check if the op and its sibling are the initialization and the rest of a
1475# for (..;..;..) { ... } loop
1476sub is_for_loop {
1477    my $op = shift;
1478    # This OP might be almost anything, though it won't be a
1479    # nextstate. (It's the initialization, so in the canonical case it
1480    # will be an sassign.) The sibling is (old style) a lineseq whose
1481    # first child is a nextstate and whose second is a leaveloop, or
1482    # (new style) an unstack whose sibling is a leaveloop.
1483    my $lseq = $op->sibling;
1484    return 0 unless !is_state($op) and !null($lseq);
1485    if ($lseq->name eq "lineseq") {
1486	if ($lseq->first && !null($lseq->first) && is_state($lseq->first)
1487	    && (my $sib = $lseq->first->sibling)) {
1488	    return (!null($sib) && $sib->name eq "leaveloop");
1489	}
1490    } elsif ($lseq->name eq "unstack" && ($lseq->flags & OPf_SPECIAL)) {
1491	my $sib = $lseq->sibling;
1492	return $sib && !null($sib) && $sib->name eq "leaveloop";
1493    }
1494    return 0;
1495}
1496
1497sub is_scalar {
1498    my $op = shift;
1499    return ($op->name eq "rv2sv" or
1500	    $op->name eq "padsv" or
1501	    $op->name eq "gv" or # only in array/hash constructs
1502	    $op->flags & OPf_KIDS && !null($op->first)
1503	      && $op->first->name eq "gvsv");
1504}
1505
1506sub maybe_parens {
1507    my $self = shift;
1508    my($text, $cx, $prec) = @_;
1509    if ($prec < $cx              # unary ops nest just fine
1510	or $prec == $cx and $cx != 4 and $cx != 16 and $cx != 21
1511	or $self->{'parens'})
1512    {
1513	$text = "($text)";
1514	# In a unop, let parent reuse our parens; see maybe_parens_unop
1515	$text = "\cS" . $text if $cx == 16;
1516	return $text;
1517    } else {
1518	return $text;
1519    }
1520}
1521
1522# same as above, but get around the 'if it looks like a function' rule
1523sub maybe_parens_unop {
1524    my $self = shift;
1525    my($name, $kid, $cx) = @_;
1526    if ($cx > 16 or $self->{'parens'}) {
1527	$kid =  $self->deparse($kid, 1);
1528 	if ($name eq "umask" && $kid =~ /^\d+$/) {
1529	    $kid = sprintf("%#o", $kid);
1530	}
1531	return $self->keyword($name) . "($kid)";
1532    } else {
1533	$kid = $self->deparse($kid, 16);
1534 	if ($name eq "umask" && $kid =~ /^\d+$/) {
1535	    $kid = sprintf("%#o", $kid);
1536	}
1537	$name = $self->keyword($name);
1538	if (substr($kid, 0, 1) eq "\cS") {
1539	    # use kid's parens
1540	    return $name . substr($kid, 1);
1541	} elsif (substr($kid, 0, 1) eq "(") {
1542	    # avoid looks-like-a-function trap with extra parens
1543	    # ('+' can lead to ambiguities)
1544	    return "$name(" . $kid  . ")";
1545	} else {
1546	    return "$name $kid";
1547	}
1548    }
1549}
1550
1551sub maybe_parens_func {
1552    my $self = shift;
1553    my($func, $text, $cx, $prec) = @_;
1554    if ($prec <= $cx or substr($text, 0, 1) eq "(" or $self->{'parens'}) {
1555	return "$func($text)";
1556    } else {
1557        return $func . (length($text) ? " $text" : "");
1558    }
1559}
1560
1561sub find_our_type {
1562    my ($self, $name) = @_;
1563    $self->populate_curcvlex() if !defined $self->{'curcvlex'};
1564    my $seq = $self->{'curcop'} ? $self->{'curcop'}->cop_seq : 0;
1565    for my $a (@{$self->{'curcvlex'}{"o$name"}}) {
1566	my ($st, undef, $padname) = @$a;
1567	if ($st >= $seq && $padname->FLAGS & PADNAMEf_TYPED) {
1568	    return $padname->SvSTASH->NAME;
1569	}
1570    }
1571    return '';
1572}
1573
1574sub maybe_local {
1575    my $self = shift;
1576    my($op, $cx, $text) = @_;
1577    my $name = $op->name;
1578    my $our_intro = ($name =~ /^(?:(?:gv|rv2)[ash]v|split|refassign
1579				  |lv(?:av)?ref)$/x)
1580			? OPpOUR_INTRO
1581			: 0;
1582    my $lval_intro = $name eq 'split' ? 0 : OPpLVAL_INTRO;
1583    # The @a in \(@a) isn't in ref context, but only when the
1584    # parens are there.
1585    my $need_parens = $self->{'in_refgen'} && $name =~ /[ah]v\z/
1586		   && ($op->flags & (OPf_PARENS|OPf_REF)) == OPf_PARENS;
1587    if ((my $priv = $op->private) & ($lval_intro|$our_intro)) {
1588	my @our_local;
1589	push @our_local, "local" if $priv & $lval_intro;
1590	push @our_local, "our"   if $priv & $our_intro;
1591	my $our_local = join " ", map $self->keyword($_), @our_local;
1592	if( $our_local[-1] eq 'our' ) {
1593	    if ( $text !~ /^\W(\w+::)*\w+\z/
1594	     and !utf8::decode($text) || $text !~ /^\W(\w+::)*\w+\z/
1595	    ) {
1596		die "Unexpected our($text)\n";
1597	    }
1598	    $text =~ s/(\w+::)+//;
1599
1600	    if (my $type = $self->find_our_type($text)) {
1601		$our_local .= ' ' . $type;
1602	    }
1603	}
1604	return $need_parens ? "($text)" : $text
1605	    if $self->{'avoid_local'}{$$op};
1606	if ($need_parens) {
1607	    return "$our_local($text)";
1608	} elsif (want_scalar($op) || $our_local eq 'our') {
1609	    return "$our_local $text";
1610	} else {
1611	    return $self->maybe_parens_func("$our_local", $text, $cx, 16);
1612	}
1613    } else {
1614	return $need_parens ? "($text)" : $text;
1615    }
1616}
1617
1618sub maybe_targmy {
1619    my $self = shift;
1620    my($op, $cx, $func, @args) = @_;
1621    if ($op->private & OPpTARGET_MY) {
1622	my $var = $self->padname($op->targ);
1623	my $val = $func->($self, $op, 7, @args);
1624	return $self->maybe_parens("$var = $val", $cx, 7);
1625    } else {
1626	return $func->($self, $op, $cx, @args);
1627    }
1628}
1629
1630sub padname_sv {
1631    my $self = shift;
1632    my $targ = shift;
1633    return $self->{'curcv'}->PADLIST->ARRAYelt(0)->ARRAYelt($targ);
1634}
1635
1636sub maybe_my {
1637    my $self = shift;
1638    my($op, $cx, $text, $padname, $forbid_parens) = @_;
1639    # The @a in \(@a) isn't in ref context, but only when the
1640    # parens are there.
1641    my $need_parens = !$forbid_parens && $self->{'in_refgen'}
1642		   && $op->name =~ /[ah]v\z/
1643		   && ($op->flags & (OPf_PARENS|OPf_REF)) == OPf_PARENS;
1644    # The @a in \my @a must not have parens.
1645    if (!$need_parens && $self->{'in_refgen'}) {
1646	$forbid_parens = 1;
1647    }
1648    if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {
1649	# Check $padname->FLAGS for statehood, rather than $op->private,
1650	# because enteriter ops do not carry the flag.
1651	my $my =
1652	    $self->keyword($padname->FLAGS & SVpad_STATE ? "state" : "my");
1653	if ($padname->FLAGS & PADNAMEf_TYPED) {
1654	    $my .= ' ' . $padname->SvSTASH->NAME;
1655	}
1656	if ($need_parens) {
1657	    return "$my($text)";
1658	} elsif ($forbid_parens || want_scalar($op)) {
1659	    return "$my $text";
1660	} else {
1661	    return $self->maybe_parens_func($my, $text, $cx, 16);
1662	}
1663    } else {
1664	return $need_parens ? "($text)" : $text;
1665    }
1666}
1667
1668# The following OPs don't have functions:
1669
1670# pp_padany -- does not exist after parsing
1671
1672sub AUTOLOAD {
1673    if ($AUTOLOAD =~ s/^.*::pp_//) {
1674	warn "unexpected OP_".
1675	  ($_[1]->type == OP_CUSTOM ? "CUSTOM ($AUTOLOAD)" : uc $AUTOLOAD);
1676	return "XXX";
1677    } else {
1678	die "Undefined subroutine $AUTOLOAD called";
1679    }
1680}
1681
1682sub DESTROY {}	#	Do not AUTOLOAD
1683
1684# $root should be the op which represents the root of whatever
1685# we're sequencing here. If it's undefined, then we don't append
1686# any subroutine declarations to the deparsed ops, otherwise we
1687# append appropriate declarations.
1688sub lineseq {
1689    my($self, $root, $cx, @ops) = @_;
1690    my($expr, @exprs);
1691
1692    my $out_cop = $self->{'curcop'};
1693    my $out_seq = defined($out_cop) ? $out_cop->cop_seq : undef;
1694    my $limit_seq;
1695    if (defined $root) {
1696	$limit_seq = $out_seq;
1697	my $nseq;
1698	$nseq = $self->find_scope_st($root->sibling) if ${$root->sibling};
1699	$limit_seq = $nseq if !defined($limit_seq)
1700			   or defined($nseq) && $nseq < $limit_seq;
1701    }
1702    $limit_seq = $self->{'limit_seq'}
1703	if defined($self->{'limit_seq'})
1704	&& (!defined($limit_seq) || $self->{'limit_seq'} < $limit_seq);
1705    local $self->{'limit_seq'} = $limit_seq;
1706
1707    $self->walk_lineseq($root, \@ops,
1708		       sub { push @exprs, $_[0]} );
1709
1710    my $sep = $cx ? '; ' : ";\n";
1711    my $body = join($sep, grep {length} @exprs);
1712    my $subs = "";
1713    if (defined $root && defined $limit_seq && !$self->{'in_format'}) {
1714	$subs = join "\n", $self->seq_subs($limit_seq);
1715    }
1716    return join($sep, grep {length} $body, $subs);
1717}
1718
1719sub scopeop {
1720    my($real_block, $self, $op, $cx) = @_;
1721    my $kid;
1722    my @kids;
1723
1724    local(@$self{qw'curstash warnings hints hinthash'})
1725		= @$self{qw'curstash warnings hints hinthash'} if $real_block;
1726    if ($real_block) {
1727	$kid = $op->first->sibling; # skip enter
1728	if (is_miniwhile($kid)) {
1729	    my $top = $kid->first;
1730	    my $name = $top->name;
1731	    if ($name eq "and") {
1732		$name = $self->keyword("while");
1733	    } elsif ($name eq "or") {
1734		$name = $self->keyword("until");
1735	    } else { # no conditional -> while 1 or until 0
1736		return $self->deparse($top->first, 1) . " "
1737		     . $self->keyword("while") . " 1";
1738	    }
1739	    my $cond = $top->first;
1740	    my $body = $cond->sibling->first; # skip lineseq
1741	    $cond = $self->deparse($cond, 1);
1742	    $body = $self->deparse($body, 1);
1743	    return "$body $name $cond";
1744	}
1745        elsif($kid->type == OP_PUSHDEFER &&
1746            $kid->private & OPpDEFER_FINALLY &&
1747            $kid->sibling->type == OP_LEAVETRYCATCH &&
1748            null($kid->sibling->sibling)) {
1749            return $self->pp_leavetrycatch_with_finally($kid->sibling, $kid, $cx);
1750        }
1751    } else {
1752	$kid = $op->first;
1753    }
1754    for (; !null($kid); $kid = $kid->sibling) {
1755	push @kids, $kid;
1756    }
1757    if ($cx > 0) { # inside an expression, (a do {} while for lineseq)
1758	my $body = $self->lineseq($op, 0, @kids);
1759	return is_lexical_subs(@kids)
1760		? $body
1761		: ($self->lex_in_scope("&do") ? "CORE::do" : "do")
1762		 . " {\n\t$body\n\b}";
1763    } else {
1764	my $lineseq = $self->lineseq($op, $cx, @kids);
1765	return (length ($lineseq) ? "$lineseq;" : "");
1766    }
1767}
1768
1769sub pp_scope { scopeop(0, @_); }
1770sub pp_lineseq { scopeop(0, @_); }
1771sub pp_leave { scopeop(1, @_); }
1772
1773# This is a special case of scopeop and lineseq, for the case of the
1774# main_root. The difference is that we print the output statements as
1775# soon as we get them, for the sake of impatient users.
1776sub deparse_root {
1777    my $self = shift;
1778    my($op) = @_;
1779    local(@$self{qw'curstash warnings hints hinthash'})
1780      = @$self{qw'curstash warnings hints hinthash'};
1781    my @kids;
1782    return if null $op->first; # Can happen, e.g., for Bytecode without -k
1783    for (my $kid = $op->first->sibling; !null($kid); $kid = $kid->sibling) {
1784	push @kids, $kid;
1785    }
1786    $self->walk_lineseq($op, \@kids,
1787			sub { return unless length $_[0];
1788			      print $self->indent($_[0].';');
1789			      print "\n"
1790				unless $_[1] == $#kids;
1791			  });
1792}
1793
1794sub walk_lineseq {
1795    my ($self, $op, $kids, $callback) = @_;
1796    my @kids = @$kids;
1797    for (my $i = 0; $i < @kids; $i++) {
1798	my $expr = "";
1799	if (is_state $kids[$i]) {
1800	    $expr = $self->deparse($kids[$i++], 0);
1801	    if ($i > $#kids) {
1802		$callback->($expr, $i);
1803		last;
1804	    }
1805	}
1806	if (is_for_loop($kids[$i])) {
1807	    $callback->($expr . $self->for_loop($kids[$i], 0),
1808		$i += $kids[$i]->sibling->name eq "unstack" ? 2 : 1);
1809	    next;
1810	}
1811	my $expr2 = $self->deparse($kids[$i], (@kids != 1)/2);
1812	$expr2 =~ s/^sub :(?!:)/+sub :/; # statement label otherwise
1813	$expr .= $expr2;
1814	$callback->($expr, $i);
1815    }
1816}
1817
1818# The BEGIN {} is used here because otherwise this code isn't executed
1819# when you run B::Deparse on itself.
1820my %globalnames;
1821BEGIN { map($globalnames{$_}++, "SIG", "STDIN", "STDOUT", "STDERR", "INC",
1822	    "ENV", "ARGV", "ARGVOUT", "_"); }
1823
1824sub gv_name {
1825    my $self = shift;
1826    my $gv = shift;
1827    my $raw = shift;
1828#Carp::confess() unless ref($gv) eq "B::GV";
1829    my $cv = $gv->FLAGS & SVf_ROK ? $gv->RV : 0;
1830    my $stash = ($cv || $gv)->STASH->NAME;
1831    my $name = $raw
1832	? $cv ? $cv->NAME_HEK || $cv->GV->NAME : $gv->NAME
1833	: $cv
1834	    ? B::safename($cv->NAME_HEK || $cv->GV->NAME)
1835	    : $gv->SAFENAME;
1836    if ($stash eq 'main' && $name =~ /^::/) {
1837	$stash = '::';
1838    }
1839    elsif (($stash eq 'main'
1840	    && ($globalnames{$name} || $name =~ /^[^A-Za-z_:]/))
1841	or ($stash eq $self->{'curstash'} && !$globalnames{$name}
1842	    && ($stash eq 'main' || $name !~ /::/))
1843	  )
1844    {
1845	$stash = "";
1846    } else {
1847	$stash = $stash . "::";
1848    }
1849    if (!$raw and $name =~ /^(\^..|{)/) {
1850        $name = "{$name}";       # ${^WARNING_BITS}, etc and ${
1851    }
1852    return $stash . $name;
1853}
1854
1855# Return the name to use for a stash variable.
1856# If a lexical with the same name is in scope, or
1857# if strictures are enabled, it may need to be
1858# fully-qualified.
1859sub stash_variable {
1860    my ($self, $prefix, $name, $cx) = @_;
1861
1862    return $prefix.$self->maybe_qualify($prefix, $name) if $name =~ /::/;
1863
1864    unless ($prefix eq '$' || $prefix eq '@' || $prefix eq '&' || #'
1865	    $prefix eq '%' || $prefix eq '$#') {
1866	return "$prefix$name";
1867    }
1868
1869    if ($name =~ /^[^[:alpha:]_+-]$/) {
1870      if (defined $cx && $cx == 26) {
1871	if ($prefix eq '@') {
1872	    return "$prefix\{$name}";
1873	}
1874	elsif ($name eq '#') { return '${#}' } #  "${#}a" vs "$#a"
1875      }
1876      if ($prefix eq '$#') {
1877	return "\$#{$name}";
1878      }
1879    }
1880
1881    return $prefix . $self->maybe_qualify($prefix, $name);
1882}
1883
1884my %unctrl = # portable to EBCDIC
1885    (
1886     "\c@" => '@',	# unused
1887     "\cA" => 'A',
1888     "\cB" => 'B',
1889     "\cC" => 'C',
1890     "\cD" => 'D',
1891     "\cE" => 'E',
1892     "\cF" => 'F',
1893     "\cG" => 'G',
1894     "\cH" => 'H',
1895     "\cI" => 'I',
1896     "\cJ" => 'J',
1897     "\cK" => 'K',
1898     "\cL" => 'L',
1899     "\cM" => 'M',
1900     "\cN" => 'N',
1901     "\cO" => 'O',
1902     "\cP" => 'P',
1903     "\cQ" => 'Q',
1904     "\cR" => 'R',
1905     "\cS" => 'S',
1906     "\cT" => 'T',
1907     "\cU" => 'U',
1908     "\cV" => 'V',
1909     "\cW" => 'W',
1910     "\cX" => 'X',
1911     "\cY" => 'Y',
1912     "\cZ" => 'Z',
1913     "\c[" => '[',	# unused
1914     "\c\\" => '\\',	# unused
1915     "\c]" => ']',	# unused
1916     "\c_" => '_',	# unused
1917    );
1918
1919# Return just the name, without the prefix.  It may be returned as a quoted
1920# string.  The second return value is a boolean indicating that.
1921sub stash_variable_name {
1922    my($self, $prefix, $gv) = @_;
1923    my $name = $self->gv_name($gv, 1);
1924    $name = $self->maybe_qualify($prefix,$name);
1925    if ($name =~ /^(?:\S|(?!\d)[\ca-\cz]?(?:\w|::)*|\d+)\z/) {
1926	$name =~ s/^([\ca-\cz])/'^' . $unctrl{$1}/e;
1927	$name =~ /^(\^..|{)/ and $name = "{$name}";
1928	return $name, 0; # not quoted
1929    }
1930    else {
1931	single_delim("q", "'", $name, $self), 1;
1932    }
1933}
1934
1935sub maybe_qualify {
1936    my ($self,$prefix,$name) = @_;
1937    my $v = ($prefix eq '$#' ? '@' : $prefix) . $name;
1938    if ($prefix eq "") {
1939	$name .= "::" if $name =~ /(?:\ACORE::[^:]*|::)\z/;
1940	return $name;
1941    }
1942    return $name if $name =~ /::/;
1943    return $self->{'curstash'}.'::'. $name
1944	if
1945	    $name =~ /^(?!\d)\w/         # alphabetic
1946	 && $v    !~ /^\$[ab]\z/	 # not $a or $b
1947	 && $v =~ /\A[\$\@\%\&]/         # scalar, array, hash, or sub
1948	 && !$globalnames{$name}         # not a global name
1949	 && $self->{hints} & $strict_bits{vars}  # strict vars
1950	 && !$self->lex_in_scope($v,1)   # no "our"
1951      or $self->lex_in_scope($v);        # conflicts with "my" variable
1952    return $name;
1953}
1954
1955sub lex_in_scope {
1956    my ($self, $name, $our) = @_;
1957    substr $name, 0, 0, = $our ? 'o' : 'm'; # our/my
1958    $self->populate_curcvlex() if !defined $self->{'curcvlex'};
1959
1960    return 0 if !defined($self->{'curcop'});
1961    my $seq = $self->{'curcop'}->cop_seq;
1962    return 0 if !exists $self->{'curcvlex'}{$name};
1963    for my $a (@{$self->{'curcvlex'}{$name}}) {
1964	my ($st, $en) = @$a;
1965	return 1 if $seq > $st && $seq <= $en;
1966    }
1967    return 0;
1968}
1969
1970sub populate_curcvlex {
1971    my $self = shift;
1972    for (my $cv = $self->{'curcv'}; class($cv) eq "CV"; $cv = $cv->OUTSIDE) {
1973	my $padlist = $cv->PADLIST;
1974	# an undef CV still in lexical chain
1975	next if class($padlist) eq "SPECIAL";
1976	my @padlist = $padlist->ARRAY;
1977	my @ns = $padlist[0]->ARRAY;
1978
1979	for (my $i=0; $i<@ns; ++$i) {
1980	    next if class($ns[$i]) eq "SPECIAL";
1981	    if (class($ns[$i]) eq "PV") {
1982		# Probably that pesky lexical @_
1983		next;
1984	    }
1985            my $name = $ns[$i]->PVX;
1986	    next unless defined $name;
1987	    my ($seq_st, $seq_en) =
1988		($ns[$i]->FLAGS & SVf_FAKE)
1989		    ? (0, 999999)
1990		    : ($ns[$i]->COP_SEQ_RANGE_LOW, $ns[$i]->COP_SEQ_RANGE_HIGH);
1991
1992	    push @{$self->{'curcvlex'}{
1993			($ns[$i]->FLAGS & PADNAMEf_OUR ? 'o' : 'm') . $name
1994		  }}, [$seq_st, $seq_en, $ns[$i]];
1995	}
1996    }
1997}
1998
1999sub find_scope_st { ((find_scope(@_))[0]); }
2000sub find_scope_en { ((find_scope(@_))[1]); }
2001
2002# Recurses down the tree, looking for pad variable introductions and COPs
2003sub find_scope {
2004    my ($self, $op, $scope_st, $scope_en) = @_;
2005    carp("Undefined op in find_scope") if !defined $op;
2006    return ($scope_st, $scope_en) unless $op->flags & OPf_KIDS;
2007
2008    my @queue = ($op);
2009    while(my $op = shift @queue ) {
2010	for (my $o=$op->first; $$o; $o=$o->sibling) {
2011	    if ($o->name =~ /^pad.v$/ && $o->private & OPpLVAL_INTRO) {
2012		my $s = int($self->padname_sv($o->targ)->COP_SEQ_RANGE_LOW);
2013		my $e = $self->padname_sv($o->targ)->COP_SEQ_RANGE_HIGH;
2014		$scope_st = $s if !defined($scope_st) || $s < $scope_st;
2015		$scope_en = $e if !defined($scope_en) || $e > $scope_en;
2016		return ($scope_st, $scope_en);
2017	    }
2018	    elsif (is_state($o)) {
2019		my $c = $o->cop_seq;
2020		$scope_st = $c if !defined($scope_st) || $c < $scope_st;
2021		$scope_en = $c if !defined($scope_en) || $c > $scope_en;
2022		return ($scope_st, $scope_en);
2023	    }
2024	    elsif ($o->flags & OPf_KIDS) {
2025		unshift (@queue, $o);
2026	    }
2027	}
2028    }
2029
2030    return ($scope_st, $scope_en);
2031}
2032
2033# Returns a list of subs which should be inserted before the COP
2034sub cop_subs {
2035    my ($self, $op, $out_seq) = @_;
2036    my $seq = $op->cop_seq;
2037    $seq = $out_seq if defined($out_seq) && $out_seq < $seq;
2038    return $self->seq_subs($seq);
2039}
2040
2041sub seq_subs {
2042    my ($self, $seq) = @_;
2043    my @text;
2044#push @text, "# ($seq)\n";
2045
2046    return "" if !defined $seq;
2047    my @pending;
2048    while (scalar(@{$self->{'subs_todo'}})
2049	   and $seq > $self->{'subs_todo'}[0][0]) {
2050	my $cv = $self->{'subs_todo'}[0][1];
2051	# Skip the OUTSIDE check for lexical subs.  We may be deparsing a
2052	# cloned anon sub with lexical subs declared in it, in which case
2053	# the OUTSIDE pointer points to the anon protosub.
2054	my $lexical = ref $self->{'subs_todo'}[0][3];
2055	my $outside = !$lexical && $cv && $cv->OUTSIDE;
2056	if (!$lexical and $cv
2057	 and ${$cv->OUTSIDE || \0} != ${$self->{'curcv'}})
2058	{
2059	    push @pending, shift @{$self->{'subs_todo'}};
2060	    next;
2061	}
2062	push @text, $self->next_todo;
2063    }
2064    unshift @{$self->{'subs_todo'}}, @pending;
2065    return @text;
2066}
2067
2068sub _features_from_bundle {
2069    my ($hints, $hh) = @_;
2070    foreach (@{$feature::feature_bundle{@feature::hint_bundles[$hints >> $feature::hint_shift]}}) {
2071	$hh->{$feature::feature{$_}} = 1;
2072    }
2073    return $hh;
2074}
2075
2076# generate any pragmas, 'package foo' etc needed to synchronise
2077# with the given cop
2078
2079sub pragmata {
2080    my $self = shift;
2081    my($op) = @_;
2082
2083    my @text;
2084
2085    my $stash = $op->stashpv;
2086    if ($stash ne $self->{'curstash'}) {
2087	push @text, $self->keyword("package") . " $stash;\n";
2088	$self->{'curstash'} = $stash;
2089    }
2090
2091    my $warnings = $op->warnings;
2092    my $warning_bits;
2093    if ($warnings->isa("B::SPECIAL") && $$warnings == 4) {
2094	$warning_bits = $warnings::Bits{"all"};
2095    }
2096    elsif ($warnings->isa("B::SPECIAL") && $$warnings == 5) {
2097        $warning_bits = $warnings::NONE;
2098    }
2099    elsif ($warnings->isa("B::SPECIAL")) {
2100	$warning_bits = undef;
2101    }
2102    else {
2103	$warning_bits = $warnings->PV;
2104    }
2105
2106    my ($w1, $w2);
2107    # The number of valid bit positions may have grown (by a byte or
2108    # more) since the last warnings state, by custom warnings
2109    # categories being registered in the meantime. Normalise the
2110    # bitmasks first so they may be fairly compared.
2111    $w1 = defined($self->{warnings})
2112                ? warnings::_expand_bits($self->{warnings})
2113                : undef;
2114    $w2 = defined($warning_bits)
2115                ? warnings::_expand_bits($warning_bits)
2116                : undef;
2117
2118    if (defined($w2) and !defined($w1) || $w1 ne $w2) {
2119	push @text, $self->declare_warnings($w1, $w2);
2120	$self->{'warnings'} = $w2;
2121    }
2122
2123    my $hints = $op->hints;
2124    my $old_hints = $self->{'hints'};
2125    if ($self->{'hints'} != $hints) {
2126	push @text, $self->declare_hints($self->{'hints'}, $hints);
2127	$self->{'hints'} = $hints;
2128    }
2129
2130    my $newhh;
2131    $newhh = $op->hints_hash->HASH;
2132
2133    {
2134	# feature bundle hints
2135	my $from = $old_hints & $feature::hint_mask;
2136	my $to   = $    hints & $feature::hint_mask;
2137	if ($from != $to) {
2138	    if ($to == $feature::hint_mask) {
2139		if ($self->{'hinthash'}) {
2140		    delete $self->{'hinthash'}{$_}
2141			for grep /^feature_/, keys %{$self->{'hinthash'}};
2142		}
2143		else { $self->{'hinthash'} = {} }
2144		$self->{'hinthash'}
2145		    = _features_from_bundle($from, $self->{'hinthash'});
2146	    }
2147	    else {
2148		my $bundle =
2149		    $feature::hint_bundles[$to >> $feature::hint_shift];
2150		$bundle =~ s/(\d[13579])\z/$1+1/e; # 5.11 => 5.12
2151		push @text,
2152		    $self->keyword("no") . " feature ':all';\n",
2153		    $self->keyword("use") . " feature ':$bundle';\n";
2154	    }
2155	}
2156    }
2157
2158    {
2159	push @text, $self->declare_hinthash(
2160	    $self->{'hinthash'}, $newhh,
2161	    $self->{indent_size}, $self->{hints},
2162	);
2163	$self->{'hinthash'} = $newhh;
2164    }
2165
2166    return join("", @text);
2167}
2168
2169
2170# Notice how subs and formats are inserted between statements here;
2171# also $[ assignments and pragmas.
2172sub pp_nextstate {
2173    my $self = shift;
2174    my($op, $cx) = @_;
2175    $self->{'curcop'} = $op;
2176
2177    my @text;
2178
2179    my @subs = $self->cop_subs($op);
2180    if (@subs) {
2181	# Special marker to swallow up the semicolon
2182	push @subs, "\cK";
2183    }
2184    push @text, @subs;
2185
2186    push @text, $self->pragmata($op);
2187
2188
2189    # This should go after of any branches that add statements, to
2190    # increase the chances that it refers to the same line it did in
2191    # the original program.
2192    if ($self->{'linenums'} && $cx != .5) { # $cx == .5 means in a format
2193	push @text, "\f#line " . $op->line .
2194	  ' "' . $op->file, qq'"\n';
2195    }
2196
2197    push @text, $op->label . ": " if $op->label;
2198
2199    return join("", @text);
2200}
2201
2202sub declare_warnings {
2203    my ($self, $from, $to) = @_;
2204    $from //= '';
2205    my $all = warnings::bits("all");
2206    unless (($from & ~$all) =~ /[^\0]/) {
2207        # no FATAL bits need turning off
2208        if (   $to eq $all) {
2209            return $self->keyword("use") . " warnings;\n";
2210        }
2211        elsif ($to eq ("\0"x length($to))) {
2212            return $self->keyword("no") . " warnings;\n";
2213        }
2214    }
2215
2216    return "BEGIN {\${^WARNING_BITS} = \""
2217           . join("", map { sprintf("\\x%02x", ord $_) } split "", $to)
2218           . "\"}\n\cK";
2219}
2220
2221sub declare_hints {
2222    my ($self, $from, $to) = @_;
2223    my $use = $to   & ~$from;
2224    my $no  = $from & ~$to;
2225    my $decls = "";
2226    for my $pragma (hint_pragmas($use)) {
2227	$decls .= $self->keyword("use") . " $pragma;\n";
2228    }
2229    for my $pragma (hint_pragmas($no)) {
2230        $decls .= $self->keyword("no") . " $pragma;\n";
2231    }
2232    return $decls;
2233}
2234
2235# Internal implementation hints that the core sets automatically, so don't need
2236# (or want) to be passed back to the user
2237my %ignored_hints = (
2238    'open<' => 1,
2239    'open>' => 1,
2240    ':'     => 1,
2241    'strict/refs' => 1,
2242    'strict/subs' => 1,
2243    'strict/vars' => 1,
2244    'feature/bits' => 1,
2245);
2246
2247my %rev_feature;
2248
2249sub declare_hinthash {
2250    my ($self, $from, $to, $indent, $hints) = @_;
2251    my $doing_features =
2252	($hints & $feature::hint_mask) == $feature::hint_mask;
2253    my @decls;
2254    my @features;
2255    my @unfeatures; # bugs?
2256    for my $key (sort keys %$to) {
2257	next if $ignored_hints{$key};
2258	my $is_feature = $key =~ /^feature_/;
2259	next if $is_feature and not $doing_features;
2260	if (!exists $from->{$key} or $from->{$key} ne $to->{$key}) {
2261	    push(@features, $key), next if $is_feature;
2262	    push @decls,
2263		qq(\$^H{) . single_delim("q", "'", $key, $self) . qq(} = )
2264	      . (
2265		   defined $to->{$key}
2266			? single_delim("q", "'", $to->{$key}, $self)
2267			: 'undef'
2268		)
2269	      . qq(;);
2270	}
2271    }
2272    for my $key (sort keys %$from) {
2273	next if $ignored_hints{$key};
2274	my $is_feature = $key =~ /^feature_/;
2275	next if $is_feature and not $doing_features;
2276	if (!exists $to->{$key}) {
2277	    push(@unfeatures, $key), next if $is_feature;
2278	    push @decls, qq(delete \$^H{'$key'};);
2279	}
2280    }
2281    my @ret;
2282    if (@features || @unfeatures) {
2283	if (!%rev_feature) { %rev_feature = reverse %feature::feature }
2284    }
2285    if (@features) {
2286	push @ret, $self->keyword("use") . " feature "
2287		 . join(", ", map "'$rev_feature{$_}'", @features) . ";\n";
2288    }
2289    if (@unfeatures) {
2290	push @ret, $self->keyword("no") . " feature "
2291		 . join(", ", map "'$rev_feature{$_}'", @unfeatures)
2292		 . ";\n";
2293    }
2294    @decls and
2295	push @ret,
2296	     join("\n" . (" " x $indent), "BEGIN {", @decls) . "\n}\n\cK";
2297    return @ret;
2298}
2299
2300sub hint_pragmas {
2301    my ($bits) = @_;
2302    my (@pragmas, @strict);
2303    push @pragmas, "integer" if $bits & 0x1;
2304    for (sort keys %strict_bits) {
2305	push @strict, "'$_'" if $bits & $strict_bits{$_};
2306    }
2307    if (@strict == keys %strict_bits) {
2308	push @pragmas, "strict";
2309    }
2310    elsif (@strict) {
2311	push @pragmas, "strict " . join ', ', @strict;
2312    }
2313    push @pragmas, "bytes" if $bits & 0x8;
2314    return @pragmas;
2315}
2316
2317sub pp_dbstate { pp_nextstate(@_) }
2318sub pp_setstate { pp_nextstate(@_) }
2319
2320sub pp_unstack { return "" } # see also leaveloop
2321
2322my %feature_keywords = (
2323  # keyword => 'feature',
2324    state   => 'state',
2325    say     => 'say',
2326    given   => 'switch',
2327    when    => 'switch',
2328    default => 'switch',
2329    break   => 'switch',
2330    evalbytes=>'evalbytes',
2331    __SUB__ => '__SUB__',
2332   fc       => 'fc',
2333   try      => 'try',
2334   catch    => 'try',
2335   finally  => 'try',
2336   defer    => 'defer',
2337   signatures => 'signatures',
2338);
2339
2340# keywords that are strong and also have a prototype
2341#
2342my %strong_proto_keywords = map { $_ => 1 } qw(
2343    pos
2344    prototype
2345    scalar
2346    study
2347    undef
2348);
2349
2350sub feature_enabled {
2351	my($self,$name) = @_;
2352	my $hh;
2353	my $hints = $self->{hints} & $feature::hint_mask;
2354	if ($hints && $hints != $feature::hint_mask) {
2355	    $hh = _features_from_bundle($hints);
2356	}
2357	elsif ($hints) { $hh = $self->{'hinthash'} }
2358	return $hh && $hh->{"feature_$feature_keywords{$name}"}
2359}
2360
2361sub keyword {
2362    my $self = shift;
2363    my $name = shift;
2364    return $name if $name =~ /^CORE::/; # just in case
2365    if (exists $feature_keywords{$name}) {
2366	return "CORE::$name" if not $self->feature_enabled($name);
2367    }
2368    # This sub may be called for a program that has no nextstate ops.  In
2369    # that case we may have a lexical sub named no/use/sub in scope but
2370    # $self->lex_in_scope will return false because it depends on the
2371    # current nextstate op.  So we need this alternate method if there is
2372    # no current cop.
2373    if (!$self->{'curcop'}) {
2374	$self->populate_curcvlex() if !defined $self->{'curcvlex'};
2375	return "CORE::$name" if exists $self->{'curcvlex'}{"m&$name"}
2376			     || exists $self->{'curcvlex'}{"o&$name"};
2377    } elsif ($self->lex_in_scope("&$name")
2378	  || $self->lex_in_scope("&$name", 1)) {
2379	return "CORE::$name";
2380    }
2381    if ($strong_proto_keywords{$name}
2382        || ($name !~ /^(?:chom?p|do|exec|glob|s(?:elect|ystem))\z/
2383	    && !defined eval{prototype "CORE::$name"})
2384    ) { return $name }
2385    if (
2386	exists $self->{subs_declared}{$name}
2387	 or
2388	exists &{"$self->{curstash}::$name"}
2389    ) {
2390	return "CORE::$name"
2391    }
2392    return $name;
2393}
2394
2395sub baseop {
2396    my $self = shift;
2397    my($op, $cx, $name) = @_;
2398    return $self->keyword($name);
2399}
2400
2401sub pp_stub { "()" }
2402sub pp_wantarray { baseop(@_, "wantarray") }
2403sub pp_fork { baseop(@_, "fork") }
2404sub pp_wait { maybe_targmy(@_, \&baseop, "wait") }
2405sub pp_getppid { maybe_targmy(@_, \&baseop, "getppid") }
2406sub pp_time { maybe_targmy(@_, \&baseop, "time") }
2407sub pp_tms { baseop(@_, "times") }
2408sub pp_ghostent { baseop(@_, "gethostent") }
2409sub pp_gnetent { baseop(@_, "getnetent") }
2410sub pp_gprotoent { baseop(@_, "getprotoent") }
2411sub pp_gservent { baseop(@_, "getservent") }
2412sub pp_ehostent { baseop(@_, "endhostent") }
2413sub pp_enetent { baseop(@_, "endnetent") }
2414sub pp_eprotoent { baseop(@_, "endprotoent") }
2415sub pp_eservent { baseop(@_, "endservent") }
2416sub pp_gpwent { baseop(@_, "getpwent") }
2417sub pp_spwent { baseop(@_, "setpwent") }
2418sub pp_epwent { baseop(@_, "endpwent") }
2419sub pp_ggrent { baseop(@_, "getgrent") }
2420sub pp_sgrent { baseop(@_, "setgrent") }
2421sub pp_egrent { baseop(@_, "endgrent") }
2422sub pp_getlogin { baseop(@_, "getlogin") }
2423
2424sub POSTFIX () { 1 }
2425
2426# I couldn't think of a good short name, but this is the category of
2427# symbolic unary operators with interesting precedence
2428
2429sub pfixop {
2430    my $self = shift;
2431    my($op, $cx, $name, $prec, $flags) = (@_, 0);
2432    my $kid = $op->first;
2433    $kid = $self->deparse($kid, $prec);
2434    return $self->maybe_parens(($flags & POSTFIX)
2435				 ? "$kid$name"
2436				   # avoid confusion with filetests
2437				 : $name eq '-'
2438				   && $kid =~ /^[a-zA-Z](?!\w)/
2439					? "$name($kid)"
2440					: "$name$kid",
2441			       $cx, $prec);
2442}
2443
2444sub pp_preinc { pfixop(@_, "++", 23) }
2445sub pp_predec { pfixop(@_, "--", 23) }
2446sub pp_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
2447sub pp_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
2448sub pp_i_preinc { pfixop(@_, "++", 23) }
2449sub pp_i_predec { pfixop(@_, "--", 23) }
2450sub pp_i_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
2451sub pp_i_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
2452sub pp_complement { maybe_targmy(@_, \&pfixop, "~", 21) }
2453*pp_ncomplement = *pp_complement;
2454sub pp_scomplement { maybe_targmy(@_, \&pfixop, "~.", 21) }
2455
2456sub pp_negate { maybe_targmy(@_, \&real_negate) }
2457sub real_negate {
2458    my $self = shift;
2459    my($op, $cx) = @_;
2460    if ($op->first->name =~ /^(i_)?negate$/) {
2461	# avoid --$x
2462	$self->pfixop($op, $cx, "-", 21.5);
2463    } else {
2464	$self->pfixop($op, $cx, "-", 21);
2465    }
2466}
2467sub pp_i_negate { pp_negate(@_) }
2468
2469sub pp_not {
2470    my $self = shift;
2471    my($op, $cx) = @_;
2472    if ($cx <= 4) {
2473	$self->listop($op, $cx, "not", $op->first);
2474    } else {
2475	$self->pfixop($op, $cx, "!", 21);
2476    }
2477}
2478
2479sub unop {
2480    my $self = shift;
2481    my($op, $cx, $name, $nollafr) = @_;
2482    my $kid;
2483    if ($op->flags & OPf_KIDS) {
2484	$kid = $op->first;
2485 	if (not $name) {
2486 	    # this deals with 'boolkeys' right now
2487 	    return $self->deparse($kid,$cx);
2488 	}
2489	my $builtinname = $name;
2490	$builtinname =~ /^CORE::/ or $builtinname = "CORE::$name";
2491	if (defined prototype($builtinname)
2492	   && $builtinname ne 'CORE::readline'
2493	   && prototype($builtinname) =~ /^;?\*/
2494	   && $kid->name eq "rv2gv") {
2495	    $kid = $kid->first;
2496	}
2497
2498	if ($nollafr) {
2499	    if (($kid = $self->deparse($kid, 16)) !~ s/^\cS//) {
2500		# require foo() is a syntax error.
2501		$kid =~ /^(?!\d)\w/ and $kid = "($kid)";
2502	    }
2503	    return $self->maybe_parens(
2504			$self->keyword($name) . " $kid", $cx, 16
2505		   );
2506	}
2507	return $self->maybe_parens_unop($name, $kid, $cx);
2508    } else {
2509	return $self->maybe_parens(
2510	    $self->keyword($name) . ($op->flags & OPf_SPECIAL ? "()" : ""),
2511	    $cx, 16,
2512	);
2513    }
2514}
2515
2516sub pp_chop { maybe_targmy(@_, \&unop, "chop") }
2517sub pp_chomp { maybe_targmy(@_, \&unop, "chomp") }
2518sub pp_schop { maybe_targmy(@_, \&unop, "chop") }
2519sub pp_schomp { maybe_targmy(@_, \&unop, "chomp") }
2520sub pp_defined { unop(@_, "defined") }
2521sub pp_undef {
2522    if ($_[1]->private & OPpTARGET_MY) {
2523        my $targ = $_[1]->targ;
2524        my $var = $_[0]->maybe_my($_[1], $_[2], $_[0]->padname($targ),
2525            $_[0]->padname_sv($targ),
2526            1);
2527        my $func = unop(@_, "undef");
2528        if ($func =~ /\s/) {
2529            return unop(@_, "undef").$var;
2530        } else {
2531            return "$var = undef";
2532        }
2533    }
2534    unop(@_, "undef")
2535}
2536sub pp_study { unop(@_, "study") }
2537sub pp_ref { unop(@_, "ref") }
2538sub pp_pos { maybe_local(@_, unop(@_, "pos")) }
2539
2540sub pp_sin { maybe_targmy(@_, \&unop, "sin") }
2541sub pp_cos { maybe_targmy(@_, \&unop, "cos") }
2542sub pp_rand { maybe_targmy(@_, \&unop, "rand") }
2543sub pp_srand { unop(@_, "srand") }
2544sub pp_exp { maybe_targmy(@_, \&unop, "exp") }
2545sub pp_log { maybe_targmy(@_, \&unop, "log") }
2546sub pp_sqrt { maybe_targmy(@_, \&unop, "sqrt") }
2547sub pp_int { maybe_targmy(@_, \&unop, "int") }
2548sub pp_hex { maybe_targmy(@_, \&unop, "hex") }
2549sub pp_oct { maybe_targmy(@_, \&unop, "oct") }
2550sub pp_abs { maybe_targmy(@_, \&unop, "abs") }
2551
2552sub pp_length { maybe_targmy(@_, \&unop, "length") }
2553sub pp_ord { maybe_targmy(@_, \&unop, "ord") }
2554sub pp_chr { maybe_targmy(@_, \&unop, "chr") }
2555
2556sub pp_each { unop(@_, "each") }
2557sub pp_values { unop(@_, "values") }
2558sub pp_keys { unop(@_, "keys") }
2559{ no strict 'refs'; *{"pp_r$_"} = *{"pp_$_"} for qw< keys each values >; }
2560sub pp_boolkeys {
2561    # no name because its an optimisation op that has no keyword
2562    unop(@_,"");
2563}
2564sub pp_aeach { unop(@_, "each") }
2565sub pp_avalues { unop(@_, "values") }
2566sub pp_akeys { unop(@_, "keys") }
2567sub pp_pop { unop(@_, "pop") }
2568sub pp_shift { unop(@_, "shift") }
2569
2570sub pp_caller { unop(@_, "caller") }
2571sub pp_reset { unop(@_, "reset") }
2572sub pp_exit { unop(@_, "exit") }
2573sub pp_prototype { unop(@_, "prototype") }
2574
2575sub pp_close { unop(@_, "close") }
2576sub pp_fileno { unop(@_, "fileno") }
2577sub pp_umask { unop(@_, "umask") }
2578sub pp_untie { unop(@_, "untie") }
2579sub pp_tied { unop(@_, "tied") }
2580sub pp_dbmclose { unop(@_, "dbmclose") }
2581sub pp_getc { unop(@_, "getc") }
2582sub pp_eof { unop(@_, "eof") }
2583sub pp_tell { unop(@_, "tell") }
2584sub pp_getsockname { unop(@_, "getsockname") }
2585sub pp_getpeername { unop(@_, "getpeername") }
2586
2587sub pp_chdir {
2588    my ($self, $op, $cx) = @_;
2589    if (($op->flags & (OPf_SPECIAL|OPf_KIDS)) == (OPf_SPECIAL|OPf_KIDS)) {
2590	my $kw = $self->keyword("chdir");
2591	my $kid = $self->const_sv($op->first)->PV;
2592	my $code = $kw
2593		 . ($cx >= 16 || $self->{'parens'} ? "($kid)" : " $kid");
2594	maybe_targmy(@_, sub { $_[3] }, $code);
2595    } else {
2596	maybe_targmy(@_, \&unop, "chdir")
2597    }
2598}
2599
2600sub pp_chroot { maybe_targmy(@_, \&unop, "chroot") }
2601sub pp_readlink { unop(@_, "readlink") }
2602sub pp_rmdir { maybe_targmy(@_, \&unop, "rmdir") }
2603sub pp_readdir { unop(@_, "readdir") }
2604sub pp_telldir { unop(@_, "telldir") }
2605sub pp_rewinddir { unop(@_, "rewinddir") }
2606sub pp_closedir { unop(@_, "closedir") }
2607sub pp_getpgrp { maybe_targmy(@_, \&unop, "getpgrp") }
2608sub pp_localtime { unop(@_, "localtime") }
2609sub pp_gmtime { unop(@_, "gmtime") }
2610sub pp_alarm { unop(@_, "alarm") }
2611sub pp_sleep { maybe_targmy(@_, \&unop, "sleep") }
2612
2613sub pp_dofile {
2614    my $code = unop(@_, "do", 1); # llafr does not apply
2615    if ($code =~ s/^((?:CORE::)?do) \{/$1({/) { $code .= ')' }
2616    $code;
2617}
2618sub pp_entereval {
2619    unop(
2620      @_,
2621      $_[1]->private & OPpEVAL_BYTES ? 'evalbytes' : "eval"
2622    )
2623}
2624
2625sub pp_ghbyname { unop(@_, "gethostbyname") }
2626sub pp_gnbyname { unop(@_, "getnetbyname") }
2627sub pp_gpbyname { unop(@_, "getprotobyname") }
2628sub pp_shostent { unop(@_, "sethostent") }
2629sub pp_snetent { unop(@_, "setnetent") }
2630sub pp_sprotoent { unop(@_, "setprotoent") }
2631sub pp_sservent { unop(@_, "setservent") }
2632sub pp_gpwnam { unop(@_, "getpwnam") }
2633sub pp_gpwuid { unop(@_, "getpwuid") }
2634sub pp_ggrnam { unop(@_, "getgrnam") }
2635sub pp_ggrgid { unop(@_, "getgrgid") }
2636
2637sub pp_lock { unop(@_, "lock") }
2638
2639sub pp_continue { unop(@_, "continue"); }
2640sub pp_break { unop(@_, "break"); }
2641
2642sub givwhen {
2643    my $self = shift;
2644    my($op, $cx, $givwhen) = @_;
2645
2646    my $enterop = $op->first;
2647    my ($head, $block);
2648    if ($enterop->flags & OPf_SPECIAL) {
2649	$head = $self->keyword("default");
2650	$block = $self->deparse($enterop->first, 0);
2651    }
2652    else {
2653	my $cond = $enterop->first;
2654	my $cond_str = $self->deparse($cond, 1);
2655	$head = "$givwhen ($cond_str)";
2656	$block = $self->deparse($cond->sibling, 0);
2657    }
2658
2659    return "$head {\n".
2660	"\t$block\n".
2661	"\b}\cK";
2662}
2663
2664sub pp_leavegiven { givwhen(@_, $_[0]->keyword("given")); }
2665sub pp_leavewhen  { givwhen(@_, $_[0]->keyword("when")); }
2666
2667sub pp_exists {
2668    my $self = shift;
2669    my($op, $cx) = @_;
2670    my $arg;
2671    my $name = $self->keyword("exists");
2672    if ($op->private & OPpEXISTS_SUB) {
2673	# Checking for the existence of a subroutine
2674	return $self->maybe_parens_func($name,
2675				$self->pp_rv2cv($op->first, 16), $cx, 16);
2676    }
2677    if ($op->flags & OPf_SPECIAL) {
2678	# Array element, not hash element
2679	return $self->maybe_parens_func($name,
2680				$self->pp_aelem($op->first, 16), $cx, 16);
2681    }
2682    return $self->maybe_parens_func($name, $self->pp_helem($op->first, 16),
2683				    $cx, 16);
2684}
2685
2686sub pp_delete {
2687    my $self = shift;
2688    my($op, $cx) = @_;
2689    my $arg;
2690    my $name = $self->keyword("delete");
2691    if ($op->private & (OPpSLICE|OPpKVSLICE)) {
2692	if ($op->flags & OPf_SPECIAL) {
2693	    # Deleting from an array, not a hash
2694	    return $self->maybe_parens_func($name,
2695					$self->pp_aslice($op->first, 16),
2696					$cx, 16);
2697	}
2698	return $self->maybe_parens_func($name,
2699					$self->pp_hslice($op->first, 16),
2700					$cx, 16);
2701    } else {
2702	if ($op->flags & OPf_SPECIAL) {
2703	    # Deleting from an array, not a hash
2704	    return $self->maybe_parens_func($name,
2705					$self->pp_aelem($op->first, 16),
2706					$cx, 16);
2707	}
2708	return $self->maybe_parens_func($name,
2709					$self->pp_helem($op->first, 16),
2710					$cx, 16);
2711    }
2712}
2713
2714sub pp_require {
2715    my $self = shift;
2716    my($op, $cx) = @_;
2717    my $opname = $op->flags & OPf_SPECIAL ? 'CORE::require' : 'require';
2718    my $kid = $op->first;
2719    if ($kid->name eq 'const') {
2720	my $priv = $kid->private;
2721	my $sv = $self->const_sv($kid);
2722	my $arg;
2723	if ($priv & OPpCONST_BARE) {
2724	    $arg = $sv->PV;
2725	    $arg =~ s[/][::]g;
2726	    $arg =~ s/\.pm//g;
2727	} elsif ($priv & OPpCONST_NOVER) {
2728	    $opname = $self->keyword('no');
2729	    $arg = $self->const($sv, 16);
2730	} elsif ((my $tmp = $self->const($sv, 16)) =~ /^v/) {
2731	    $arg = $tmp;
2732	}
2733	if ($arg) {
2734	    return $self->maybe_parens("$opname $arg", $cx, 16);
2735	}
2736    }
2737    $self->unop(
2738	    $op, $cx,
2739	    $opname,
2740	    1, # llafr does not apply
2741    );
2742}
2743
2744sub pp_scalar {
2745    my $self = shift;
2746    my($op, $cx) = @_;
2747    my $kid = $op->first;
2748    if (not null $kid->sibling) {
2749	# XXX Was a here-doc
2750	return $self->dquote($op);
2751    }
2752    $self->unop(@_, "scalar");
2753}
2754
2755
2756sub padval {
2757    my $self = shift;
2758    my $targ = shift;
2759    return $self->{'curcv'}->PADLIST->ARRAYelt(1)->ARRAYelt($targ);
2760}
2761
2762sub anon_hash_or_list {
2763    my $self = shift;
2764    my($op, $cx) = @_;
2765
2766    my($pre, $post) = @{{"anonlist" => ["[","]"],
2767			 "anonhash" => ["{","}"]}->{$op->name}};
2768    my($expr, @exprs);
2769    $op = $op->first->sibling; # skip pushmark
2770    for (; !null($op); $op = $op->sibling) {
2771	$expr = $self->deparse($op, 6);
2772	push @exprs, $expr;
2773    }
2774    if ($pre eq "{" and $cx < 1) {
2775	# Disambiguate that it's not a block
2776	$pre = "+{";
2777    }
2778    return $pre . join(", ", @exprs) . $post;
2779}
2780
2781sub pp_anonlist {
2782    my $self = shift;
2783    my ($op, $cx) = @_;
2784    if ($op->flags & OPf_SPECIAL) {
2785	return $self->anon_hash_or_list($op, $cx);
2786    }
2787    warn "Unexpected op pp_" . $op->name() . " without OPf_SPECIAL";
2788    return 'XXX';
2789}
2790
2791*pp_anonhash = \&pp_anonlist;
2792
2793sub pp_emptyavhv {
2794    my $self = shift;
2795    my ($op, $cx, $forbid_parens) = @_;
2796    my $val = ($op->private & OPpEMPTYAVHV_IS_HV) ? '{}' : '[]';
2797    if ($op->private & OPpTARGET_MY) {
2798        my $targ = $op->targ;
2799        my $var = $self->maybe_my($op, $cx, $self->padname($targ),
2800                           $self->padname_sv($targ),
2801                           $forbid_parens);
2802        return $self->maybe_parens("$var = $val", $cx, 7);
2803    } else {
2804        return $val;
2805    }
2806}
2807
2808sub pp_refgen {
2809    my $self = shift;
2810    my($op, $cx) = @_;
2811    my $kid = $op->first;
2812    if ($kid->name eq "null") {
2813	my $anoncode = $kid = $kid->first;
2814
2815	# Perl no longer generates this, but XS modules might:
2816	if ($anoncode->name eq "anonconst") {
2817	    $anoncode = $anoncode->first->first->sibling;
2818	}
2819
2820	# Same as with `anonconst`:
2821	if ($anoncode->name eq "anoncode"
2822	 or !null($anoncode = $kid->sibling) and
2823		 $anoncode->name eq "anoncode") {
2824            return $self->e_anoncode({ code => $self->padval($anoncode->targ) });
2825
2826	# Perl still generates this:
2827	} elsif ($kid->name eq "pushmark") {
2828            my $sib_name = $kid->sibling->name;
2829            if ($sib_name eq 'entersub') {
2830                my $text = $self->deparse($kid->sibling, 1);
2831                # Always show parens for \(&func()), but only with -p otherwise
2832                $text = "($text)" if $self->{'parens'}
2833                                 or $kid->sibling->private & OPpENTERSUB_AMPER;
2834                return "\\$text";
2835            }
2836        }
2837    }
2838    local $self->{'in_refgen'} = 1;
2839    $self->pfixop($op, $cx, "\\", 20);
2840}
2841
2842sub e_anoncode {
2843    my ($self, $info) = @_;
2844    my $text = $self->deparse_sub($info->{code});
2845    return $self->keyword("sub") . " $text";
2846}
2847
2848sub pp_anoncode {
2849    my ($self, $anoncode) = @_;
2850
2851    return $self->e_anoncode( { code => $self->padval($anoncode->targ) } );
2852}
2853
2854sub pp_anonconst {
2855    my ($self, $anonconst) = @_;
2856
2857    return $self->pp_anoncode( $anonconst->first->first->sibling );
2858}
2859
2860sub pp_srefgen { pp_refgen(@_) }
2861
2862sub pp_readline {
2863    my $self = shift;
2864    my($op, $cx) = @_;
2865    my $kid = $op->first;
2866    if (is_scalar($kid)
2867        and $op->flags & OPf_SPECIAL
2868        and $self->deparse($kid, 1) eq 'ARGV')
2869    {
2870        return '<<>>';
2871    }
2872    return $self->unop($op, $cx, "readline");
2873}
2874
2875sub pp_rcatline {
2876    my $self = shift;
2877    my($op) = @_;
2878    return "<" . $self->gv_name($self->gv_or_padgv($op)) . ">";
2879}
2880
2881# Unary operators that can occur as pseudo-listops inside double quotes
2882sub dq_unop {
2883    my $self = shift;
2884    my($op, $cx, $name, $prec, $flags) = (@_, 0, 0);
2885    my $kid;
2886    if ($op->flags & OPf_KIDS) {
2887       $kid = $op->first;
2888       # If there's more than one kid, the first is an ex-pushmark.
2889       $kid = $kid->sibling if not null $kid->sibling;
2890       return $self->maybe_parens_unop($name, $kid, $cx);
2891    } else {
2892       return $name .  ($op->flags & OPf_SPECIAL ? "()" : "");
2893    }
2894}
2895
2896sub pp_ucfirst { dq_unop(@_, "ucfirst") }
2897sub pp_lcfirst { dq_unop(@_, "lcfirst") }
2898sub pp_uc { dq_unop(@_, "uc") }
2899sub pp_lc { dq_unop(@_, "lc") }
2900sub pp_quotemeta { maybe_targmy(@_, \&dq_unop, "quotemeta") }
2901sub pp_fc { dq_unop(@_, "fc") }
2902
2903sub loopex {
2904    my $self = shift;
2905    my ($op, $cx, $name) = @_;
2906    if (class($op) eq "PVOP") {
2907	$name .= " " . $op->pv;
2908    } elsif (class($op) eq "OP") {
2909	# no-op
2910    } elsif (class($op) eq "UNOP") {
2911	(my $kid = $self->deparse($op->first, 7)) =~ s/^\cS//;
2912	# last foo() is a syntax error.
2913	$kid =~ /^(?!\d)\w/ and $kid = "($kid)";
2914	$name .= " $kid";
2915    }
2916    return $self->maybe_parens($name, $cx, 7);
2917}
2918
2919sub pp_last { loopex(@_, "last") }
2920sub pp_next { loopex(@_, "next") }
2921sub pp_redo { loopex(@_, "redo") }
2922sub pp_goto { loopex(@_, "goto") }
2923sub pp_dump { loopex(@_, "CORE::dump") }
2924
2925sub ftst {
2926    my $self = shift;
2927    my($op, $cx, $name) = @_;
2928    if (class($op) eq "UNOP") {
2929	# Genuine '-X' filetests are exempt from the LLAFR, but not
2930	# l?stat()
2931	if ($name =~ /^-/) {
2932	    (my $kid = $self->deparse($op->first, 16)) =~ s/^\cS//;
2933	    return $self->maybe_parens("$name $kid", $cx, 16);
2934	}
2935	return $self->maybe_parens_unop($name, $op->first, $cx);
2936    } elsif (class($op) =~ /^(SV|PAD)OP$/) {
2937	return $self->maybe_parens_func($name, $self->pp_gv($op, 1), $cx, 16);
2938    } else { # I don't think baseop filetests ever survive ck_ftst, but...
2939	return $name;
2940    }
2941}
2942
2943sub pp_lstat    { ftst(@_, "lstat") }
2944sub pp_stat     { ftst(@_, "stat") }
2945sub pp_ftrread  { ftst(@_, "-R") }
2946sub pp_ftrwrite { ftst(@_, "-W") }
2947sub pp_ftrexec  { ftst(@_, "-X") }
2948sub pp_fteread  { ftst(@_, "-r") }
2949sub pp_ftewrite { ftst(@_, "-w") }
2950sub pp_fteexec  { ftst(@_, "-x") }
2951sub pp_ftis     { ftst(@_, "-e") }
2952sub pp_fteowned { ftst(@_, "-O") }
2953sub pp_ftrowned { ftst(@_, "-o") }
2954sub pp_ftzero   { ftst(@_, "-z") }
2955sub pp_ftsize   { ftst(@_, "-s") }
2956sub pp_ftmtime  { ftst(@_, "-M") }
2957sub pp_ftatime  { ftst(@_, "-A") }
2958sub pp_ftctime  { ftst(@_, "-C") }
2959sub pp_ftsock   { ftst(@_, "-S") }
2960sub pp_ftchr    { ftst(@_, "-c") }
2961sub pp_ftblk    { ftst(@_, "-b") }
2962sub pp_ftfile   { ftst(@_, "-f") }
2963sub pp_ftdir    { ftst(@_, "-d") }
2964sub pp_ftpipe   { ftst(@_, "-p") }
2965sub pp_ftlink   { ftst(@_, "-l") }
2966sub pp_ftsuid   { ftst(@_, "-u") }
2967sub pp_ftsgid   { ftst(@_, "-g") }
2968sub pp_ftsvtx   { ftst(@_, "-k") }
2969sub pp_fttty    { ftst(@_, "-t") }
2970sub pp_fttext   { ftst(@_, "-T") }
2971sub pp_ftbinary { ftst(@_, "-B") }
2972
2973sub SWAP_CHILDREN () { 1 }
2974sub ASSIGN () { 2 } # has OP= variant
2975sub LIST_CONTEXT () { 4 } # Assignment is in list context
2976
2977my(%left, %right);
2978
2979sub assoc_class {
2980    my $op = shift;
2981    my $name = $op->name;
2982    if ($name eq "concat" and $op->first->name eq "concat") {
2983	# avoid spurious '=' -- see comment in pp_concat
2984	return "concat";
2985    }
2986    if ($name eq "null" and class($op) eq "UNOP"
2987	and $op->first->name =~ /^(and|x?or)$/
2988	and null $op->first->sibling)
2989    {
2990	# Like all conditional constructs, OP_ANDs and OP_ORs are topped
2991	# with a null that's used as the common end point of the two
2992	# flows of control. For precedence purposes, ignore it.
2993	# (COND_EXPRs have these too, but we don't bother with
2994	# their associativity).
2995	return assoc_class($op->first);
2996    }
2997    return $name . ($op->flags & OPf_STACKED ? "=" : "");
2998}
2999
3000# Left associative operators, like '+', for which
3001# $a + $b + $c is equivalent to ($a + $b) + $c
3002
3003BEGIN {
3004    %left = ('multiply' => 19, 'i_multiply' => 19,
3005	     'divide' => 19, 'i_divide' => 19,
3006	     'modulo' => 19, 'i_modulo' => 19,
3007	     'repeat' => 19,
3008	     'add' => 18, 'i_add' => 18,
3009	     'subtract' => 18, 'i_subtract' => 18,
3010	     'concat' => 18,
3011	     'left_shift' => 17, 'right_shift' => 17,
3012	     'bit_and' => 13, 'nbit_and' => 13, 'sbit_and' => 13,
3013	     'bit_or' => 12, 'bit_xor' => 12,
3014	     'sbit_or' => 12, 'sbit_xor' => 12,
3015	     'nbit_or' => 12, 'nbit_xor' => 12,
3016	     'and' => 3,
3017	     'or' => 2, 'xor' => 2,
3018	    );
3019}
3020
3021sub deparse_binop_left {
3022    my $self = shift;
3023    my($op, $left, $prec) = @_;
3024    if ($left{assoc_class($op)} && $left{assoc_class($left)}
3025	and $left{assoc_class($op)} == $left{assoc_class($left)})
3026    {
3027	return $self->deparse($left, $prec - .00001);
3028    } else {
3029	return $self->deparse($left, $prec);
3030    }
3031}
3032
3033# Right associative operators, like '=', for which
3034# $a = $b = $c is equivalent to $a = ($b = $c)
3035
3036BEGIN {
3037    %right = ('pow' => 22,
3038	      'sassign=' => 7, 'aassign=' => 7,
3039	      'multiply=' => 7, 'i_multiply=' => 7,
3040	      'divide=' => 7, 'i_divide=' => 7,
3041	      'modulo=' => 7, 'i_modulo=' => 7,
3042	      'repeat=' => 7, 'refassign' => 7, 'refassign=' => 7,
3043	      'add=' => 7, 'i_add=' => 7,
3044	      'subtract=' => 7, 'i_subtract=' => 7,
3045	      'concat=' => 7,
3046	      'left_shift=' => 7, 'right_shift=' => 7,
3047	      'bit_and=' => 7, 'sbit_and=' => 7, 'nbit_and=' => 7,
3048	      'nbit_or=' => 7, 'nbit_xor=' => 7,
3049	      'sbit_or=' => 7, 'sbit_xor=' => 7,
3050	      'andassign' => 7,
3051	      'orassign' => 7,
3052	     );
3053}
3054
3055sub deparse_binop_right {
3056    my $self = shift;
3057    my($op, $right, $prec) = @_;
3058    if ($right{assoc_class($op)} && $right{assoc_class($right)}
3059	and $right{assoc_class($op)} == $right{assoc_class($right)})
3060    {
3061	return $self->deparse($right, $prec - .00001);
3062    } else {
3063	return $self->deparse($right, $prec);
3064    }
3065}
3066
3067sub binop {
3068    my $self = shift;
3069    my ($op, $cx, $opname, $prec, $flags) = (@_, 0);
3070    my $left = $op->first;
3071    my $right = $op->last;
3072    my $eq = "";
3073    if ($op->flags & OPf_STACKED && $flags & ASSIGN) {
3074	$eq = "=";
3075	$prec = 7;
3076    }
3077    if ($flags & SWAP_CHILDREN) {
3078	($left, $right) = ($right, $left);
3079    }
3080    my $leftop = $left;
3081    $left = $self->deparse_binop_left($op, $left, $prec);
3082    $left = "($left)" if $flags & LIST_CONTEXT
3083		     and    $left !~ /^(my|our|local|state|)\s*[\@%\(]/
3084			 || do {
3085				# Parenthesize if the left argument is a
3086				# lone repeat op.
3087				my $left = $leftop->first->sibling;
3088				$left->name eq 'repeat'
3089				    && null($left->sibling);
3090			    };
3091    $right = $self->deparse_binop_right($op, $right, $prec);
3092    return $self->maybe_parens("$left $opname$eq $right", $cx, $prec);
3093}
3094
3095sub pp_add { maybe_targmy(@_, \&binop, "+", 18, ASSIGN) }
3096sub pp_multiply { maybe_targmy(@_, \&binop, "*", 19, ASSIGN) }
3097sub pp_subtract { maybe_targmy(@_, \&binop, "-",18,  ASSIGN) }
3098sub pp_divide { maybe_targmy(@_, \&binop, "/", 19, ASSIGN) }
3099sub pp_modulo { maybe_targmy(@_, \&binop, "%", 19, ASSIGN) }
3100sub pp_i_add { maybe_targmy(@_, \&binop, "+", 18, ASSIGN) }
3101sub pp_i_multiply { maybe_targmy(@_, \&binop, "*", 19, ASSIGN) }
3102sub pp_i_subtract { maybe_targmy(@_, \&binop, "-", 18, ASSIGN) }
3103sub pp_i_divide { maybe_targmy(@_, \&binop, "/", 19, ASSIGN) }
3104sub pp_i_modulo { maybe_targmy(@_, \&binop, "%", 19, ASSIGN) }
3105sub pp_pow { maybe_targmy(@_, \&binop, "**", 22, ASSIGN) }
3106
3107sub pp_left_shift { maybe_targmy(@_, \&binop, "<<", 17, ASSIGN) }
3108sub pp_right_shift { maybe_targmy(@_, \&binop, ">>", 17, ASSIGN) }
3109sub pp_bit_and { maybe_targmy(@_, \&binop, "&", 13, ASSIGN) }
3110sub pp_bit_or { maybe_targmy(@_, \&binop, "|", 12, ASSIGN) }
3111sub pp_bit_xor { maybe_targmy(@_, \&binop, "^", 12, ASSIGN) }
3112*pp_nbit_and = *pp_bit_and;
3113*pp_nbit_or  = *pp_bit_or;
3114*pp_nbit_xor = *pp_bit_xor;
3115sub pp_sbit_and { maybe_targmy(@_, \&binop, "&.", 13, ASSIGN) }
3116sub pp_sbit_or { maybe_targmy(@_, \&binop, "|.", 12, ASSIGN) }
3117sub pp_sbit_xor { maybe_targmy(@_, \&binop, "^.", 12, ASSIGN) }
3118
3119sub pp_eq { binop(@_, "==", 14) }
3120sub pp_ne { binop(@_, "!=", 14) }
3121sub pp_lt { binop(@_, "<", 15) }
3122sub pp_gt { binop(@_, ">", 15) }
3123sub pp_ge { binop(@_, ">=", 15) }
3124sub pp_le { binop(@_, "<=", 15) }
3125sub pp_ncmp { binop(@_, "<=>", 14) }
3126sub pp_i_eq { binop(@_, "==", 14) }
3127sub pp_i_ne { binop(@_, "!=", 14) }
3128sub pp_i_lt { binop(@_, "<", 15) }
3129sub pp_i_gt { binop(@_, ">", 15) }
3130sub pp_i_ge { binop(@_, ">=", 15) }
3131sub pp_i_le { binop(@_, "<=", 15) }
3132sub pp_i_ncmp { maybe_targmy(@_, \&binop, "<=>", 14) }
3133
3134sub pp_seq { binop(@_, "eq", 14) }
3135sub pp_sne { binop(@_, "ne", 14) }
3136sub pp_slt { binop(@_, "lt", 15) }
3137sub pp_sgt { binop(@_, "gt", 15) }
3138sub pp_sge { binop(@_, "ge", 15) }
3139sub pp_sle { binop(@_, "le", 15) }
3140sub pp_scmp { maybe_targmy(@_, \&binop, "cmp", 14) }
3141
3142sub pp_isa { binop(@_, "isa", 15) }
3143
3144sub pp_sassign { binop(@_, "=", 7, SWAP_CHILDREN) }
3145sub pp_aassign { binop(@_, "=", 7, SWAP_CHILDREN | LIST_CONTEXT) }
3146
3147sub pp_padsv_store {
3148    my $self = shift;
3149    my ($op, $cx, $forbid_parens, @args) = @_;
3150    my $targ = $op->targ;
3151    my $var = $self->maybe_my($op, $cx, $self->padname($targ),
3152                           $self->padname_sv($targ),
3153                           $forbid_parens);
3154
3155    my $val = $self->deparse($op->first, 7);
3156    return $self->maybe_parens("$var = $val", $cx, 7);
3157}
3158
3159sub pp_smartmatch {
3160    my ($self, $op, $cx) = @_;
3161    if (($op->flags & OPf_SPECIAL) && $self->{expand} < 2) {
3162	return $self->deparse($op->last, $cx);
3163    }
3164    else {
3165	binop(@_, "~~", 14);
3166    }
3167}
3168
3169# '.' is special because concats-of-concats are optimized to save copying
3170# by making all but the first concat stacked. The effect is as if the
3171# programmer had written '($a . $b) .= $c', except legal.
3172sub pp_concat { maybe_targmy(@_, \&real_concat) }
3173sub real_concat {
3174    my $self = shift;
3175    my($op, $cx) = @_;
3176    my $left = $op->first;
3177    my $right = $op->last;
3178    my $eq = "";
3179    my $prec = 18;
3180    if (($op->flags & OPf_STACKED) and !($op->private & OPpCONCAT_NESTED)) {
3181        # '.=' rather than optimised '.'
3182	$eq = "=";
3183	$prec = 7;
3184    }
3185    $left = $self->deparse_binop_left($op, $left, $prec);
3186    $right = $self->deparse_binop_right($op, $right, $prec);
3187    return $self->maybe_parens("$left .$eq $right", $cx, $prec);
3188}
3189
3190sub pp_repeat { maybe_targmy(@_, \&repeat) }
3191
3192# 'x' is weird when the left arg is a list
3193sub repeat {
3194    my $self = shift;
3195    my($op, $cx) = @_;
3196    my $left = $op->first;
3197    my $right = $op->last;
3198    my $eq = "";
3199    my $prec = 19;
3200    if ($op->flags & OPf_STACKED) {
3201	$eq = "=";
3202	$prec = 7;
3203    }
3204    if (null($right)) { # list repeat; count is inside left-side ex-list
3205			# in 5.21.5 and earlier
3206	my $kid = $left->first->sibling; # skip pushmark
3207	my @exprs;
3208	for (; !null($kid->sibling); $kid = $kid->sibling) {
3209	    push @exprs, $self->deparse($kid, 6);
3210	}
3211	$right = $kid;
3212	$left = "(" . join(", ", @exprs). ")";
3213    } else {
3214	my $dolist = $op->private & OPpREPEAT_DOLIST;
3215	$left = $self->deparse_binop_left($op, $left, $dolist ? 1 : $prec);
3216	if ($dolist) {
3217	    $left = "($left)";
3218	}
3219    }
3220    $right = $self->deparse_binop_right($op, $right, $prec);
3221    return $self->maybe_parens("$left x$eq $right", $cx, $prec);
3222}
3223
3224sub range {
3225    my $self = shift;
3226    my ($op, $cx, $type) = @_;
3227    my $left = $op->first;
3228    my $right = $left->sibling;
3229    $left = $self->deparse($left, 9);
3230    $right = $self->deparse($right, 9);
3231    return $self->maybe_parens("$left $type $right", $cx, 9);
3232}
3233
3234sub pp_flop {
3235    my $self = shift;
3236    my($op, $cx) = @_;
3237    my $flip = $op->first;
3238    my $type = ($flip->flags & OPf_SPECIAL) ? "..." : "..";
3239    return $self->range($flip->first, $cx, $type);
3240}
3241
3242# one-line while/until is handled in pp_leave
3243
3244sub logop {
3245    my $self = shift;
3246    my ($op, $cx, $lowop, $lowprec, $highop, $highprec, $blockname) = @_;
3247    my $left = $op->first;
3248    my $right = $op->first->sibling;
3249    $blockname &&= $self->keyword($blockname);
3250    if ($cx < 1 and is_scope($right) and $blockname
3251	and $self->{'expand'} < 7)
3252    { # if ($a) {$b}
3253	$left = $self->deparse($left, 1);
3254	$right = $self->deparse($right, 0);
3255	return "$blockname ($left) {\n\t$right\n\b}\cK";
3256    } elsif ($cx < 1 and $blockname and not $self->{'parens'}
3257	     and $self->{'expand'} < 7) { # $b if $a
3258	$right = $self->deparse($right, 1);
3259	$left = $self->deparse($left, 1);
3260	return "$right $blockname $left";
3261    } elsif ($cx > $lowprec and $highop) { # $a && $b
3262	$left = $self->deparse_binop_left($op, $left, $highprec);
3263	$right = $self->deparse_binop_right($op, $right, $highprec);
3264	return $self->maybe_parens("$left $highop $right", $cx, $highprec);
3265    } else { # $a and $b
3266	$left = $self->deparse_binop_left($op, $left, $lowprec);
3267	$right = $self->deparse_binop_right($op, $right, $lowprec);
3268	return $self->maybe_parens("$left $lowop $right", $cx, $lowprec);
3269    }
3270}
3271
3272sub pp_and { logop(@_, "and", 3, "&&", 11, "if") }
3273sub pp_or  { logop(@_, "or",  2, "||", 10, "unless") }
3274sub pp_dor { logop(@_, "//", 10) }
3275
3276# xor is syntactically a logop, but it's really a binop (contrary to
3277# old versions of opcode.pl). Syntax is what matters here.
3278sub pp_xor { logop(@_, "xor", 2, "",   0,  "") }
3279
3280sub logassignop {
3281    my $self = shift;
3282    my ($op, $cx, $opname) = @_;
3283    my $left = $op->first;
3284    my $right = $op->first->sibling->first; # skip sassign
3285    $left = $self->deparse($left, 7);
3286    $right = $self->deparse($right, 7);
3287    return $self->maybe_parens("$left $opname $right", $cx, 7);
3288}
3289
3290sub pp_andassign { logassignop(@_, "&&=") }
3291sub pp_orassign  { logassignop(@_, "||=") }
3292sub pp_dorassign { logassignop(@_, "//=") }
3293
3294my %cmpchain_cmpops = (
3295	eq => ["==", 14],
3296	i_eq => ["==", 14],
3297	ne => ["!=", 14],
3298	i_ne => ["!=", 14],
3299	seq => ["eq", 14],
3300	sne => ["ne", 14],
3301	lt => ["<", 15],
3302	i_lt => ["<", 15],
3303	gt => [">", 15],
3304	i_gt => [">", 15],
3305	le => ["<=", 15],
3306	i_le => ["<=", 15],
3307	ge => [">=", 15],
3308	i_ge => [">=", 15],
3309	slt => ["lt", 15],
3310	sgt => ["gt", 15],
3311	sle => ["le", 15],
3312	sge => ["ge", 15],
3313);
3314sub pp_cmpchain_and {
3315    my($self, $op, $cx) = @_;
3316    my($prec, $dep);
3317    while(1) {
3318	my($thiscmp, $rightcond);
3319	if($op->name eq "cmpchain_and") {
3320	    $thiscmp = $op->first;
3321	    $rightcond = $thiscmp->sibling;
3322	} else {
3323	    $thiscmp = $op;
3324	}
3325	my $thiscmptype = $cmpchain_cmpops{$thiscmp->name} // (return "XXX");
3326	if(defined $prec) {
3327	    $thiscmptype->[1] == $prec or return "XXX";
3328	    $thiscmp->first->name eq "null" &&
3329		    !($thiscmp->first->flags & OPf_KIDS)
3330		or return "XXX";
3331	} else {
3332	    $prec = $thiscmptype->[1];
3333	    $dep = $self->deparse($thiscmp->first, $prec);
3334	}
3335	$dep .= " ".$thiscmptype->[0]." ";
3336	my $operand = $thiscmp->last;
3337	if(defined $rightcond) {
3338	    $operand->name eq "cmpchain_dup" or return "XXX";
3339	    $operand = $operand->first;
3340	}
3341	$dep .= $self->deparse($operand, $prec);
3342	last unless defined $rightcond;
3343	if($rightcond->name eq "null" && ($rightcond->flags & OPf_KIDS) &&
3344		$rightcond->first->name eq "cmpchain_and") {
3345	    $rightcond = $rightcond->first;
3346	}
3347	$op = $rightcond;
3348    }
3349    return $self->maybe_parens($dep, $cx, $prec);
3350}
3351
3352sub rv2gv_or_string {
3353    my($self,$op) = @_;
3354    if ($op->name eq "gv") { # could be open("open") or open("###")
3355	my($name,$quoted) =
3356	    $self->stash_variable_name("", $self->gv_or_padgv($op));
3357	$quoted ? $name : "*$name";
3358    }
3359    else {
3360	$self->deparse($op, 6);
3361    }
3362}
3363
3364sub listop {
3365    my $self = shift;
3366    my($op, $cx, $name, $kid, $nollafr) = @_;
3367    my(@exprs);
3368    my $parens = ($cx >= 5) || $self->{'parens'};
3369    $kid ||= $op->first->sibling;
3370    # If there are no arguments, add final parentheses (or parenthesize the
3371    # whole thing if the llafr does not apply) to account for cases like
3372    # (return)+1 or setpgrp()+1.  When the llafr does not apply, we use a
3373    # precedence of 6 (< comma), as "return, 1" does not need parentheses.
3374    if (null $kid) {
3375	return $nollafr
3376		? $self->maybe_parens($self->keyword($name), $cx, 7)
3377		: $self->keyword($name) . '()' x (7 < $cx);
3378    }
3379    my $first;
3380    my $fullname = $self->keyword($name);
3381    my $proto = prototype("CORE::$name");
3382    if (
3383	 (     (defined $proto && $proto =~ /^;?\*/)
3384	    || $name eq 'select' # select(F) doesn't have a proto
3385	 )
3386	 && $kid->name eq "rv2gv"
3387	 && !($kid->private & OPpLVAL_INTRO)
3388    ) {
3389	$first = $self->rv2gv_or_string($kid->first);
3390    }
3391    else {
3392	$first = $self->deparse($kid, 6);
3393    }
3394    if ($name eq "chmod" && $first =~ /^\d+$/) {
3395	$first = sprintf("%#o", $first);
3396    }
3397    $first = "+$first"
3398	if not $parens and not $nollafr and substr($first, 0, 1) eq "(";
3399    push @exprs, $first;
3400    $kid = $kid->sibling;
3401    if (defined $proto && $proto =~ /^\*\*/ && $kid->name eq "rv2gv"
3402	 && !($kid->private & OPpLVAL_INTRO)) {
3403	push @exprs, $first = $self->rv2gv_or_string($kid->first);
3404	$kid = $kid->sibling;
3405    }
3406    for (; !null($kid); $kid = $kid->sibling) {
3407	push @exprs, $self->deparse($kid, 6);
3408    }
3409    if ($name eq "reverse" && ($op->private & OPpREVERSE_INPLACE)) {
3410	return "$exprs[0] = $fullname"
3411	         . ($parens ? "($exprs[0])" : " $exprs[0]");
3412    }
3413
3414    if ($parens && $nollafr) {
3415	return "($fullname " . join(", ", @exprs) . ")";
3416    } elsif ($parens) {
3417	return "$fullname(" . join(", ", @exprs) . ")";
3418    } else {
3419	return "$fullname " . join(", ", @exprs);
3420    }
3421}
3422
3423sub pp_bless { listop(@_, "bless") }
3424sub pp_atan2 { maybe_targmy(@_, \&listop, "atan2") }
3425sub pp_substr {
3426    my ($self,$op,$cx) = @_;
3427    if ($op->private & OPpSUBSTR_REPL_FIRST) {
3428	return
3429	   listop($self, $op, 7, "substr", $op->first->sibling->sibling)
3430	 . " = "
3431	 . $self->deparse($op->first->sibling, 7);
3432    }
3433    maybe_local(@_, listop(@_, "substr"))
3434}
3435
3436sub pp_index {
3437    # Also handles pp_rindex.
3438    #
3439    # The body of this function includes an unrolled maybe_targmy(),
3440    # since the two parts of that sub's actions need to have have the
3441    # '== -1' bit in between
3442
3443    my($self, $op, $cx) = @_;
3444
3445    my $lex  = ($op->private & OPpTARGET_MY);
3446    my $bool = ($op->private & OPpTRUEBOOL);
3447
3448    my $val = $self->listop($op, ($bool ? 14 : $lex ? 7 : $cx), $op->name);
3449
3450    # (index() == -1) has op_eq and op_const optimised away
3451    if ($bool) {
3452        $val .= ($op->private & OPpINDEX_BOOLNEG) ? " == -1" : " != -1";
3453        $val = "($val)" if ($op->flags & OPf_PARENS);
3454    }
3455    if ($lex) {
3456	my $var = $self->padname($op->targ);
3457	$val = $self->maybe_parens("$var = $val", $cx, 7);
3458    }
3459    $val;
3460}
3461
3462sub pp_rindex { pp_index(@_); }
3463sub pp_vec { maybe_targmy(@_, \&maybe_local, listop(@_, "vec")) }
3464sub pp_sprintf { maybe_targmy(@_, \&listop, "sprintf") }
3465sub pp_formline { listop(@_, "formline") } # see also deparse_format
3466sub pp_crypt { maybe_targmy(@_, \&listop, "crypt") }
3467sub pp_unpack { listop(@_, "unpack") }
3468sub pp_pack { listop(@_, "pack") }
3469sub pp_join { maybe_targmy(@_, \&listop, "join") }
3470sub pp_splice { listop(@_, "splice") }
3471sub pp_push { maybe_targmy(@_, \&listop, "push") }
3472sub pp_unshift { maybe_targmy(@_, \&listop, "unshift") }
3473sub pp_reverse { listop(@_, "reverse") }
3474sub pp_warn { listop(@_, "warn") }
3475sub pp_die { listop(@_, "die") }
3476sub pp_return { listop(@_, "return", undef, 1) } # llafr does not apply
3477sub pp_open { listop(@_, "open") }
3478sub pp_pipe_op { listop(@_, "pipe") }
3479sub pp_tie { listop(@_, "tie") }
3480sub pp_binmode { listop(@_, "binmode") }
3481sub pp_dbmopen { listop(@_, "dbmopen") }
3482sub pp_sselect { listop(@_, "select") }
3483sub pp_select { listop(@_, "select") }
3484sub pp_read { listop(@_, "read") }
3485sub pp_sysopen { listop(@_, "sysopen") }
3486sub pp_sysseek { listop(@_, "sysseek") }
3487sub pp_sysread { listop(@_, "sysread") }
3488sub pp_syswrite { listop(@_, "syswrite") }
3489sub pp_send { listop(@_, "send") }
3490sub pp_recv { listop(@_, "recv") }
3491sub pp_seek { listop(@_, "seek") }
3492sub pp_fcntl { listop(@_, "fcntl") }
3493sub pp_ioctl { listop(@_, "ioctl") }
3494sub pp_flock { maybe_targmy(@_, \&listop, "flock") }
3495sub pp_socket { listop(@_, "socket") }
3496sub pp_sockpair { listop(@_, "socketpair") }
3497sub pp_bind { listop(@_, "bind") }
3498sub pp_connect { listop(@_, "connect") }
3499sub pp_listen { listop(@_, "listen") }
3500sub pp_accept { listop(@_, "accept") }
3501sub pp_shutdown { listop(@_, "shutdown") }
3502sub pp_gsockopt { listop(@_, "getsockopt") }
3503sub pp_ssockopt { listop(@_, "setsockopt") }
3504sub pp_chown { maybe_targmy(@_, \&listop, "chown") }
3505sub pp_unlink { maybe_targmy(@_, \&listop, "unlink") }
3506sub pp_chmod { maybe_targmy(@_, \&listop, "chmod") }
3507sub pp_utime { maybe_targmy(@_, \&listop, "utime") }
3508sub pp_rename { maybe_targmy(@_, \&listop, "rename") }
3509sub pp_link { maybe_targmy(@_, \&listop, "link") }
3510sub pp_symlink { maybe_targmy(@_, \&listop, "symlink") }
3511sub pp_mkdir { maybe_targmy(@_, \&listop, "mkdir") }
3512sub pp_open_dir { listop(@_, "opendir") }
3513sub pp_seekdir { listop(@_, "seekdir") }
3514sub pp_waitpid { maybe_targmy(@_, \&listop, "waitpid") }
3515sub pp_system { maybe_targmy(@_, \&indirop, "system") }
3516sub pp_exec { maybe_targmy(@_, \&indirop, "exec") }
3517sub pp_kill { maybe_targmy(@_, \&listop, "kill") }
3518sub pp_setpgrp { maybe_targmy(@_, \&listop, "setpgrp") }
3519sub pp_getpriority { maybe_targmy(@_, \&listop, "getpriority") }
3520sub pp_setpriority { maybe_targmy(@_, \&listop, "setpriority") }
3521sub pp_shmget { listop(@_, "shmget") }
3522sub pp_shmctl { listop(@_, "shmctl") }
3523sub pp_shmread { listop(@_, "shmread") }
3524sub pp_shmwrite { listop(@_, "shmwrite") }
3525sub pp_msgget { listop(@_, "msgget") }
3526sub pp_msgctl { listop(@_, "msgctl") }
3527sub pp_msgsnd { listop(@_, "msgsnd") }
3528sub pp_msgrcv { listop(@_, "msgrcv") }
3529sub pp_semget { listop(@_, "semget") }
3530sub pp_semctl { listop(@_, "semctl") }
3531sub pp_semop { listop(@_, "semop") }
3532sub pp_ghbyaddr { listop(@_, "gethostbyaddr") }
3533sub pp_gnbyaddr { listop(@_, "getnetbyaddr") }
3534sub pp_gpbynumber { listop(@_, "getprotobynumber") }
3535sub pp_gsbyname { listop(@_, "getservbyname") }
3536sub pp_gsbyport { listop(@_, "getservbyport") }
3537sub pp_syscall { listop(@_, "syscall") }
3538
3539sub pp_glob {
3540    my $self = shift;
3541    my($op, $cx) = @_;
3542    my $kid = $op->first->sibling;  # skip pushmark
3543    my $keyword =
3544	$op->flags & OPf_SPECIAL ? 'glob' : $self->keyword('glob');
3545    my $text = $self->deparse($kid, $cx);
3546    return $cx >= 5 || $self->{'parens'}
3547	? "$keyword($text)"
3548	: "$keyword $text";
3549}
3550
3551# Truncate is special because OPf_SPECIAL makes a bareword first arg
3552# be a filehandle. This could probably be better fixed in the core
3553# by moving the GV lookup into ck_truc.
3554
3555sub pp_truncate {
3556    my $self = shift;
3557    my($op, $cx) = @_;
3558    my(@exprs);
3559    my $parens = ($cx >= 5) || $self->{'parens'};
3560    my $kid = $op->first->sibling;
3561    my $fh;
3562    if ($op->flags & OPf_SPECIAL) {
3563	# $kid is an OP_CONST
3564	$fh = $self->const_sv($kid)->PV;
3565    } else {
3566	$fh = $self->deparse($kid, 6);
3567        $fh = "+$fh" if not $parens and substr($fh, 0, 1) eq "(";
3568    }
3569    my $len = $self->deparse($kid->sibling, 6);
3570    my $name = $self->keyword('truncate');
3571    if ($parens) {
3572	return "$name($fh, $len)";
3573    } else {
3574	return "$name $fh, $len";
3575    }
3576}
3577
3578sub indirop {
3579    my $self = shift;
3580    my($op, $cx, $name) = @_;
3581    my($expr, @exprs);
3582    my $firstkid = my $kid = $op->first->sibling;
3583    my $indir = "";
3584    if ($op->flags & OPf_STACKED) {
3585	$indir = $kid;
3586	$indir = $indir->first; # skip rv2gv
3587	if (is_scope($indir)) {
3588	    $indir = "{" . $self->deparse($indir, 0) . "}";
3589	    $indir = "{;}" if $indir eq "{}";
3590	} elsif ($indir->name eq "const" && $indir->private & OPpCONST_BARE) {
3591	    $indir = $self->const_sv($indir)->PV;
3592	} else {
3593	    $indir = $self->deparse($indir, 24);
3594	}
3595	$indir = $indir . " ";
3596	$kid = $kid->sibling;
3597    }
3598    if ($name eq "sort" && $op->private & (OPpSORT_NUMERIC | OPpSORT_INTEGER)) {
3599	$indir = ($op->private & OPpSORT_DESCEND) ? '{$b <=> $a} '
3600						  : '{$a <=> $b} ';
3601    }
3602    elsif ($name eq "sort" && $op->private & OPpSORT_DESCEND) {
3603	$indir = '{$b cmp $a} ';
3604    }
3605    for (; !null($kid); $kid = $kid->sibling) {
3606	$expr = $self->deparse($kid, !$indir && $kid == $firstkid && $name eq "sort" && $firstkid->name eq "entersub" ? 16 : 6);
3607	push @exprs, $expr;
3608    }
3609    my $name2;
3610    if ($name eq "sort" && $op->private & OPpSORT_REVERSE) {
3611	$name2 = $self->keyword('reverse') . ' ' . $self->keyword('sort');
3612    }
3613    else { $name2 = $self->keyword($name) }
3614    if ($name eq "sort" && ($op->private & OPpSORT_INPLACE)) {
3615	return "$exprs[0] = $name2 $indir $exprs[0]";
3616    }
3617
3618    my $args = $indir . join(", ", @exprs);
3619    if ($indir ne "" && $name eq "sort") {
3620	# We don't want to say "sort(f 1, 2, 3)", since perl -w will
3621	# give bareword warnings in that case. Therefore if context
3622	# requires, we'll put parens around the outside "(sort f 1, 2,
3623	# 3)". Unfortunately, we'll currently think the parens are
3624	# necessary more often that they really are, because we don't
3625	# distinguish which side of an assignment we're on.
3626	if ($cx >= 5) {
3627	    return "($name2 $args)";
3628	} else {
3629	    return "$name2 $args";
3630	}
3631    } elsif (
3632	!$indir && $name eq "sort"
3633      && !null($op->first->sibling)
3634      && $op->first->sibling->name eq 'entersub'
3635    ) {
3636	# We cannot say sort foo(bar), as foo will be interpreted as a
3637	# comparison routine.  We have to say sort(...) in that case.
3638	return "$name2($args)";
3639    } else {
3640	return length $args
3641		? $self->maybe_parens_func($name2, $args, $cx, 5)
3642		: $name2 . '()' x (7 < $cx);
3643    }
3644
3645}
3646
3647sub pp_prtf { indirop(@_, "printf") }
3648sub pp_print { indirop(@_, "print") }
3649sub pp_say  { indirop(@_, "say") }
3650sub pp_sort { indirop(@_, "sort") }
3651
3652sub mapop {
3653    my $self = shift;
3654    my($op, $cx, $name) = @_;
3655    my($expr, @exprs);
3656    my $kid = $op->first; # this is the (map|grep)start
3657    $kid = $kid->first->sibling; # skip a pushmark
3658    my $code = $kid->first; # skip a null
3659    if (is_scope $code) {
3660	$code = "{" . $self->deparse($code, 0) . "} ";
3661    } else {
3662	$code = $self->deparse($code, 24);
3663	$code .= ", " if !null($kid->sibling);
3664    }
3665    $kid = $kid->sibling;
3666    for (; !null($kid); $kid = $kid->sibling) {
3667	$expr = $self->deparse($kid, 6);
3668	push @exprs, $expr if defined $expr;
3669    }
3670    return $self->maybe_parens_func($self->keyword($name),
3671				    $code . join(", ", @exprs), $cx, 5);
3672}
3673
3674sub pp_mapwhile { mapop(@_, "map") }
3675sub pp_grepwhile { mapop(@_, "grep") }
3676sub pp_mapstart { baseop(@_, "map") }
3677sub pp_grepstart { baseop(@_, "grep") }
3678
3679my %uses_intro;
3680BEGIN {
3681    @uses_intro{
3682	eval { require B::Op_private }
3683	  ? @{$B::Op_private::ops_using{OPpLVAL_INTRO}}
3684	  : qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice
3685	       hslice delete padsv padav padhv enteriter entersub padrange
3686	       pushmark cond_expr refassign list)
3687    } = ();
3688    delete @uses_intro{qw( lvref lvrefslice lvavref entersub )};
3689}
3690
3691
3692# Look for a my/state attribute declaration in a list or ex-list.
3693# Returns undef if not found, 'my($x, @a) :Foo(bar)' etc otherwise.
3694#
3695# There are three basic tree structs that are expected:
3696#
3697# my $x :foo;
3698#      <1> ex-list vK/LVINTRO ->c
3699#         <0> ex-pushmark v ->3
3700#         <1> entersub[t2] vKRS*/TARG ->b
3701#                ....
3702#         <0> padsv[$x:64,65] vM/LVINTRO ->c
3703#
3704# my @a :foo;
3705# my %h :foo;
3706#
3707#      <1> ex-list vK ->c
3708#         <0> ex-pushmark v ->3
3709#         <0> padav[@a:64,65] vM/LVINTRO ->4
3710#         <1> entersub[t2] vKRS*/TARG ->c
3711#            ....
3712#
3713# my ($x,@a,%h) :foo;
3714#
3715#      <;> nextstate(main 64 -e:1) v:{ ->3
3716#      <@> list vKP ->w
3717#         <0> pushmark vM/LVINTRO ->4
3718#         <0> padsv[$x:64,65] vM/LVINTRO ->5
3719#         <0> padav[@a:64,65] vM/LVINTRO ->6
3720#         <0> padhv[%h:64,65] vM/LVINTRO ->7
3721#         <1> entersub[t4] vKRS*/TARG ->f
3722#            ....
3723#         <1> entersub[t5] vKRS*/TARG ->n
3724#            ....
3725#         <1> entersub[t6] vKRS*/TARG ->v
3726#           ....
3727# where the entersub in all cases looks like
3728#        <1> entersub[t2] vKRS*/TARG ->c
3729#           <0> pushmark s ->5
3730#           <$> const[PV "attributes"] sM ->6
3731#           <$> const[PV "main"] sM ->7
3732#           <1> srefgen sKM/1 ->9
3733#              <1> ex-list lKRM ->8
3734#                 <0> padsv[@a:64,65] sRM ->8
3735#           <$> const[PV "foo"] sM ->a
3736#           <.> method_named[PV "import"] ->b
3737
3738sub maybe_var_attr {
3739    my ($self, $op, $cx) = @_;
3740
3741    my $kid = $op->first->sibling; # skip pushmark
3742    return if class($kid) eq 'NULL';
3743
3744    my $lop;
3745    my $type;
3746
3747    # Extract out all the pad ops and entersub ops into
3748    # @padops and @entersubops. Return if anything else seen.
3749    # Also determine what class (if any) all the pad vars belong to
3750    my $class;
3751    my $decl; # 'my' or 'state'
3752    my (@padops, @entersubops);
3753    for ($lop = $kid; !null($lop); $lop = $lop->sibling) {
3754	my $lopname = $lop->name;
3755	my $loppriv = $lop->private;
3756        if ($lopname =~ /^pad[sah]v$/) {
3757            return unless $loppriv & OPpLVAL_INTRO;
3758
3759            my $padname = $self->padname_sv($lop->targ);
3760            my $thisclass = ($padname->FLAGS & PADNAMEf_TYPED)
3761                                ? $padname->SvSTASH->NAME : 'main';
3762
3763            # all pad vars must be in the same class
3764            $class //= $thisclass;
3765            return unless $thisclass eq $class;
3766
3767            # all pad vars must be the same sort of declaration
3768            # (all my, all state, etc)
3769            my $this = ($loppriv & OPpPAD_STATE) ? 'state' : 'my';
3770            if (defined $decl) {
3771                return unless $this eq $decl;
3772            }
3773            $decl = $this;
3774
3775            push @padops, $lop;
3776        }
3777        elsif ($lopname eq 'entersub') {
3778            push @entersubops, $lop;
3779        }
3780        else {
3781            return;
3782        }
3783    }
3784
3785    return unless @padops && @padops == @entersubops;
3786
3787    # there should be a balance: each padop has a corresponding
3788    # 'attributes'->import() method call, in the same order.
3789
3790    my @varnames;
3791    my $attr_text;
3792
3793    for my $i (0..$#padops) {
3794        my $padop = $padops[$i];
3795        my $esop  = $entersubops[$i];
3796
3797        push @varnames, $self->padname($padop->targ);
3798
3799        return unless ($esop->flags & OPf_KIDS);
3800
3801        my $kid = $esop->first;
3802        return unless $kid->type == OP_PUSHMARK;
3803
3804        $kid = $kid->sibling;
3805        return unless $$kid && $kid->type == OP_CONST;
3806	return unless $self->const_sv($kid)->PV eq 'attributes';
3807
3808        $kid = $kid->sibling;
3809        return unless $$kid && $kid->type == OP_CONST; # __PACKAGE__
3810
3811        $kid = $kid->sibling;
3812        return unless  $$kid
3813                    && $kid->name eq "srefgen"
3814                    && ($kid->flags & OPf_KIDS)
3815                    && ($kid->first->flags & OPf_KIDS)
3816                    && $kid->first->first->name =~ /^pad[sah]v$/
3817                    && $kid->first->first->targ == $padop->targ;
3818
3819        $kid = $kid->sibling;
3820        my @attr;
3821        while ($$kid) {
3822            last if ($kid->type != OP_CONST);
3823            push @attr, $self->const_sv($kid)->PV;
3824            $kid = $kid->sibling;
3825        }
3826        return unless @attr;
3827        my $thisattr = ":" . join(' ', @attr);
3828        $attr_text //= $thisattr;
3829        # all import calls must have the same list of attributes
3830        return unless $attr_text eq $thisattr;
3831
3832        return unless $kid->name eq 'method_named';
3833	return unless $self->meth_sv($kid)->PV eq 'import';
3834
3835        $kid = $kid->sibling;
3836        return if $$kid;
3837    }
3838
3839    my $res = $decl;
3840    $res .= " $class " if $class ne 'main';
3841    $res .=
3842            (@varnames > 1)
3843            ? "(" . join(', ', @varnames) . ')'
3844            : " $varnames[0]";
3845
3846    return "$res $attr_text";
3847}
3848
3849
3850sub pp_list {
3851    my $self = shift;
3852    my($op, $cx) = @_;
3853
3854    {
3855        # might be my ($s,@a,%h) :Foo(bar);
3856        my $my_attr = maybe_var_attr($self, $op, $cx);
3857        return $my_attr if defined $my_attr;
3858    }
3859
3860    my($expr, @exprs);
3861    my $kid = $op->first->sibling; # skip pushmark
3862    return '' if class($kid) eq 'NULL';
3863    my $lop;
3864    my $local = "either"; # could be local(...), my(...), state(...) or our(...)
3865    my $type;
3866    for ($lop = $kid; !null($lop); $lop = $lop->sibling) {
3867	my $lopname = $lop->name;
3868	my $loppriv = $lop->private;
3869	my $newtype;
3870	if ($lopname =~ /^pad[ash]v$/ && $loppriv & OPpLVAL_INTRO) {
3871	    if ($loppriv & OPpPAD_STATE) { # state()
3872		($local = "", last) if $local !~ /^(?:either|state)$/;
3873		$local = "state";
3874	    } else { # my()
3875		($local = "", last) if $local !~ /^(?:either|my)$/;
3876		$local = "my";
3877	    }
3878	    my $padname = $self->padname_sv($lop->targ);
3879	    if ($padname->FLAGS & PADNAMEf_TYPED) {
3880		$newtype = $padname->SvSTASH->NAME;
3881	    }
3882	} elsif ($lopname eq 'padsv_store') {
3883            # don't interpret as my (list) if it has an implicit assign
3884            $local = "";
3885	} elsif ($lopname =~ /^(?:gv|rv2)([ash])v$/
3886			&& $loppriv & OPpOUR_INTRO
3887		or $lopname eq "null" && class($lop) eq 'UNOP'
3888			&& $lop->first->name eq "gvsv"
3889			&& $lop->first->private & OPpOUR_INTRO) { # our()
3890	    my $newlocal = "local " x !!($loppriv & OPpLVAL_INTRO) . "our";
3891	    ($local = "", last)
3892		if $local ne 'either' && $local ne $newlocal;
3893	    $local = $newlocal;
3894	    my $funny = !$1 || $1 eq 's' ? '$' : $1 eq 'a' ? '@' : '%';
3895	    if (my $t = $self->find_our_type(
3896		    $funny . $self->gv_or_padgv($lop->first)->NAME
3897	       )) {
3898		$newtype = $t;
3899	    }
3900	} elsif ($lopname ne 'undef'
3901	   and    !($loppriv & OPpLVAL_INTRO)
3902	       || !exists $uses_intro{$lopname eq 'null'
3903					? substr B::ppname($lop->targ), 3
3904					: $lopname})
3905	{
3906	    $local = ""; # or not
3907	    last;
3908	} elsif ($lopname ne "undef")
3909	{
3910	    # local()
3911	    ($local = "", last) if $local !~ /^(?:either|local)$/;
3912	    $local = "local";
3913	}
3914	if (defined $type && defined $newtype && $newtype ne $type) {
3915	    $local = '';
3916	    last;
3917	}
3918	$type = $newtype;
3919    }
3920    $local = "" if $local eq "either"; # no point if it's all undefs
3921    $local &&= join ' ', map $self->keyword($_), split / /, $local;
3922    $local .= " $type " if $local && length $type;
3923    return $self->deparse($kid, $cx) if null $kid->sibling and not $local;
3924    for (; !null($kid); $kid = $kid->sibling) {
3925	if ($local) {
3926	    if (class($kid) eq "UNOP" and $kid->first->name eq "gvsv") {
3927		$lop = $kid->first;
3928	    } else {
3929		$lop = $kid;
3930	    }
3931	    $self->{'avoid_local'}{$$lop}++;
3932	    $expr = $self->deparse($kid, 6);
3933	    delete $self->{'avoid_local'}{$$lop};
3934	} else {
3935	    $expr = $self->deparse($kid, 6);
3936	}
3937	push @exprs, $expr;
3938    }
3939    if ($local) {
3940        if (@exprs == 1 && ($local eq 'state' || $local eq 'CORE::state')) {
3941            # 'state @a = ...' is legal, while 'state(@a) = ...' currently isn't
3942            return "$local $exprs[0]";
3943        }
3944	return "$local(" . join(", ", @exprs) . ")";
3945    } else {
3946	return $self->maybe_parens( join(", ", @exprs), $cx, 6);
3947    }
3948}
3949
3950sub is_ifelse_cont {
3951    my $op = shift;
3952    return ($op->name eq "null" and class($op) eq "UNOP"
3953	    and $op->first->name =~ /^(and|cond_expr)$/
3954	    and is_scope($op->first->first->sibling));
3955}
3956
3957sub pp_cond_expr {
3958    my $self = shift;
3959    my($op, $cx) = @_;
3960    my $cond = $op->first;
3961    my $true = $cond->sibling;
3962    my $false = $true->sibling;
3963    my $cuddle = $self->{'cuddle'};
3964    unless ($cx < 1 and (is_scope($true) and $true->name ne "null") and
3965	    (is_scope($false) || is_ifelse_cont($false))
3966	    and $self->{'expand'} < 7) {
3967	$cond = $self->deparse($cond, 8);
3968	$true = $self->deparse($true, 6);
3969	$false = $self->deparse($false, 8);
3970	return $self->maybe_parens("$cond ? $true : $false", $cx, 8);
3971    }
3972
3973    $cond = $self->deparse($cond, 1);
3974    $true = $self->deparse($true, 0);
3975    my $head = $self->keyword("if") . " ($cond) {\n\t$true\n\b}";
3976    my @elsifs;
3977    my $elsif;
3978    while (!null($false) and is_ifelse_cont($false)) {
3979	my $newop = $false->first;
3980	my $newcond = $newop->first;
3981	my $newtrue = $newcond->sibling;
3982	$false = $newtrue->sibling; # last in chain is OP_AND => no else
3983	if ($newcond->name eq "lineseq")
3984	{
3985	    # lineseq to ensure correct line numbers in elsif()
3986	    # Bug #37302 fixed by change #33710.
3987	    $newcond = $newcond->first->sibling;
3988	}
3989	$newcond = $self->deparse($newcond, 1);
3990	$newtrue = $self->deparse($newtrue, 0);
3991	$elsif ||= $self->keyword("elsif");
3992	push @elsifs, "$elsif ($newcond) {\n\t$newtrue\n\b}";
3993    }
3994    if (!null($false)) {
3995	$false = $cuddle . $self->keyword("else") . " {\n\t" .
3996	  $self->deparse($false, 0) . "\n\b}\cK";
3997    } else {
3998	$false = "\cK";
3999    }
4000    return $head . join($cuddle, "", @elsifs) . $false;
4001}
4002
4003sub pp_once {
4004    my ($self, $op, $cx) = @_;
4005    my $cond = $op->first;
4006    my $true = $cond->sibling;
4007
4008    my $ret = $self->deparse($true, $cx);
4009    $ret =~ s/^(\(?)\$/$1 . $self->keyword("state") . ' $'/e;
4010    $ret;
4011}
4012
4013sub loop_common {
4014    my $self = shift;
4015    my($op, $cx, $init) = @_;
4016    my $enter = $op->first;
4017    my $kid = $enter->sibling;
4018    local(@$self{qw'curstash warnings hints hinthash'})
4019		= @$self{qw'curstash warnings hints hinthash'};
4020    my $head = "";
4021    my $bare = 0;
4022    my $body;
4023    my $cond = undef;
4024    my $name;
4025    if ($kid->name eq "lineseq") { # bare or infinite loop
4026	if ($kid->last->name eq "unstack") { # infinite
4027	    $head = "while (1) "; # Can't use for(;;) if there's a continue
4028	    $cond = "";
4029	} else {
4030	    $bare = 1;
4031	}
4032	$body = $kid;
4033    } elsif ($enter->name eq "enteriter") { # foreach
4034	my $ary = $enter->first->sibling; # first was pushmark
4035	my $var = $ary->sibling;
4036	if ($ary->name eq 'null' and $enter->private & OPpITER_REVERSED) {
4037	    # "reverse" was optimised away
4038	    $ary = listop($self, $ary->first->sibling, 1, 'reverse');
4039	} elsif ($enter->flags & OPf_STACKED
4040	    and not null $ary->first->sibling->sibling)
4041	{
4042	    $ary = $self->deparse($ary->first->sibling, 9) . " .. " .
4043	      $self->deparse($ary->first->sibling->sibling, 9);
4044	} else {
4045	    $ary = $self->deparse($ary, 1);
4046	}
4047
4048        if ($enter->flags & OPf_PARENS) {
4049            # for my ($x, $y, ...) ...
4050            # for my ($foo, $bar) () stores the count (less 1) in the targ of
4051            # the ITER op. For the degenerate case of 1 var ($x), the
4052            # TARG is zero, so it works anyway
4053            my $iter_targ = $kid->first->first->targ;
4054            my @vars;
4055            my $targ = $enter->targ;
4056            while ($iter_targ-- >= 0) {
4057                push @vars, $self->padname_sv($targ)->PVX;
4058                ++$targ;
4059            }
4060            $var = 'my (' . join(', ', @vars) . ')';
4061        } elsif (null $var) {
4062            $var = $self->pp_padsv($enter, 1, 1);
4063	} elsif ($var->name eq "rv2gv") {
4064	    $var = $self->pp_rv2sv($var, 1);
4065	    if ($enter->private & OPpOUR_INTRO) {
4066		# our declarations don't have package names
4067		$var =~ s/^(.).*::/$1/;
4068		$var = "our $var";
4069	    }
4070	} elsif ($var->name eq "gv") {
4071	    $var = "\$" . $self->deparse($var, 1);
4072	} else {
4073	    $var = $self->deparse($var, 1);
4074	}
4075	$body = $kid->first->first->sibling; # skip OP_AND and OP_ITER
4076	if (!is_state $body->first and $body->first->name !~ /^(?:stub|leave|scope)$/) {
4077	    confess unless $var eq '$_';
4078	    $body = $body->first;
4079	    return $self->deparse($body, 2) . " "
4080		 . $self->keyword("foreach") . " ($ary)";
4081	}
4082	$head = "foreach $var ($ary) ";
4083    } elsif ($kid->name eq "null") { # while/until
4084	$kid = $kid->first;
4085	$name = {"and" => "while", "or" => "until"}->{$kid->name};
4086	$cond = $kid->first;
4087	$body = $kid->first->sibling;
4088    } elsif ($kid->name eq "stub") { # bare and empty
4089	return "{;}"; # {} could be a hashref
4090    }
4091    # If there isn't a continue block, then the next pointer for the loop
4092    # will point to the unstack, which is kid's last child, except
4093    # in a bare loop, when it will point to the leaveloop. When neither of
4094    # these conditions hold, then the second-to-last child is the continue
4095    # block (or the last in a bare loop).
4096    my $cont_start = $enter->nextop;
4097    my $cont;
4098    my $precond;
4099    my $postcond;
4100    if ($$cont_start != $$op && ${$cont_start} != ${$body->last}) {
4101	if ($bare) {
4102	    $cont = $body->last;
4103	} else {
4104	    $cont = $body->first;
4105	    while (!null($cont->sibling->sibling)) {
4106		$cont = $cont->sibling;
4107	    }
4108	}
4109	my $state = $body->first;
4110	my $cuddle = $self->{'cuddle'};
4111	my @states;
4112	for (; $$state != $$cont; $state = $state->sibling) {
4113	    push @states, $state;
4114	}
4115	$body = $self->lineseq(undef, 0, @states);
4116	if (defined $cond and not is_scope $cont and $self->{'expand'} < 3) {
4117	    $precond = "for ($init; ";
4118	    $postcond = "; " . $self->deparse($cont, 1) .") ";
4119	    $cont = "\cK";
4120	} else {
4121	    $cont = $cuddle . "continue {\n\t" .
4122	      $self->deparse($cont, 0) . "\n\b}\cK";
4123	}
4124    } else {
4125	return "" if !defined $body;
4126	if (length $init) {
4127	    $precond = "for ($init; ";
4128	    $postcond = ";) ";
4129	}
4130	$cont = "\cK";
4131	$body = $self->deparse($body, 0);
4132    }
4133    if ($precond) { # for(;;)
4134	$cond &&= $name eq 'until'
4135		    ? listop($self, undef, 1, "not", $cond->first)
4136		    : $self->deparse($cond, 1);
4137	$head = "$precond$cond$postcond";
4138    }
4139    if ($name && !$head) {
4140	ref $cond and $cond = $self->deparse($cond, 1);
4141	$head = "$name ($cond) ";
4142    }
4143    $head =~ s/^(for(?:each)?|while|until)/$self->keyword($1)/e;
4144    $body =~ s/;?$/;\n/;
4145
4146    return $head . "{\n\t" . $body . "\b}" . $cont;
4147}
4148
4149sub pp_leaveloop { shift->loop_common(@_, "") }
4150
4151sub for_loop {
4152    my $self = shift;
4153    my($op, $cx) = @_;
4154    my $init = $self->deparse($op, 1);
4155    my $s = $op->sibling;
4156    my $ll = $s->name eq "unstack" ? $s->sibling : $s->first->sibling;
4157    return $self->loop_common($ll, $cx, $init);
4158}
4159
4160sub pp_leavetry {
4161    my $self = shift;
4162    return "eval {\n\t" . $self->pp_leave(@_) . "\n\b}";
4163}
4164
4165sub pp_leavetrycatch_with_finally {
4166    my $self = shift;
4167    my ($op, $finallyop) = @_;
4168
4169    # Expect that the first three kids should be (entertrycatch, poptry, catch)
4170    my $entertrycatch = $op->first;
4171    $entertrycatch->name eq "entertrycatch" or die "Expected entertrycatch as first child of leavetrycatch";
4172
4173    my $tryblock = $entertrycatch->sibling;
4174    $tryblock->name eq "poptry" or die "Expected poptry as second child of leavetrycatch";
4175
4176    my $catch = $tryblock->sibling;
4177    $catch->name eq "catch" or die "Expected catch as third child of leavetrycatch";
4178
4179    my $catchblock = $catch->first->sibling;
4180    my $name = $catchblock->name;
4181    unless ($name eq "scope" || $name eq "leave") {
4182      die "Expected scope or leave as second child of catch, got $name instead";
4183    }
4184
4185    my $trycode = scopeop(0, $self, $tryblock);
4186    my $catchvar = $self->padname($catch->targ);
4187    my $catchcode = $name eq 'scope' ? scopeop(0, $self, $catchblock)
4188                                     : scopeop(1, $self, $catchblock);
4189
4190    my $finallycode = "";
4191    if($finallyop) {
4192        my $body = $self->deparse($finallyop->first->first);
4193        $finallycode = "\nfinally {\n\t$body\n\b}";
4194    }
4195
4196    return "try {\n\t$trycode\n\b}\n" .
4197           "catch($catchvar) {\n\t$catchcode\n\b}$finallycode\cK";
4198}
4199
4200sub pp_leavetrycatch {
4201    my $self = shift;
4202    my ($op, @args) = @_;
4203    return $self->pp_leavetrycatch_with_finally($op, undef, @args);
4204}
4205
4206sub _op_is_or_was {
4207  my ($op, $expect_type) = @_;
4208  my $type = $op->type;
4209  return($type == $expect_type
4210         || ($type == OP_NULL && $op->targ == $expect_type));
4211}
4212
4213sub pp_null {
4214    my($self, $op, $cx) = @_;
4215
4216    # might be 'my $s :Foo(bar);'
4217    if ($op->targ == OP_LIST) {
4218        my $my_attr = maybe_var_attr($self, $op, $cx);
4219        return $my_attr if defined $my_attr;
4220    }
4221
4222    if (class($op) eq "OP") {
4223	# old value is lost
4224	return $self->{'ex_const'} if $op->targ == OP_CONST;
4225    } elsif (class ($op) eq "COP") {
4226	    return &pp_nextstate;
4227    } elsif ($op->first->name eq 'pushmark'
4228             or $op->first->name eq 'null'
4229                && $op->first->targ == OP_PUSHMARK
4230                && _op_is_or_was($op, OP_LIST)) {
4231	return $self->pp_list($op, $cx);
4232    } elsif ($op->first->name eq "enter") {
4233	return $self->pp_leave($op, $cx);
4234    } elsif ($op->first->name eq "leave") {
4235	return $self->pp_leave($op->first, $cx);
4236    } elsif ($op->first->name eq "scope") {
4237	return $self->pp_scope($op->first, $cx);
4238    } elsif ($op->targ == OP_STRINGIFY) {
4239	return $self->dquote($op, $cx);
4240    } elsif ($op->targ == OP_GLOB) {
4241	return $self->pp_glob(
4242	         $op->first    # entersub
4243	            ->first    # ex-list
4244	            ->first    # pushmark
4245	            ->sibling, # glob
4246	         $cx
4247	       );
4248    } elsif (!null($op->first->sibling) and
4249	     $op->first->sibling->name eq "readline" and
4250	     $op->first->sibling->flags & OPf_STACKED) {
4251	return $self->maybe_parens($self->deparse($op->first, 7) . " = "
4252				   . $self->deparse($op->first->sibling, 7),
4253				   $cx, 7);
4254    } elsif (!null($op->first->sibling) and
4255	     $op->first->sibling->name =~ /^transr?\z/ and
4256	     $op->first->sibling->flags & OPf_STACKED) {
4257	return $self->maybe_parens($self->deparse($op->first, 20) . " =~ "
4258				   . $self->deparse($op->first->sibling, 20),
4259				   $cx, 20);
4260    } elsif ($op->flags & OPf_SPECIAL && $cx < 1 && !$op->targ) {
4261	return ($self->lex_in_scope("&do") ? "CORE::do" : "do")
4262	     . " {\n\t". $self->deparse($op->first, $cx) ."\n\b};";
4263    } elsif (!null($op->first->sibling) and
4264	     $op->first->sibling->name eq "null" and
4265	     class($op->first->sibling) eq "UNOP" and
4266	     $op->first->sibling->first->flags & OPf_STACKED and
4267	     $op->first->sibling->first->name eq "rcatline") {
4268	return $self->maybe_parens($self->deparse($op->first, 18) . " .= "
4269				   . $self->deparse($op->first->sibling, 18),
4270				   $cx, 18);
4271    } else {
4272	return $self->deparse($op->first, $cx);
4273    }
4274}
4275
4276sub padname {
4277    my $self = shift;
4278    my $targ = shift;
4279    return $self->padname_sv($targ)->PVX;
4280}
4281
4282sub padany {
4283    my $self = shift;
4284    my $op = shift;
4285    return substr($self->padname($op->targ), 1); # skip $/@/%
4286}
4287
4288sub pp_padsv {
4289    my $self = shift;
4290    my($op, $cx, $forbid_parens) = @_;
4291    my $targ = $op->targ;
4292    return $self->maybe_my($op, $cx, $self->padname($targ),
4293			   $self->padname_sv($targ),
4294			   $forbid_parens);
4295}
4296
4297sub pp_padav { pp_padsv(@_) }
4298
4299# prepend 'keys' where its been optimised away, with suitable handling
4300# of CORE:: and parens
4301
4302sub add_keys_keyword {
4303    my ($self, $str, $cx) = @_;
4304    $str = $self->maybe_parens($str, $cx, 16);
4305    # 'keys %h' versus 'keys(%h)'
4306    $str = " $str" unless $str =~ /^\(/;
4307    return $self->keyword("keys") . $str;
4308}
4309
4310sub pp_padhv {
4311    my ($self, $op, $cx) = @_;
4312    my $str =  pp_padsv(@_);
4313    # with OPpPADHV_ISKEYS the keys op is optimised away, except
4314    # in scalar context the old op is kept (but not executed) so its targ
4315    # can be used.
4316    if (     ($op->private & OPpPADHV_ISKEYS)
4317        && !(($op->flags & OPf_WANT) == OPf_WANT_SCALAR))
4318    {
4319        $str = $self->add_keys_keyword($str, $cx);
4320    }
4321    $str;
4322}
4323
4324sub gv_or_padgv {
4325    my $self = shift;
4326    my $op = shift;
4327    if (class($op) eq "PADOP") {
4328	return $self->padval($op->padix);
4329    } else { # class($op) eq "SVOP"
4330	return $op->gv;
4331    }
4332}
4333
4334sub pp_gvsv {
4335    my $self = shift;
4336    my($op, $cx) = @_;
4337    my $gv = $self->gv_or_padgv($op);
4338    return $self->maybe_local($op, $cx, $self->stash_variable("\$",
4339				 $self->gv_name($gv), $cx));
4340}
4341
4342sub pp_gv {
4343    my $self = shift;
4344    my($op, $cx) = @_;
4345    my $gv = $self->gv_or_padgv($op);
4346    return $self->maybe_qualify("", $self->gv_name($gv));
4347}
4348
4349sub pp_aelemfastlex_store {
4350    my $self = shift;
4351    my($op, $cx) = @_;
4352    my $name = $self->padname($op->targ);
4353    $name =~ s/^@/\$/;
4354    my $i = $op->private;
4355    $i -= 256 if $i > 127;
4356    my $val = $self->deparse($op->first, 7);
4357    return $self->maybe_parens("${name}[$i] = $val", $cx, 7);
4358}
4359
4360sub pp_aelemfast_lex {
4361    my $self = shift;
4362    my($op, $cx) = @_;
4363    my $name = $self->padname($op->targ);
4364    $name =~ s/^@/\$/;
4365    my $i = $op->private;
4366    $i -= 256 if $i > 127;
4367    return $name . "[$i]";
4368}
4369
4370sub pp_aelemfast {
4371    my $self = shift;
4372    my($op, $cx) = @_;
4373    # optimised PADAV, pre 5.15
4374    return $self->pp_aelemfast_lex(@_) if ($op->flags & OPf_SPECIAL);
4375
4376    my $gv = $self->gv_or_padgv($op);
4377    my($name,$quoted) = $self->stash_variable_name('@',$gv);
4378    $name = $quoted ? "$name->" : '$' . $name;
4379    my $i = $op->private;
4380    $i -= 256 if $i > 127;
4381    return $name . "[$i]";
4382}
4383
4384sub rv2x {
4385    my $self = shift;
4386    my($op, $cx, $type) = @_;
4387
4388    if (class($op) eq 'NULL' || !$op->can("first")) {
4389	carp("Unexpected op in pp_rv2x");
4390	return 'XXX';
4391    }
4392    my $kid = $op->first;
4393    if ($kid->name eq "gv") {
4394	return $self->stash_variable($type,
4395		    $self->gv_name($self->gv_or_padgv($kid)), $cx);
4396    } elsif (is_scalar $kid) {
4397	my $str = $self->deparse($kid, 0);
4398	if ($str =~ /^\$([^\w\d])\z/) {
4399	    # "$$+" isn't a legal way to write the scalar dereference
4400	    # of $+, since the lexer can't tell you aren't trying to
4401	    # do something like "$$ + 1" to get one more than your
4402	    # PID. Either "${$+}" or "$${+}" are workable
4403	    # disambiguations, but if the programmer did the former,
4404	    # they'd be in the "else" clause below rather than here.
4405	    # It's not clear if this should somehow be unified with
4406	    # the code in dq and re_dq that also adds lexer
4407	    # disambiguation braces.
4408	    $str = '$' . "{$1}"; #'
4409	}
4410	return $type . $str;
4411    } else {
4412	return $type . "{" . $self->deparse($kid, 0) . "}";
4413    }
4414}
4415
4416sub pp_rv2sv { maybe_local(@_, rv2x(@_, "\$")) }
4417sub pp_rv2gv { maybe_local(@_, rv2x(@_, "*")) }
4418
4419sub pp_rv2hv {
4420    my ($self, $op, $cx) = @_;
4421    my $str = rv2x(@_, "%");
4422    if ($op->private & OPpRV2HV_ISKEYS) {
4423        $str = $self->add_keys_keyword($str, $cx);
4424    }
4425    return maybe_local(@_, $str);
4426}
4427
4428# skip rv2av
4429sub pp_av2arylen {
4430    my $self = shift;
4431    my($op, $cx) = @_;
4432    my $kid = $op->first;
4433    if ($kid->name eq "padav") {
4434	return $self->maybe_local($op, $cx, '$#' . $self->padany($kid));
4435    } else {
4436        my $kkid;
4437        if (   $kid->name eq "rv2av"
4438           && ($kkid = $kid->first)
4439           && $kkid->name !~ /^(scope|leave|gv)$/)
4440        {
4441            # handle (expr)->$#* postfix form
4442            my $expr;
4443            $expr = $self->deparse($kkid, 24); # 24 is '->'
4444            $expr = "$expr->\$#*";
4445            # XXX maybe_local is probably wrong here: local($#-expression)
4446            # doesn't "do" local (the is no INTRO flag set)
4447            return $self->maybe_local($op, $cx, $expr);
4448        }
4449        else {
4450            # handle $#{expr} form
4451            # XXX see maybe_local comment above
4452            return $self->maybe_local($op, $cx, $self->rv2x($kid, $cx, '$#'));
4453        }
4454    }
4455}
4456
4457# skip down to the old, ex-rv2cv
4458sub pp_rv2cv {
4459    my ($self, $op, $cx) = @_;
4460    if (!null($op->first) && $op->first->name eq 'null' &&
4461	$op->first->targ == OP_LIST)
4462    {
4463	return $self->rv2x($op->first->first->sibling, $cx, "&")
4464    }
4465    else {
4466	return $self->rv2x($op, $cx, "")
4467    }
4468}
4469
4470sub list_const {
4471    my $self = shift;
4472    my($cx, @list) = @_;
4473    my @a = map $self->const($_, 6), @list;
4474    if (@a == 0) {
4475	return "()";
4476    } elsif (@a == 1) {
4477	return $a[0];
4478    } elsif ( @a > 2 and !grep(!/^-?\d+$/, @a)) {
4479	# collapse (-1,0,1,2) into (-1..2)
4480	my ($s, $e) = @a[0,-1];
4481	my $i = $s;
4482	return $self->maybe_parens("$s..$e", $cx, 9)
4483	  unless grep $i++ != $_, @a;
4484    }
4485    return $self->maybe_parens(join(", ", @a), $cx, 6);
4486}
4487
4488sub pp_rv2av {
4489    my $self = shift;
4490    my($op, $cx) = @_;
4491    my $kid = $op->first;
4492    if ($kid->name eq "const") { # constant list
4493	my $av = $self->const_sv($kid);
4494	return $self->list_const($cx, $av->ARRAY);
4495    } else {
4496	return $self->maybe_local($op, $cx, $self->rv2x($op, $cx, "\@"));
4497    }
4498 }
4499
4500sub is_subscriptable {
4501    my $op = shift;
4502    if ($op->name =~ /^([ahg]elem|multideref$)/) {
4503	return 1;
4504    } elsif ($op->name eq "entersub") {
4505	my $kid = $op->first;
4506	return 0 unless null $kid->sibling;
4507	$kid = $kid->first;
4508	$kid = $kid->sibling until null $kid->sibling;
4509	return 0 if is_scope($kid);
4510	$kid = $kid->first;
4511	return 0 if $kid->name eq "gv" || $kid->name eq "padcv";
4512	return 0 if is_scalar($kid);
4513	return is_subscriptable($kid);
4514    } else {
4515	return 0;
4516    }
4517}
4518
4519sub elem_or_slice_array_name
4520{
4521    my $self = shift;
4522    my ($array, $left, $padname, $allow_arrow) = @_;
4523
4524    if ($array->name eq $padname) {
4525	return $self->padany($array);
4526    } elsif (is_scope($array)) { # ${expr}[0]
4527	return "{" . $self->deparse($array, 0) . "}";
4528    } elsif ($array->name eq "gv") {
4529	($array, my $quoted) =
4530	    $self->stash_variable_name(
4531		$left eq '[' ? '@' : '%', $self->gv_or_padgv($array)
4532	    );
4533	if (!$allow_arrow && $quoted) {
4534	    # This cannot happen.
4535	    die "Invalid variable name $array for slice";
4536	}
4537	return $quoted ? "$array->" : $array;
4538    } elsif (!$allow_arrow || is_scalar $array) { # $x[0], $$x[0], ...
4539	return $self->deparse($array, 24);
4540    } else {
4541	return undef;
4542    }
4543}
4544
4545sub elem_or_slice_single_index
4546{
4547    my $self = shift;
4548    my ($idx) = @_;
4549
4550    $idx = $self->deparse($idx, 1);
4551
4552    # Outer parens in an array index will confuse perl
4553    # if we're interpolating in a regular expression, i.e.
4554    # /$x$foo[(-1)]/ is *not* the same as /$x$foo[-1]/
4555    #
4556    # If $self->{parens}, then an initial '(' will
4557    # definitely be paired with a final ')'. If
4558    # !$self->{parens}, the misleading parens won't
4559    # have been added in the first place.
4560    #
4561    # [You might think that we could get "(...)...(...)"
4562    # where the initial and final parens do not match
4563    # each other. But we can't, because the above would
4564    # only happen if there's an infix binop between the
4565    # two pairs of parens, and *that* means that the whole
4566    # expression would be parenthesized as well.]
4567    #
4568    $idx =~ s/^\((.*)\)$/$1/ if $self->{'parens'};
4569
4570    # Hash-element braces will autoquote a bareword inside themselves.
4571    # We need to make sure that C<$hash{warn()}> doesn't come out as
4572    # C<$hash{warn}>, which has a quite different meaning. Currently
4573    # B::Deparse will always quote strings, even if the string was a
4574    # bareword in the original (i.e. the OPpCONST_BARE flag is ignored
4575    # for constant strings.) So we can cheat slightly here - if we see
4576    # a bareword, we know that it is supposed to be a function call.
4577    #
4578    $idx =~ s/^([A-Za-z_]\w*)$/$1()/;
4579
4580    return $idx;
4581}
4582
4583sub elem {
4584    my $self = shift;
4585    my ($op, $cx, $left, $right, $padname) = @_;
4586    my($array, $idx) = ($op->first, $op->first->sibling);
4587
4588    $idx = $self->elem_or_slice_single_index($idx);
4589
4590    unless ($array->name eq $padname) { # Maybe this has been fixed
4591	$array = $array->first; # skip rv2av (or ex-rv2av in _53+)
4592    }
4593    if (my $array_name=$self->elem_or_slice_array_name
4594	    ($array, $left, $padname, 1)) {
4595	return ($array_name =~ /->\z/
4596		    ? $array_name
4597		    : $array_name eq '#' ? '${#}' : "\$" . $array_name)
4598	      . $left . $idx . $right;
4599    } else {
4600	# $x[20][3]{hi} or expr->[20]
4601	my $arrow = is_subscriptable($array) ? "" : "->";
4602	return $self->deparse($array, 24) . $arrow . $left . $idx . $right;
4603    }
4604
4605}
4606
4607# a simplified version of elem_or_slice_array_name()
4608# for the use of pp_multideref
4609
4610sub multideref_var_name {
4611    my $self = shift;
4612    my ($gv, $is_hash) = @_;
4613
4614    my ($name, $quoted) =
4615        $self->stash_variable_name( $is_hash  ? '%' : '@', $gv);
4616    return $quoted ? "$name->"
4617                   : $name eq '#'
4618                        ? '${#}'       # avoid ${#}[1] => $#[1]
4619                        : '$' . $name;
4620}
4621
4622
4623# deparse an OP_MULTICONCAT. If $in_dq is 1, we're within
4624# a double-quoted string, so for example.
4625#     "abc\Qdef$x\Ebar"
4626# might get compiled as
4627#    multiconcat("abc", metaquote(multiconcat("def", $x)), "bar")
4628# and the inner multiconcat should be deparsed as C<def$x> rather than
4629# the normal C<def . $x>
4630# Ditto if  $in_dq is 2, handle qr/...\Qdef$x\E.../.
4631
4632sub do_multiconcat {
4633    my $self = shift;
4634    my($op, $cx, $in_dq) = @_;
4635
4636    my $kid;
4637    my @kids;
4638    my $assign;
4639    my $append;
4640    my $lhs = "";
4641
4642    for ($kid = $op->first; !null $kid; $kid = $kid->sibling) {
4643        # skip the consts and/or padsv we've optimised away
4644        push @kids, $kid
4645            unless $kid->type == OP_NULL
4646              && (   $kid->targ == OP_PADSV
4647                  || $kid->targ == OP_CONST
4648                  || $kid->targ == OP_PUSHMARK);
4649    }
4650
4651    $append = ($op->private & OPpMULTICONCAT_APPEND);
4652
4653    if ($op->private & OPpTARGET_MY) {
4654        # '$lex  = ...' or '$lex .= ....' or 'my $lex = '
4655        $lhs = $self->padname($op->targ);
4656        $lhs = "my $lhs" if ($op->private & OPpLVAL_INTRO);
4657        $assign = 1;
4658    }
4659    elsif ($op->flags & OPf_STACKED) {
4660        # 'expr  = ...' or 'expr .= ....'
4661        my $expr = $append ? shift(@kids) : pop(@kids);
4662        $lhs = $self->deparse($expr, 7);
4663        $assign = 1;
4664    }
4665
4666    if ($assign) {
4667        $lhs .=  $append ? ' .= ' : ' = ';
4668    }
4669
4670    my ($nargs, $const_str, @const_lens) = $op->aux_list($self->{curcv});
4671
4672    my @consts;
4673    my $i = 0;
4674    for (@const_lens) {
4675        if ($_ == -1) {
4676            push @consts, undef;
4677        }
4678        else {
4679            push @consts, substr($const_str, $i, $_);
4680        my @args;
4681            $i += $_;
4682        }
4683    }
4684
4685    my $rhs = "";
4686
4687    if (   $in_dq
4688        || (($op->private & OPpMULTICONCAT_STRINGIFY) && !$self->{'unquote'}))
4689    {
4690        # "foo=$foo bar=$bar "
4691        my $not_first;
4692        while (@consts) {
4693            if ($not_first) {
4694                my $s = $self->dq(shift(@kids), 18);
4695                # don't deparse "a${$}b" as "a$$b"
4696                $s = '${$}' if $s eq '$$';
4697                $rhs = dq_disambiguate($rhs, $s);
4698            }
4699            $not_first = 1;
4700            my $c = shift @consts;
4701            if (defined $c) {
4702                if ($in_dq == 2) {
4703                    # in pattern: don't convert newline to '\n' etc etc
4704                    my $s = re_uninterp(escape_re(re_unback($c)));
4705                    $rhs = re_dq_disambiguate($rhs, $s)
4706                }
4707                else {
4708                    my $s = uninterp(escape_str(unback($c)));
4709                    $rhs = dq_disambiguate($rhs, $s)
4710                }
4711            }
4712        }
4713        return $rhs if $in_dq;
4714        $rhs = single_delim("qq", '"', $rhs, $self);
4715    }
4716    elsif ($op->private & OPpMULTICONCAT_FAKE) {
4717        # sprintf("foo=%s bar=%s ", $foo, $bar)
4718
4719        my @all;
4720        @consts = map { $_ //= ''; s/%/%%/g; $_ } @consts;
4721        my $fmt = join '%s', @consts;
4722        push @all, $self->quoted_const_str($fmt);
4723
4724        # the following is a stripped down copy of sub listop {}
4725        my $parens = $assign || ($cx >= 5) || $self->{'parens'};
4726        my $fullname = $self->keyword('sprintf');
4727        push @all, map $self->deparse($_, 6), @kids;
4728
4729        $rhs = $parens
4730                ? "$fullname(" . join(", ", @all) . ")"
4731                : "$fullname " . join(", ", @all);
4732    }
4733    else {
4734        # "foo=" . $foo . " bar=" . $bar
4735        my @all;
4736        my $not_first;
4737        while (@consts) {
4738            push @all, $self->deparse(shift(@kids), 18) if $not_first;
4739            $not_first = 1;
4740            my $c = shift @consts;
4741            if (defined $c) {
4742                push @all, $self->quoted_const_str($c);
4743            }
4744        }
4745        $rhs .= join ' . ', @all;
4746    }
4747
4748    my $text = $lhs . $rhs;
4749
4750    $text = "($text)" if     ($cx >= (($assign) ? 7 : 18+1))
4751                          || $self->{'parens'};
4752
4753    return $text;
4754}
4755
4756
4757sub pp_multiconcat {
4758    my $self = shift;
4759    $self->do_multiconcat(@_, 0);
4760}
4761
4762
4763sub pp_multideref {
4764    my $self = shift;
4765    my($op, $cx) = @_;
4766    my $text = "";
4767
4768    if ($op->private & OPpMULTIDEREF_EXISTS) {
4769        $text = $self->keyword("exists"). " ";
4770    }
4771    elsif ($op->private & OPpMULTIDEREF_DELETE) {
4772        $text = $self->keyword("delete"). " ";
4773    }
4774    elsif ($op->private & OPpLVAL_INTRO) {
4775        $text = $self->keyword("local"). " ";
4776    }
4777
4778    if ($op->first && ($op->first->flags & OPf_KIDS)) {
4779        # arbitrary initial expression, e.g. f(1,2,3)->[...]
4780        my $expr = $self->deparse($op->first, 24);
4781        # stop "exists (expr)->{...}" being interpreted as
4782        #"(exists (expr))->{...}"
4783        $expr = "+$expr" if $expr =~ /^\(/;
4784        $text .=  $expr;
4785    }
4786
4787    my @items = $op->aux_list($self->{curcv});
4788    my $actions = shift @items;
4789
4790    my $is_hash;
4791    my $derefs = 0;
4792
4793    while (1) {
4794        if (($actions & MDEREF_ACTION_MASK) == MDEREF_reload) {
4795            $actions = shift @items;
4796            next;
4797        }
4798
4799        $is_hash = (
4800           ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_pop_rv2hv_helem
4801        || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_gvsv_vivify_rv2hv_helem
4802        || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_padsv_vivify_rv2hv_helem
4803        || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_vivify_rv2hv_helem
4804        || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_padhv_helem
4805        || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_gvhv_helem
4806        );
4807
4808        if (   ($actions & MDEREF_ACTION_MASK) == MDEREF_AV_padav_aelem
4809            || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_padhv_helem)
4810        {
4811            $derefs = 1;
4812            $text .= '$' . substr($self->padname(shift @items), 1);
4813        }
4814        elsif (   ($actions & MDEREF_ACTION_MASK) == MDEREF_AV_gvav_aelem
4815               || ($actions & MDEREF_ACTION_MASK) == MDEREF_HV_gvhv_helem)
4816        {
4817            $derefs = 1;
4818            $text .= $self->multideref_var_name(shift @items, $is_hash);
4819        }
4820        else {
4821            if (   ($actions & MDEREF_ACTION_MASK) ==
4822                                        MDEREF_AV_padsv_vivify_rv2av_aelem
4823                || ($actions & MDEREF_ACTION_MASK) ==
4824                                        MDEREF_HV_padsv_vivify_rv2hv_helem)
4825            {
4826                $text .= $self->padname(shift @items);
4827            }
4828            elsif (   ($actions & MDEREF_ACTION_MASK) ==
4829                                           MDEREF_AV_gvsv_vivify_rv2av_aelem
4830                   || ($actions & MDEREF_ACTION_MASK) ==
4831                                           MDEREF_HV_gvsv_vivify_rv2hv_helem)
4832            {
4833                $text .= $self->multideref_var_name(shift @items, $is_hash);
4834            }
4835            elsif (   ($actions & MDEREF_ACTION_MASK) ==
4836                                           MDEREF_AV_pop_rv2av_aelem
4837                   || ($actions & MDEREF_ACTION_MASK) ==
4838                                           MDEREF_HV_pop_rv2hv_helem)
4839            {
4840                if (   ($op->flags & OPf_KIDS)
4841                    && (   _op_is_or_was($op->first, OP_RV2AV)
4842                        || _op_is_or_was($op->first, OP_RV2HV))
4843                    && ($op->first->flags & OPf_KIDS)
4844                    && (   _op_is_or_was($op->first->first, OP_AELEM)
4845                        || _op_is_or_was($op->first->first, OP_HELEM))
4846                    )
4847                {
4848                    $derefs++;
4849                }
4850            }
4851
4852            $text .= '->' if !$derefs++;
4853        }
4854
4855
4856        if (($actions & MDEREF_INDEX_MASK) == MDEREF_INDEX_none) {
4857            last;
4858        }
4859
4860        $text .= $is_hash ? '{' : '[';
4861
4862        if (($actions & MDEREF_INDEX_MASK) == MDEREF_INDEX_const) {
4863            my $key = shift @items;
4864            if ($is_hash) {
4865                $text .= $self->const($key, $cx);
4866            }
4867            else {
4868                $text .= $key;
4869            }
4870        }
4871        elsif (($actions & MDEREF_INDEX_MASK) == MDEREF_INDEX_padsv) {
4872            $text .= $self->padname(shift @items);
4873        }
4874        elsif (($actions & MDEREF_INDEX_MASK) == MDEREF_INDEX_gvsv) {
4875            $text .= '$' .  ($self->stash_variable_name('$', shift @items))[0];
4876        }
4877
4878        $text .= $is_hash ? '}' : ']';
4879
4880        if ($actions & MDEREF_FLAG_last) {
4881            last;
4882        }
4883        $actions >>= MDEREF_SHIFT;
4884    }
4885
4886    return $text;
4887}
4888
4889
4890sub pp_aelem { maybe_local(@_, elem(@_, "[", "]", "padav")) }
4891sub pp_helem { maybe_local(@_, elem(@_, "{", "}", "padhv")) }
4892
4893sub pp_gelem {
4894    my $self = shift;
4895    my($op, $cx) = @_;
4896    my($glob, $part) = ($op->first, $op->last);
4897    $glob = $glob->first; # skip rv2gv
4898    $glob = $glob->first if $glob->name eq "rv2gv"; # this one's a bug
4899    my $scope = is_scope($glob);
4900    $glob = $self->deparse($glob, 0);
4901    $part = $self->deparse($part, 1);
4902    $glob =~ s/::\z// unless $scope;
4903    return "*" . ($scope ? "{$glob}" : $glob) . "{$part}";
4904}
4905
4906sub slice {
4907    my $self = shift;
4908    my ($op, $cx, $left, $right, $regname, $padname) = @_;
4909    my $last;
4910    my(@elems, $kid, $array, $list);
4911    if (class($op) eq "LISTOP") {
4912	$last = $op->last;
4913    } else { # ex-hslice inside delete()
4914	for ($kid = $op->first; !null $kid->sibling; $kid = $kid->sibling) {}
4915	$last = $kid;
4916    }
4917    $array = $last;
4918    $array = $array->first
4919	if $array->name eq $regname or $array->name eq "null";
4920    $array = $self->elem_or_slice_array_name($array,$left,$padname,0);
4921    $kid = $op->first->sibling; # skip pushmark
4922    if ($kid->name eq "list") {
4923	$kid = $kid->first->sibling; # skip list, pushmark
4924	for (; !null $kid; $kid = $kid->sibling) {
4925	    push @elems, $self->deparse($kid, 6);
4926	}
4927	$list = join(", ", @elems);
4928    } else {
4929	$list = $self->elem_or_slice_single_index($kid);
4930    }
4931    my $lead = (   _op_is_or_was($op, OP_KVHSLICE)
4932                || _op_is_or_was($op, OP_KVASLICE))
4933               ? '%' : '@';
4934    return $lead . $array . $left . $list . $right;
4935}
4936
4937sub pp_aslice   { maybe_local(@_, slice(@_, "[", "]", "rv2av", "padav")) }
4938sub pp_kvaslice {                 slice(@_, "[", "]", "rv2av", "padav")  }
4939sub pp_hslice   { maybe_local(@_, slice(@_, "{", "}", "rv2hv", "padhv")) }
4940sub pp_kvhslice {                 slice(@_, "{", "}", "rv2hv", "padhv")  }
4941
4942sub pp_lslice {
4943    my $self = shift;
4944    my($op, $cx) = @_;
4945    my $idx = $op->first;
4946    my $list = $op->last;
4947    my(@elems, $kid);
4948    $list = $self->deparse($list, 1);
4949    $idx = $self->deparse($idx, 1);
4950    return "($list)" . "[$idx]";
4951}
4952
4953sub want_scalar {
4954    my $op = shift;
4955    return ($op->flags & OPf_WANT) == OPf_WANT_SCALAR;
4956}
4957
4958sub want_list {
4959    my $op = shift;
4960    return ($op->flags & OPf_WANT) == OPf_WANT_LIST;
4961}
4962
4963sub _method {
4964    my $self = shift;
4965    my($op, $cx) = @_;
4966    my $kid = $op->first->sibling; # skip pushmark
4967    my($meth, $obj, @exprs);
4968    if ($kid->name eq "list" and want_list $kid) {
4969	# When an indirect object isn't a bareword but the args are in
4970	# parens, the parens aren't part of the method syntax (the LLAFR
4971	# doesn't apply), but they make a list with OPf_PARENS set that
4972	# doesn't get flattened by the append_elem that adds the method,
4973	# making a (object, arg1, arg2, ...) list where the object
4974	# usually is. This can be distinguished from
4975	# '($obj, $arg1, $arg2)->meth()' (which is legal if $arg2 is an
4976	# object) because in the later the list is in scalar context
4977	# as the left side of -> always is, while in the former
4978	# the list is in list context as method arguments always are.
4979	# (Good thing there aren't method prototypes!)
4980	$meth = $kid->sibling;
4981	$kid = $kid->first->sibling; # skip pushmark
4982	$obj = $kid;
4983	$kid = $kid->sibling;
4984	for (; not null $kid; $kid = $kid->sibling) {
4985	    push @exprs, $kid;
4986	}
4987    } else {
4988	$obj = $kid;
4989	$kid = $kid->sibling;
4990	for (; !null ($kid->sibling) && $kid->name!~/^method(?:_named)?\z/;
4991	      $kid = $kid->sibling) {
4992	    push @exprs, $kid
4993	}
4994	$meth = $kid;
4995    }
4996
4997    if ($meth->name eq "method_named") {
4998	$meth = $self->meth_sv($meth)->PV;
4999    } elsif ($meth->name eq "method_super") {
5000	$meth = "SUPER::".$self->meth_sv($meth)->PV;
5001    } elsif ($meth->name eq "method_redir") {
5002        $meth = $self->meth_rclass_sv($meth)->PV.'::'.$self->meth_sv($meth)->PV;
5003    } elsif ($meth->name eq "method_redir_super") {
5004        $meth = $self->meth_rclass_sv($meth)->PV.'::SUPER::'.
5005                $self->meth_sv($meth)->PV;
5006    } else {
5007	$meth = $meth->first;
5008	if ($meth->name eq "const") {
5009	    # As of 5.005_58, this case is probably obsoleted by the
5010	    # method_named case above
5011	    $meth = $self->const_sv($meth)->PV; # needs to be bare
5012	}
5013    }
5014
5015    return { method => $meth, variable_method => ref($meth),
5016             object => $obj, args => \@exprs  },
5017	   $cx;
5018}
5019
5020# compat function only
5021sub method {
5022    my $self = shift;
5023    my $info = $self->_method(@_);
5024    return $self->e_method( $self->_method(@_) );
5025}
5026
5027sub e_method {
5028    my ($self, $info, $cx) = @_;
5029    my $obj = $self->deparse($info->{object}, 24);
5030
5031    my $meth = $info->{method};
5032    $meth = $self->deparse($meth, 1) if $info->{variable_method};
5033    my $args = join(", ", map { $self->deparse($_, 6) } @{$info->{args}} );
5034    if ($info->{object}->name eq 'scope' && want_list $info->{object}) {
5035	# method { $object }
5036	# This must be deparsed this way to preserve list context
5037	# of $object.
5038	my $need_paren = $cx >= 6;
5039	return '(' x $need_paren
5040	     . $meth . substr($obj,2) # chop off the "do"
5041	     . " $args"
5042	     . ')' x $need_paren;
5043    }
5044    my $kid = $obj . "->" . $meth;
5045    if (length $args) {
5046	return $kid . "(" . $args . ")"; # parens mandatory
5047    } else {
5048	return $kid;
5049    }
5050}
5051
5052# returns "&" if the prototype doesn't match the args,
5053# or ("", $args_after_prototype_demunging) if it does.
5054sub check_proto {
5055    my $self = shift;
5056    return "&" if $self->{'noproto'};
5057    my ($proto, @args) = @_;
5058    my $doneok = 0;
5059    my @reals;
5060    $proto =~ s/^\s+//;
5061    while (length $proto) {
5062        $proto =~ s/^(\\?[\$\@&%*]|\\\[[\$\@&%*]+\]|[_+;])\s*//
5063            or return "&";  # malformed prototype
5064	my $chr = $1;
5065        if ($chr eq ";") {
5066	    $doneok = 1;
5067        } elsif ($chr eq '@' or $chr eq '%') {
5068            # An unbackslashed @ or % gobbles up the rest of the args
5069	    push @reals, map($self->deparse($_, 6), @args);
5070	    @args = ();
5071            $proto = '';
5072        } elsif (!@args) {
5073            last if $doneok;
5074            return "&"; # too few args and no ';'
5075	} else {
5076            my $arg = shift @args;
5077            if ($chr eq '$' || $chr eq '_') {
5078		if (want_scalar $arg) {
5079		    push @reals, $self->deparse($arg, 6);
5080		} else {
5081		    return "&";
5082		}
5083	    } elsif ($chr eq "&") {
5084                if ($arg->name =~ /^(?:s?refgen|undef)\z/) {
5085		    push @reals, $self->deparse($arg, 6);
5086		} else {
5087		    return "&";
5088		}
5089	    } elsif ($chr eq "*") {
5090                if ($arg->name =~ /^s?refgen\z/
5091		    and $arg->first->first->name eq "rv2gv")
5092                {
5093                    my $real = $arg->first->first; # skip refgen, null
5094                    if ($real->first->name eq "gv") {
5095                        push @reals, $self->deparse($real, 6);
5096                    } else {
5097                        push @reals, $self->deparse($real->first, 6);
5098                    }
5099                } else {
5100                    return "&";
5101                }
5102            } elsif ($chr eq "+") {
5103                my $real;
5104                if ($arg->name =~ /^s?refgen\z/ and
5105                    !null($real = $arg->first) and
5106                    !null($real->first) and
5107                    $real->first->name =~ /^(?:rv2|pad)[ah]v\z/)
5108                {
5109                    push @reals, $self->deparse($real, 6);
5110                } elsif (want_scalar $arg) {
5111                    push @reals, $self->deparse($arg, 6);
5112                } else {
5113                    return "&";
5114                }
5115	    } elsif (substr($chr, 0, 1) eq "\\") {
5116		$chr =~ tr/\\[]//d;
5117                my $real;
5118                if ($arg->name =~ /^s?refgen\z/ and
5119		    !null($real = $arg->first) and
5120		    ($chr =~ /\$/ && is_scalar($real->first)
5121		     or ($chr =~ /@/
5122                         && !null($real->first)
5123                         && $real->first->name =~ /^(?:rv2|pad)av\z/)
5124		     or ($chr =~ /%/
5125                         && !null($real->first)
5126                         && $real->first->name =~ /^(?:rv2|pad)hv\z/)
5127		     #or ($chr =~ /&/ # This doesn't work
5128		     #   && $real->first->name eq "rv2cv")
5129		     or ($chr =~ /\*/
5130			 && $real->first->name eq "rv2gv")))
5131                {
5132                    push @reals, $self->deparse($real, 6);
5133                } else {
5134                    return "&";
5135                }
5136            } else {
5137                # should not happen
5138                return "&";
5139            }
5140        }
5141    }
5142    return "&" if @args; # too many args
5143    return ("", join ", ", @reals);
5144}
5145
5146sub retscalar {
5147    my $name = $_[0]->name;
5148    # XXX There has to be a better way of doing this scalar-op check.
5149    #     Currently PL_opargs is not exposed.
5150    if ($name eq 'null') {
5151        $name = substr B::ppname($_[0]->targ), 3
5152    }
5153    $name =~ /^(?:scalar|pushmark|wantarray|const|gvsv|gv|padsv|rv2gv
5154                 |rv2sv|av2arylen|anoncode|prototype|srefgen|ref|bless
5155                 |regcmaybe|regcreset|regcomp|qr|subst|substcont|trans
5156                 |transr|sassign|chop|schop|chomp|schomp|defined|undef
5157                 |study|pos|preinc|i_preinc|predec|i_predec|postinc
5158                 |i_postinc|postdec|i_postdec|pow|multiply|i_multiply
5159                 |divide|i_divide|modulo|i_modulo|add|i_add|subtract
5160                 |i_subtract|concat|multiconcat|stringify|left_shift|right_shift|lt
5161                 |i_lt|gt|i_gt|le|i_le|ge|i_ge|eq|i_eq|ne|i_ne|ncmp|i_ncmp
5162                 |slt|sgt|sle|sge|seq|sne|scmp|[sn]?bit_(?:and|x?or)|negate
5163                 |i_negate|not|[sn]?complement|smartmatch|atan2|sin|cos
5164                 |rand|srand|exp|log|sqrt|int|hex|oct|abs|length|substr
5165                 |vec|index|rindex|sprintf|formline|ord|chr|crypt|ucfirst
5166                 |lcfirst|uc|lc|quotemeta|aelemfast|aelem|exists|helem
5167                 |pack|join|anonlist|anonhash|push|pop|shift|unshift|xor
5168                 |andassign|orassign|dorassign|warn|die|reset|nextstate
5169                 |dbstate|unstack|last|next|redo|dump|goto|exit|open|close
5170                 |pipe_op|fileno|umask|binmode|tie|untie|tied|dbmopen
5171                 |dbmclose|select|getc|read|enterwrite|prtf|print|say
5172                 |sysopen|sysseek|sysread|syswrite|eof|tell|seek|truncate
5173                 |fcntl|ioctl|flock|send|recv|socket|sockpair|bind|connect
5174                 |listen|accept|shutdown|gsockopt|ssockopt|getsockname
5175                 |getpeername|ftrread|ftrwrite|ftrexec|fteread|ftewrite
5176                 |fteexec|ftis|ftsize|ftmtime|ftatime|ftctime|ftrowned
5177                 |fteowned|ftzero|ftsock|ftchr|ftblk|ftfile|ftdir|ftpipe
5178                 |ftsuid|ftsgid|ftsvtx|ftlink|fttty|fttext|ftbinary|chdir
5179                 |chown|chroot|unlink|chmod|utime|rename|link|symlink
5180                 |readlink|mkdir|rmdir|open_dir|telldir|seekdir|rewinddir
5181                 |closedir|fork|wait|waitpid|system|exec|kill|getppid
5182                 |getpgrp|setpgrp|getpriority|setpriority|time|alarm|sleep
5183                 |shmget|shmctl|shmread|shmwrite|msgget|msgctl|msgsnd
5184                 |msgrcv|semop|semget|semctl|hintseval|shostent|snetent
5185                 |sprotoent|sservent|ehostent|enetent|eprotoent|eservent
5186                 |spwent|epwent|sgrent|egrent|getlogin|syscall|lock|runcv
5187                 |fc|padsv_store)\z/x
5188}
5189
5190sub pp_entersub {
5191    my $self = shift;
5192    my($op, $cx) = @_;
5193    return $self->e_method($self->_method($op, $cx))
5194        unless null $op->first->sibling;
5195    my $prefix = "";
5196    my $amper = "";
5197    my($kid, @exprs);
5198    if ($op->private & OPpENTERSUB_AMPER) {
5199	$amper = "&";
5200    }
5201    $kid = $op->first;
5202    $kid = $kid->first->sibling; # skip ex-list, pushmark
5203    for (; not null $kid->sibling; $kid = $kid->sibling) {
5204	push @exprs, $kid;
5205    }
5206    my $simple = 0;
5207    my $proto = undef;
5208    my $lexical;
5209    if (is_scope($kid)) {
5210	$amper = "&";
5211	$kid = "{" . $self->deparse($kid, 0) . "}";
5212    } elsif ($kid->first->name eq "gv") {
5213	my $gv = $self->gv_or_padgv($kid->first);
5214	my $cv;
5215	if (class($gv) eq 'GV' && class($cv = $gv->CV) ne "SPECIAL"
5216	 || $gv->FLAGS & SVf_ROK && class($cv = $gv->RV) eq 'CV') {
5217	    $proto = $cv->PV if $cv->FLAGS & SVf_POK;
5218	}
5219	$simple = 1; # only calls of named functions can be prototyped
5220	$kid = $self->maybe_qualify("!", $self->gv_name($gv));
5221	my $fq;
5222	# Fully qualify any sub name that conflicts with a lexical.
5223	if ($self->lex_in_scope("&$kid")
5224	 || $self->lex_in_scope("&$kid", 1))
5225	{
5226	    $fq++;
5227	} elsif (!$amper) {
5228	    if ($kid eq 'main::') {
5229		$kid = '::';
5230	    }
5231	    else {
5232	      if ($kid !~ /::/ && $kid ne 'x') {
5233		# Fully qualify any sub name that is also a keyword.  While
5234		# we could check the import flag, we cannot guarantee that
5235		# the code deparsed so far would set that flag, so we qual-
5236		# ify the names regardless of importation.
5237		if (exists $feature_keywords{$kid}) {
5238		    $fq++ if $self->feature_enabled($kid);
5239		} elsif (do { local $@; local $SIG{__DIE__};
5240			      eval { () = prototype "CORE::$kid"; 1 } }) {
5241		    $fq++
5242		}
5243	      }
5244	      if ($kid !~ /^(?:\w|::)(?:[\w\d]|::(?!\z))*\z/) {
5245		$kid = single_delim("q", "'", $kid, $self) . '->';
5246	      }
5247	    }
5248	}
5249	$fq and substr $kid, 0, 0, = $self->{'curstash'}.'::';
5250    } elsif (is_scalar ($kid->first) && $kid->first->name ne 'rv2cv') {
5251	$amper = "&";
5252	$kid = $self->deparse($kid, 24);
5253    } else {
5254	$prefix = "";
5255	my $grandkid = $kid->first;
5256	my $arrow = ($lexical = $grandkid->name eq "padcv")
5257		 || is_subscriptable($grandkid)
5258		    ? ""
5259		    : "->";
5260	$kid = $self->deparse($kid, 24) . $arrow;
5261	if ($lexical) {
5262	    my $padlist = $self->{'curcv'}->PADLIST;
5263	    my $padoff = $grandkid->targ;
5264	    my $padname = $padlist->ARRAYelt(0)->ARRAYelt($padoff);
5265	    my $protocv = $padname->FLAGS & SVpad_STATE
5266		? $padlist->ARRAYelt(1)->ARRAYelt($padoff)
5267		: $padname->PROTOCV;
5268	    if ($protocv->FLAGS & SVf_POK) {
5269		$proto = $protocv->PV
5270	    }
5271	    $simple = 1;
5272	}
5273    }
5274
5275    # Doesn't matter how many prototypes there are, if
5276    # they haven't happened yet!
5277    my $declared = $lexical || exists $self->{'subs_declared'}{$kid};
5278    if (not $declared and $self->{'in_coderef2text'}) {
5279	no strict 'refs';
5280	no warnings 'uninitialized';
5281	$declared =
5282	       (
5283		 defined &{ ${$self->{'curstash'}."::"}{$kid} }
5284		 && !exists
5285		     $self->{'subs_deparsed'}{$self->{'curstash'}."::".$kid}
5286		 && defined prototype $self->{'curstash'}."::".$kid
5287	       );
5288    }
5289    if (!$declared && defined($proto)) {
5290	# Avoid "too early to check prototype" warning
5291	($amper, $proto) = ('&');
5292    }
5293
5294    my $args;
5295    my $listargs = 1;
5296    if ($declared and defined $proto and not $amper) {
5297	($amper, $args) = $self->check_proto($proto, @exprs);
5298	$listargs = $amper;
5299    }
5300    if ($listargs) {
5301	$args = join(", ", map(
5302		    ($_->flags & OPf_WANT) == OPf_WANT_SCALAR
5303		 && !retscalar($_)
5304			? $self->maybe_parens_unop('scalar', $_, 6)
5305			: $self->deparse($_, 6),
5306		    @exprs
5307		));
5308    }
5309    if ($prefix or $amper) {
5310	if ($kid eq '&') { $kid = "{$kid}" } # &{&} cannot be written as &&
5311	if ($op->flags & OPf_STACKED) {
5312	    return $prefix . $amper . $kid . "(" . $args . ")";
5313	} else {
5314	    return $prefix . $amper. $kid;
5315	}
5316    } else {
5317	# It's a syntax error to call CORE::GLOBAL::foo with a prefix,
5318	# so it must have been translated from a keyword call. Translate
5319	# it back.
5320	$kid =~ s/^CORE::GLOBAL:://;
5321
5322        if (!$declared) {
5323	    return "$kid(" . $args . ")";
5324        }
5325
5326        my $dproto = defined($proto) ? $proto : "undefined";
5327        if ($dproto =~ /^\s*\z/) {
5328	    return $kid;
5329        }
5330
5331        my $scalar_proto = $dproto =~ /^ \s* (?: ;\s* )* (?: [\$*_+] |\\ \s* (?: [\$\@%&*] | \[ [^\]]+ \] ) ) \s* \z/x;
5332        if ($scalar_proto and !@exprs || is_scalar($exprs[0])) {
5333	    # is_scalar is an excessively conservative test here:
5334	    # really, we should be comparing to the precedence of the
5335	    # top operator of $exprs[0] (ala unop()), but that would
5336	    # take some major code restructuring to do right.
5337	    return $self->maybe_parens_func($kid, $args, $cx, 16);
5338        } elsif (not $scalar_proto and defined($proto) || $simple) {
5339	    return $self->maybe_parens_func($kid, $args, $cx, 5);
5340	} else {
5341	    return "$kid(" . $args . ")";
5342	}
5343    }
5344}
5345
5346sub pp_enterwrite { unop(@_, "write") }
5347
5348# escape things that cause interpolation in double quotes,
5349# but not character escapes
5350sub uninterp {
5351    my($str) = @_;
5352    $str =~ s/(^|\G|[^\\])((?:\\\\)*)([\$\@]|\\[uUlLQE])/$1$2\\$3/g;
5353    return $str;
5354}
5355
5356{
5357my $bal;
5358BEGIN {
5359    use re "eval";
5360    # Matches any string which is balanced with respect to {braces}
5361    $bal = qr(
5362      (?:
5363	[^\\{}]
5364      | \\\\
5365      | \\[{}]
5366      | \{(??{$bal})\}
5367      )*
5368    )x;
5369}
5370
5371# the same, but treat $|, $), $( and $ at the end of the string differently
5372# and leave comments unmangled for the sake of /x and (?x).
5373sub re_uninterp {
5374    my($str) = @_;
5375
5376    $str =~ s/
5377	  ( ^|\G                  # $1
5378          | [^\\]
5379          )
5380
5381          (                       # $2
5382            (?:\\\\)*
5383          )
5384
5385          (                       # $3
5386            ( \(\?\??\{$bal\}\)   # $4  (skip over (?{}) and (??{}) blocks)
5387            | \#[^\n]*            #     (skip over comments)
5388            )
5389          | [\$\@]
5390            (?!\||\)|\(|$|\s)
5391          | \\[uUlLQE]
5392          )
5393
5394	/defined($4) && length($4) ? "$1$2$4" : "$1$2\\$3"/xeg;
5395
5396    return $str;
5397}
5398}
5399
5400# character escapes, but not delimiters that might need to be escaped
5401sub escape_str { # ASCII, UTF8
5402    my($str) = @_;
5403    $str =~ s/(.)/ord($1) > 255 ? sprintf("\\x{%x}", ord($1)) : $1/eg;
5404    $str =~ s/\a/\\a/g;
5405#    $str =~ s/\cH/\\b/g; # \b means something different in a regex; and \cH
5406                          # isn't a backspace in EBCDIC
5407    $str =~ s/\t/\\t/g;
5408    $str =~ s/\n/\\n/g;
5409    $str =~ s/\e/\\e/g;
5410    $str =~ s/\f/\\f/g;
5411    $str =~ s/\r/\\r/g;
5412    $str =~ s/([\cA-\cZ])/'\\c' . $unctrl{$1}/ge;
5413    $str =~ s/([[:^print:]])/sprintf("\\%03o", ord($1))/age;
5414    return $str;
5415}
5416
5417# For regexes.  Leave whitespace unmangled in case of /x or (?x).
5418sub escape_re {
5419    my($str) = @_;
5420    $str =~ s/(.)/ord($1) > 255 ? sprintf("\\x{%x}", ord($1)) : $1/eg;
5421    $str =~ s/([[:^print:]])/
5422	($1 =~ y! \t\n!!) ? $1 : sprintf("\\%03o", ord($1))/age;
5423    $str =~ s/\n/\n\f/g;
5424    return $str;
5425}
5426
5427# Don't do this for regexen
5428sub unback {
5429    my($str) = @_;
5430    $str =~ s/\\/\\\\/g;
5431    return $str;
5432}
5433
5434# Remove backslashes which precede literal control characters,
5435# to avoid creating ambiguity when we escape the latter.
5436#
5437# Don't remove a backslash from escaped whitespace: where the T represents
5438# a literal tab character, /T/x is not equivalent to /\T/x
5439
5440sub re_unback {
5441    my($str) = @_;
5442
5443    # the insane complexity here is due to the behaviour of "\c\"
5444    $str =~ s/
5445                # these two lines ensure that the backslash we're about to
5446                # remove isn't preceded by something which makes it part
5447                # of a \c
5448
5449                (^ | [^\\] | \\c\\)             # $1
5450                (?<!\\c)
5451
5452                # the backslash to remove
5453                \\
5454
5455                # keep pairs of backslashes
5456                (\\\\)*                         # $2
5457
5458                # only remove if the thing following is a control char
5459                (?=[[:^print:]])
5460                # and not whitespace
5461                (?=\S)
5462            /$1$2/xg;
5463    return $str;
5464}
5465
5466sub balanced_delim {
5467    my($str) = @_;
5468    my @str = split //, $str;
5469    my($ar, $open, $close, $fail, $c, $cnt, $last_bs);
5470    for $ar (['[',']'], ['(',')'], ['<','>'], ['{','}']) {
5471	($open, $close) = @$ar;
5472	$fail = 0; $cnt = 0; $last_bs = 0;
5473	for $c (@str) {
5474	    if ($c eq $open) {
5475		$fail = 1 if $last_bs;
5476		$cnt++;
5477	    } elsif ($c eq $close) {
5478		$fail = 1 if $last_bs;
5479		$cnt--;
5480		if ($cnt < 0) {
5481		    # qq()() isn't ")("
5482		    $fail = 1;
5483		    last;
5484		}
5485	    }
5486	    $last_bs = $c eq '\\';
5487	}
5488	$fail = 1 if $cnt != 0;
5489	return ($open, "$open$str$close") if not $fail;
5490    }
5491    return ("", $str);
5492}
5493
5494sub single_delim {
5495    my($q, $default, $str, $self) = @_;
5496    return "$default$str$default" if $default and index($str, $default) == -1;
5497    my $coreq = $self->keyword($q); # maybe CORE::q
5498    if ($q ne 'qr') {
5499	(my $succeed, $str) = balanced_delim($str);
5500	return "$coreq$str" if $succeed;
5501    }
5502    for my $delim ('/', '"', '#') {
5503	return "$coreq$delim" . $str . $delim if index($str, $delim) == -1;
5504    }
5505    if ($default) {
5506	$str =~ s/$default/\\$default/g;
5507	return "$default$str$default";
5508    } else {
5509	$str =~ s[/][\\/]g;
5510	return "$coreq/$str/";
5511    }
5512}
5513
5514my $max_prec;
5515BEGIN { $max_prec = int(0.999 + 8*length(pack("F", 42))*log(2)/log(10)); }
5516
5517# Split a floating point number into an integer mantissa and a binary
5518# exponent. Assumes you've already made sure the number isn't zero or
5519# some weird infinity or NaN.
5520sub split_float {
5521    my($f) = @_;
5522    my $exponent = 0;
5523    if ($f == int($f)) {
5524	while ($f % 2 == 0) {
5525	    $f /= 2;
5526	    $exponent++;
5527	}
5528    } else {
5529	while ($f != int($f)) {
5530	    $f *= 2;
5531	    $exponent--;
5532	}
5533    }
5534    my $mantissa = sprintf("%.0f", $f);
5535    return ($mantissa, $exponent);
5536}
5537
5538
5539# suitably single- or double-quote a literal constant string
5540
5541sub quoted_const_str {
5542    my ($self, $str) =@_;
5543    if ($str =~ /[[:^print:]]/a) {
5544        return single_delim("qq", '"',
5545                             uninterp(escape_str unback $str), $self);
5546    } else {
5547        return single_delim("q", "'", unback($str), $self);
5548    }
5549}
5550
5551
5552sub const {
5553    my $self = shift;
5554    my($sv, $cx) = @_;
5555    if ($self->{'use_dumper'}) {
5556	return $self->const_dumper($sv, $cx);
5557    }
5558    if (class($sv) eq "SPECIAL") {
5559	# PL_sv_undef etc
5560        # return yes/no as boolean expressions rather than integers to
5561        # preserve their boolean-ness
5562	return
5563            $$sv == 1 ? 'undef'                            : # PL_sv_undef
5564            $$sv == 2 ? $self->maybe_parens("!0", $cx, 21) : # PL_sv_yes
5565            $$sv == 3 ? $self->maybe_parens("!1", $cx, 21) : # PL_sv_no
5566            $$sv == 7 ? '0'                                : # PL_sv_zero
5567                        '"???"';
5568    }
5569    if (class($sv) eq "NULL") {
5570       return 'undef';
5571    }
5572    # convert a version object into the "v1.2.3" string in its V magic
5573    if ($sv->FLAGS & SVs_RMG) {
5574	for (my $mg = $sv->MAGIC; $mg; $mg = $mg->MOREMAGIC) {
5575	    return $mg->PTR if $mg->TYPE eq 'V';
5576	}
5577    }
5578
5579    if ($sv->FLAGS & SVf_IOK) {
5580	my $str = $sv->int_value;
5581	$str = $self->maybe_parens($str, $cx, 21) if $str < 0;
5582	return $str;
5583    } elsif ($sv->FLAGS & SVf_NOK) {
5584	my $nv = $sv->NV;
5585	if ($nv == 0) {
5586	    if (pack("F", $nv) eq pack("F", 0)) {
5587		# positive zero
5588		return "0.0";
5589	    } else {
5590		# negative zero
5591		return $self->maybe_parens("-0.0", $cx, 21);
5592	    }
5593	} elsif (1/$nv == 0) {
5594	    if ($nv > 0) {
5595		# positive infinity
5596		return $self->maybe_parens("9**9**9", $cx, 22);
5597	    } else {
5598		# negative infinity
5599		return $self->maybe_parens("-9**9**9", $cx, 21);
5600	    }
5601	} elsif ($nv != $nv) {
5602	    # NaN
5603	    if (pack("F", $nv) eq pack("F", sin(9**9**9))) {
5604		# the normal kind
5605		return "sin(9**9**9)";
5606	    } elsif (pack("F", $nv) eq pack("F", -sin(9**9**9))) {
5607		# the inverted kind
5608		return $self->maybe_parens("-sin(9**9**9)", $cx, 21);
5609	    } else {
5610		# some other kind
5611		my $hex = unpack("h*", pack("F", $nv));
5612		return qq'unpack("F", pack("h*", "$hex"))';
5613	    }
5614	}
5615	# first, try the default stringification
5616	my $str = "$nv";
5617	if ($str != $nv) {
5618	    # failing that, try using more precision
5619	    $str = sprintf("%.${max_prec}g", $nv);
5620#	    if (pack("F", $str) ne pack("F", $nv)) {
5621	    if ($str != $nv) {
5622		# not representable in decimal with whatever sprintf()
5623		# and atof() Perl is using here.
5624		my($mant, $exp) = split_float($nv);
5625		return $self->maybe_parens("$mant * 2**$exp", $cx, 19);
5626	    }
5627	}
5628
5629        # preserve NV-ness: output as NNN.0 rather than NNN
5630        $str .= ".0" if $str =~ /^-?[0-9]+$/;
5631
5632	$str = $self->maybe_parens($str, $cx, 21) if $nv < 0;
5633	return $str;
5634    } elsif ($sv->FLAGS & SVf_ROK && $sv->can("RV")) {
5635	my $ref = $sv->RV;
5636	my $class = class($ref);
5637	if ($class eq "AV") {
5638	    return "[" . $self->list_const(2, $ref->ARRAY) . "]";
5639	} elsif ($class eq "HV") {
5640	    my %hash = $ref->ARRAY;
5641	    my @elts;
5642	    for my $k (sort keys %hash) {
5643		push @elts, "$k => " . $self->const($hash{$k}, 6);
5644	    }
5645	    return "{" . join(", ", @elts) . "}";
5646	} elsif ($class eq "CV") {
5647	    no overloading;
5648	    if ($self->{curcv} &&
5649		 $self->{curcv}->object_2svref == $ref->object_2svref) {
5650		return $self->keyword("__SUB__");
5651	    }
5652	    return "sub " . $self->deparse_sub($ref);
5653	}
5654	if ($class ne 'SPECIAL' and $ref->FLAGS & SVs_SMG) {
5655	    for (my $mg = $ref->MAGIC; $mg; $mg = $mg->MOREMAGIC) {
5656		if ($mg->TYPE eq 'r') {
5657		    my $re = re_uninterp(escape_re(re_unback($mg->precomp)));
5658		    return single_delim("qr", "", $re, $self);
5659		}
5660	    }
5661	}
5662
5663	my $const = $self->const($ref, 20);
5664	if ($self->{in_subst_repl} && $const =~ /^[0-9]/) {
5665	    $const = "($const)";
5666	}
5667	return $self->maybe_parens("\\$const", $cx, 20);
5668    } elsif ($sv->FLAGS & SVf_POK) {
5669	my $str = $sv->PV;
5670        return $self->quoted_const_str($str);
5671    } else {
5672	return "undef";
5673    }
5674}
5675
5676sub const_dumper {
5677    my $self = shift;
5678    my($sv, $cx) = @_;
5679    my $ref = $sv->object_2svref();
5680    my $dumper = Data::Dumper->new([$$ref], ['$v']);
5681    $dumper->Purity(1)->Terse(1)->Deparse(1)->Indent(0)->Useqq(1)->Sortkeys(1);
5682    my $str = $dumper->Dump();
5683    if ($str =~ /^\$v/) {
5684	return '${my ' . $str . ' \$v}';
5685    } else {
5686	return $str;
5687    }
5688}
5689
5690sub const_sv {
5691    my $self = shift;
5692    my $op = shift;
5693    my $sv = $op->sv;
5694    # the constant could be in the pad (under useithreads)
5695    $sv = $self->padval($op->targ) unless $$sv;
5696    return $sv;
5697}
5698
5699sub meth_sv {
5700    my $self = shift;
5701    my $op = shift;
5702    my $sv = $op->meth_sv;
5703    # the constant could be in the pad (under useithreads)
5704    $sv = $self->padval($op->targ) unless $$sv;
5705    return $sv;
5706}
5707
5708sub meth_rclass_sv {
5709    my $self = shift;
5710    my $op = shift;
5711    my $sv = $op->rclass;
5712    # the constant could be in the pad (under useithreads)
5713    $sv = $self->padval($sv) unless ref $sv;
5714    return $sv;
5715}
5716
5717sub pp_const {
5718    my $self = shift;
5719    my($op, $cx) = @_;
5720#    if ($op->private & OPpCONST_BARE) { # trouble with '=>' autoquoting
5721#	return $self->const_sv($op)->PV;
5722#    }
5723    my $sv = $self->const_sv($op);
5724    return $self->const($sv, $cx);
5725}
5726
5727
5728# Join two components of a double-quoted string, disambiguating
5729# "${foo}bar", "${foo}{bar}", "${foo}[1]", "$foo\::bar"
5730
5731sub dq_disambiguate {
5732    my ($first, $last) = @_;
5733    ($last =~ /^[A-Z\\\^\[\]_?]/ &&
5734        $first =~ s/([\$@])\^$/${1}{^}/)  # "${^}W" etc
5735        || ($last =~ /^[:'{\[\w_]/ && #'
5736            $first =~ s/([\$@])([A-Za-z_]\w*)$/${1}{$2}/);
5737    return $first . $last;
5738}
5739
5740
5741# Deparse a double-quoted optree. For example, "$a[0]\Q$b\Efo\"o" gets
5742# compiled to concat(concat($[0],quotemeta($b)),const("fo\"o")), and this
5743# sub deparses it back to $a[0]\Q$b\Efo"o
5744# (It does not add delimiters)
5745
5746sub dq {
5747    my $self = shift;
5748    my $op = shift;
5749    my $type = $op->name;
5750    if ($type eq "const") {
5751	return uninterp(escape_str(unback($self->const_sv($op)->as_string)));
5752    } elsif ($type eq "concat") {
5753        return dq_disambiguate($self->dq($op->first), $self->dq($op->last));
5754    } elsif ($type eq "multiconcat") {
5755        return $self->do_multiconcat($op, 26, 1);
5756    } elsif ($type eq "uc") {
5757	return '\U' . $self->dq($op->first->sibling) . '\E';
5758    } elsif ($type eq "lc") {
5759	return '\L' . $self->dq($op->first->sibling) . '\E';
5760    } elsif ($type eq "ucfirst") {
5761	return '\u' . $self->dq($op->first->sibling);
5762    } elsif ($type eq "lcfirst") {
5763	return '\l' . $self->dq($op->first->sibling);
5764    } elsif ($type eq "quotemeta") {
5765	return '\Q' . $self->dq($op->first->sibling) . '\E';
5766    } elsif ($type eq "fc") {
5767	return '\F' . $self->dq($op->first->sibling) . '\E';
5768    } elsif ($type eq "join") {
5769	return $self->deparse($op->last, 26); # was join($", @ary)
5770    } else {
5771	return $self->deparse($op, 26);
5772    }
5773}
5774
5775sub pp_backtick {
5776    my $self = shift;
5777    my($op, $cx) = @_;
5778    # skip pushmark if it exists (readpipe() vs ``)
5779    my $child = $op->first->sibling->isa('B::NULL')
5780	? $op->first : $op->first->sibling;
5781    if ($self->pure_string($child)) {
5782	return single_delim("qx", '`', $self->dq($child, 1), $self);
5783    }
5784    unop($self, @_, "readpipe");
5785}
5786
5787sub dquote {
5788    my $self = shift;
5789    my($op, $cx) = @_;
5790    my $kid = $op->first->sibling; # skip ex-stringify, pushmark
5791    return $self->deparse($kid, $cx) if $self->{'unquote'};
5792    $self->maybe_targmy($kid, $cx,
5793			sub {single_delim("qq", '"', $self->dq($_[1]),
5794					   $self)});
5795}
5796
5797# OP_STRINGIFY is a listop, but it only ever has one arg
5798sub pp_stringify {
5799    my ($self, $op, $cx) = @_;
5800    my $kid = $op->first->sibling;
5801    while ($kid->name eq 'null' && !null($kid->first)) {
5802	$kid = $kid->first;
5803    }
5804    if ($kid->name =~ /^(?:const|padsv|rv2sv|av2arylen|gvsv|multideref
5805			  |aelemfast(?:_lex)?|[ah]elem|join|concat)\z/x) {
5806	maybe_targmy(@_, \&dquote);
5807    }
5808    else {
5809	# Actually an optimised join.
5810	my $result = listop(@_,"join");
5811	$result =~ s/join([( ])/join$1$self->{'ex_const'}, /;
5812	$result;
5813    }
5814}
5815
5816# tr/// and s/// (and tr[][], tr[]//, tr###, etc)
5817# note that tr(from)/to/ is OK, but not tr/from/(to)
5818sub double_delim {
5819    my($from, $to) = @_;
5820    my($succeed, $delim);
5821    if ($from !~ m[/] and $to !~ m[/]) {
5822	return "/$from/$to/";
5823    } elsif (($succeed, $from) = balanced_delim($from) and $succeed) {
5824	if (($succeed, $to) = balanced_delim($to) and $succeed) {
5825	    return "$from$to";
5826	} else {
5827	    for $delim ('/', '"', '#') { # note no "'" -- s''' is special
5828		return "$from$delim$to$delim" if index($to, $delim) == -1;
5829	    }
5830	    $to =~ s[/][\\/]g;
5831	    return "$from/$to/";
5832	}
5833    } else {
5834	for $delim ('/', '"', '#') { # note no '
5835	    return "$delim$from$delim$to$delim"
5836		if index($to . $from, $delim) == -1;
5837	}
5838	$from =~ s[/][\\/]g;
5839	$to =~ s[/][\\/]g;
5840	return "/$from/$to/";
5841    }
5842}
5843
5844# Escape a characrter.
5845# Only used by tr///, so backslashes hyphens
5846
5847sub pchr {
5848    my($n) = @_;
5849    return sprintf("\\x{%X}", $n) if $n > 255;
5850    return '\\\\' if $n == ord '\\';
5851    return "\\-" if $n == ord "-";
5852    # I'm presuming a regex is not ok here, otherwise we could have used
5853    # /[[:print:]]/a to get here
5854    return chr($n) if (        utf8::native_to_unicode($n)
5855                            >= utf8::native_to_unicode(ord(' '))
5856                        and    utf8::native_to_unicode($n)
5857                            <= utf8::native_to_unicode(ord('~')));
5858
5859    my $mnemonic_pos = index("\a\b\e\f\n\r\t", chr($n));
5860    return "\\" . substr("abefnrt", $mnemonic_pos, 1) if $mnemonic_pos >= 0;
5861
5862    return '\\c' . $unctrl{chr $n} if $n >= ord("\cA") and $n <= ord("\cZ");
5863#   return '\x' . sprintf("%02x", $n);
5864    return '\\' . sprintf("%03o", $n);
5865}
5866
5867# Convert a list of characters into a string suitable for tr/// search or
5868# replacement, with suitable escaping and collapsing of ranges
5869
5870sub collapse {
5871    my(@chars) = @_;
5872    my($str, $c, $tr) = ("");
5873    for ($c = 0; $c < @chars; $c++) {
5874	$tr = $chars[$c];
5875	$str .= pchr($tr);
5876	if ($c <= $#chars - 2 and $chars[$c + 1] == $tr + 1 and
5877	    $chars[$c + 2] == $tr + 2)
5878	{
5879	    for (; $c <= $#chars-1 and $chars[$c + 1] == $chars[$c] + 1; $c++)
5880	      {}
5881	    $str .= "-";
5882	    $str .= pchr($chars[$c]);
5883	}
5884    }
5885    return $str;
5886}
5887
5888sub tr_decode_byte {
5889    my($table, $flags) = @_;
5890    my $ssize_t = $Config{ptrsize} == 8 ? 'q' : 'l';
5891    my ($size, @table) = unpack("${ssize_t}s*", $table);
5892    pop @table; # remove the wildcard final entry
5893
5894    my($c, $tr, @from, @to, @delfrom, $delhyphen);
5895    if ($table[ord "-"] != -1 and
5896	$table[ord("-") - 1] == -1 || $table[ord("-") + 1] == -1)
5897    {
5898	$tr = $table[ord "-"];
5899	$table[ord "-"] = -1;
5900	if ($tr >= 0) {
5901	    @from = ord("-");
5902	    @to = $tr;
5903	} else { # -2 ==> delete
5904	    $delhyphen = 1;
5905	}
5906    }
5907    for ($c = 0; $c < @table; $c++) {
5908	$tr = $table[$c];
5909	if ($tr >= 0) {
5910	    push @from, $c; push @to, $tr;
5911	} elsif ($tr == -2) {
5912	    push @delfrom, $c;
5913	}
5914    }
5915    @from = (@from, @delfrom);
5916
5917    if ($flags & OPpTRANS_COMPLEMENT) {
5918        unless ($flags & OPpTRANS_DELETE) {
5919            @to = () if ("@from" eq "@to");
5920        }
5921
5922	my @newfrom = ();
5923	my %from;
5924	@from{@from} = (1) x @from;
5925	for ($c = 0; $c < 256; $c++) {
5926	    push @newfrom, $c unless $from{$c};
5927	}
5928	@from = @newfrom;
5929    }
5930    unless ($flags & OPpTRANS_DELETE || !@to) {
5931	pop @to while $#to and $to[$#to] == $to[$#to -1];
5932    }
5933    my($from, $to);
5934    $from = collapse(@from);
5935    $to = collapse(@to);
5936    $from .= "-" if $delhyphen;
5937    return ($from, $to);
5938}
5939
5940my $infinity = ~0 >> 1;     # IV_MAX
5941
5942sub tr_append_to_invlist {
5943    my ($list_ref, $current, $next) = @_;
5944
5945    # Appends the range $current..$next-1 to the inversion list $list_ref
5946
5947    printf STDERR "%d: %d..%d %s", __LINE__, $current, $next, Dumper $list_ref if DEBUG;
5948
5949    if (@$list_ref && $list_ref->[-1] == $current) {
5950
5951        # The new range extends the current final one.  If it is a finite
5952        # rane, replace the current final by the new ending.
5953        if (defined $next) {
5954            $list_ref->[-1] = $next;
5955        }
5956        else {
5957            # The new range extends to infinity, which means the current end
5958            # of the inversion list is dangling.  Removing it causes things to
5959            # work.
5960            pop @$list_ref;
5961        }
5962    }
5963    else {  # The new range starts after the current final one; add it as a
5964            # new range
5965        push @$list_ref, $current;
5966        push @$list_ref, $next if defined $next;
5967    }
5968
5969    print STDERR __LINE__, ": ", Dumper $list_ref if DEBUG;
5970}
5971
5972sub tr_invlist_to_string {
5973    my ($list_ref, $to_complement) = @_;
5974
5975    # Stringify the inversion list $list_ref, possibly complementing it first.
5976    # CAUTION: this can modify $list_ref.
5977
5978    print STDERR __LINE__, ": ", Dumper $list_ref if DEBUG;
5979
5980    if ($to_complement) {
5981
5982        # Complementing an inversion list is done by prepending a 0 if it
5983        # doesn't have one there already; otherwise removing the leading 0.
5984        if ($list_ref->[0] == 0) {
5985            shift @$list_ref;
5986        }
5987        else {
5988            unshift @$list_ref, 0;
5989        }
5990
5991        print STDERR __LINE__, ": ", Dumper $list_ref if DEBUG;
5992    }
5993
5994    my $output = "";
5995
5996    # Every other element is in the list.
5997    for (my $i = 0; $i < @$list_ref; $i += 2) {
5998        my $base = $list_ref->[$i];
5999        $output .= pchr($base);
6000        last unless defined $list_ref->[$i+1];
6001
6002        # The beginning of the next element starts the range of items not in
6003        # the list.
6004        my $upper = $list_ref->[$i+1] - 1;
6005        my $range = $upper - $base;
6006        $output .= '-' if $range > 1; # Adjacent characters don't have a
6007                                      # minus, though it would be legal to do
6008                                      # so
6009        $output .= pchr($upper) if $range > 0;
6010    }
6011
6012    print STDERR __LINE__, ": tr_invlist_to_string() returning '$output'\n"
6013                                                                       if DEBUG;
6014    return $output;
6015}
6016
6017my $unmapped = ~0;
6018my $special_handling = ~0 - 1;
6019
6020sub dump_invmap {
6021    my ($invlist_ref, $map_ref) = @_;
6022
6023    for my $i (0 .. @$invlist_ref - 1) {
6024        printf STDERR "[%d]\t%x\t", $i, $invlist_ref->[$i];
6025        my $map = $map_ref->[$i];
6026        if ($map == $unmapped) {
6027            print STDERR "TR_UNMAPPED\n";
6028        }
6029        elsif ($map == $special_handling) {
6030            print STDERR "TR_SPECIAL\n";
6031        }
6032        else {
6033            printf STDERR "%x\n", $map;
6034        }
6035    }
6036}
6037
6038sub tr_decode_utf8 {
6039    my($tr_av, $flags) = @_;
6040
6041    printf STDERR "\n%s: %d: flags=0x%x\n", __FILE__, __LINE__, $flags if DEBUG;
6042
6043    my $invlist = $tr_av->ARRAYelt(0);
6044    my @invlist = unpack("J*", $invlist->PV);
6045    my @map = unpack("J*", $tr_av->ARRAYelt(1)->PV);
6046
6047    dump_invmap(\@invlist, \@map) if DEBUG;
6048
6049    my @from;
6050    my @to;
6051
6052    # Go through the whole map
6053    for (my $i = 0; $i < @invlist; $i++) {
6054        my $map = $map[$i];
6055        printf STDERR "%d: i=%d, source=%x, map=%x\n",
6056                      __LINE__, $i, $invlist[$i], $map if DEBUG;
6057
6058        # Ignore any lines that are unmapped
6059        next if $map == $unmapped;
6060
6061        # Calculate this component of the mapping;  First the lhs
6062        my $this_from = $invlist[$i];
6063        my $next_from = $invlist[$i+1] if $i < @invlist - 1;
6064
6065        # The length of the rhs is the same as the lhs, except when special
6066        my $next_map = $map - $this_from + $next_from
6067                            if $map != $special_handling && defined $next_from;
6068
6069        if (DEBUG) {
6070            printf STDERR "%d: i=%d, from=%x, to=%x",
6071                          __LINE__, $i, $this_from, $map;
6072            printf STDERR ", next_from=%x,", $next_from if defined $next_from;
6073            printf STDERR ", next_map=%x", $next_map if defined $next_map;
6074            print  STDERR "\n";
6075        }
6076
6077        # Add the lhs.
6078        tr_append_to_invlist(\@from, $this_from, $next_from);
6079
6080        # And, the rhs; special handling doesn't get output as it really is an
6081        # unmatched rhs
6082        tr_append_to_invlist(\@to, $map, $next_map) if $map != $special_handling;
6083    }
6084
6085    # Done with the input.
6086
6087    my $to;
6088    if (join("", @from) eq join("", @to)) {
6089
6090        # the rhs is suppressed if identical to the left.  That's because
6091        # tr/ABC/ABC/ can be written as tr/ABC//.  (Do this comparison before
6092        # any complementing)
6093        $to = "";
6094    }
6095    else {
6096        $to = tr_invlist_to_string(\@to, 0);  # rhs not complemented
6097    }
6098
6099    my $from = tr_invlist_to_string(\@from,
6100                                   ($flags & OPpTRANS_COMPLEMENT) != 0);
6101
6102    print STDERR "Returning ", escape_str($from), "/",
6103                               escape_str($to), "\n" if DEBUG;
6104    return (escape_str($from), escape_str($to));
6105}
6106
6107sub pp_trans {
6108    my $self = shift;
6109    my($op, $cx, $morflags) = @_;
6110    my($from, $to);
6111    my $class = class($op);
6112    my $priv_flags = $op->private;
6113    if ($class eq "PVOP") {
6114	($from, $to) = tr_decode_byte($op->pv, $priv_flags);
6115    } elsif ($class eq "PADOP") {
6116	($from, $to)
6117	  = tr_decode_utf8($self->padval($op->padix), $priv_flags);
6118    } else { # class($op) eq "SVOP"
6119	($from, $to) = tr_decode_utf8($op->sv, $priv_flags);
6120    }
6121    my $flags = "";
6122    $flags .= "c" if $priv_flags & OPpTRANS_COMPLEMENT;
6123    $flags .= "d" if $priv_flags & OPpTRANS_DELETE;
6124    $to = "" if $from eq $to and $flags eq "";
6125    $flags .= "s" if $priv_flags & OPpTRANS_SQUASH;
6126    $flags .= $morflags if defined $morflags;
6127    my $ret = $self->keyword("tr") . double_delim($from, $to) . $flags;
6128    if (my $targ = $op->targ) {
6129	return $self->maybe_parens($self->padname($targ) . " =~ $ret",
6130				   $cx, 20);
6131    }
6132    return $ret;
6133}
6134
6135sub pp_transr { push @_, 'r'; goto &pp_trans }
6136
6137# Join two components of a double-quoted re, disambiguating
6138# "${foo}bar", "${foo}{bar}", "${foo}[1]".
6139
6140sub re_dq_disambiguate {
6141    my ($first, $last) = @_;
6142    ($last =~ /^[A-Z\\\^\[\]_?]/ &&
6143	$first =~ s/([\$@])\^$/${1}{^}/)  # "${^}W" etc
6144	|| ($last =~ /^[{\[\w_]/ &&
6145	    $first =~ s/([\$@])([A-Za-z_]\w*)$/${1}{$2}/);
6146    return $first . $last;
6147}
6148
6149# Like dq(), but different
6150sub re_dq {
6151    my $self = shift;
6152    my ($op) = @_;
6153
6154    my $type = $op->name;
6155    if ($type eq "const") {
6156	my $unbacked = re_unback($self->const_sv($op)->as_string);
6157	return re_uninterp(escape_re($unbacked));
6158    } elsif ($type eq "concat") {
6159	my $first = $self->re_dq($op->first);
6160	my $last  = $self->re_dq($op->last);
6161	return re_dq_disambiguate($first, $last);
6162    } elsif ($type eq "multiconcat") {
6163        return $self->do_multiconcat($op, 26, 2);
6164    } elsif ($type eq "uc") {
6165	return '\U' . $self->re_dq($op->first->sibling) . '\E';
6166    } elsif ($type eq "lc") {
6167	return '\L' . $self->re_dq($op->first->sibling) . '\E';
6168    } elsif ($type eq "ucfirst") {
6169	return '\u' . $self->re_dq($op->first->sibling);
6170    } elsif ($type eq "lcfirst") {
6171	return '\l' . $self->re_dq($op->first->sibling);
6172    } elsif ($type eq "quotemeta") {
6173	return '\Q' . $self->re_dq($op->first->sibling) . '\E';
6174    } elsif ($type eq "fc") {
6175	return '\F' . $self->re_dq($op->first->sibling) . '\E';
6176    } elsif ($type eq "join") {
6177	return $self->deparse($op->last, 26); # was join($", @ary)
6178    } else {
6179	my $ret = $self->deparse($op, 26);
6180	$ret =~ s/^\$([(|)])\z/\${$1}/ # $( $| $) need braces
6181	or $ret =~ s/^\@([-+])\z/\@{$1}/; # @- @+ need braces
6182	return $ret;
6183    }
6184}
6185
6186sub pure_string {
6187    my ($self, $op) = @_;
6188    return 0 if null $op;
6189    my $type = $op->name;
6190
6191    if ($type eq 'const' || $type eq 'av2arylen') {
6192	return 1;
6193    }
6194    elsif ($type =~ /^(?:[ul]c(first)?|fc)$/ || $type eq 'quotemeta') {
6195	return $self->pure_string($op->first->sibling);
6196    }
6197    elsif ($type eq 'join') {
6198	my $join_op = $op->first->sibling;  # Skip pushmark
6199	return 0 unless $join_op->name eq 'null' && $join_op->targ == OP_RV2SV;
6200
6201	my $gvop = $join_op->first;
6202	return 0 unless $gvop->name eq 'gvsv';
6203        return 0 unless '"' eq $self->gv_name($self->gv_or_padgv($gvop));
6204
6205	return 0 unless ${$join_op->sibling} eq ${$op->last};
6206	return 0 unless $op->last->name =~ /^(?:[ah]slice|(?:rv2|pad)av)$/;
6207    }
6208    elsif ($type eq 'concat') {
6209	return $self->pure_string($op->first)
6210            && $self->pure_string($op->last);
6211    }
6212    elsif ($type eq 'multiconcat') {
6213        my ($kid, @kids);
6214        for ($kid = $op->first; !null $kid; $kid = $kid->sibling) {
6215            # skip the consts and/or padsv we've optimised away
6216            push @kids, $kid
6217                unless $kid->type == OP_NULL
6218                  && (   $kid->targ == OP_PADSV
6219                      || $kid->targ == OP_CONST
6220                      || $kid->targ == OP_PUSHMARK);
6221        }
6222
6223        if ($op->flags & OPf_STACKED) {
6224            # remove expr from @kids where 'expr  = ...' or 'expr .= ....'
6225            if ($op->private & OPpMULTICONCAT_APPEND) {
6226                shift(@kids);
6227            }
6228            else {
6229                pop(@kids);
6230            }
6231        }
6232        for (@kids) {
6233            return 0 unless $self->pure_string($_);
6234        }
6235        return 1;
6236    }
6237    elsif (is_scalar($op) || $type =~ /^[ah]elem$/) {
6238	return 1;
6239    }
6240    elsif ($type eq "null" and $op->can('first') and not null $op->first) {
6241        my $first = $op->first;
6242
6243        return 1 if $first->name eq "multideref";
6244        return 1 if $first->name eq "aelemfast_lex";
6245
6246        if (    $first->name eq "null"
6247            and $first->can('first')
6248	    and not null $first->first
6249            and $first->first->name eq "aelemfast"
6250	   )
6251        {
6252            return 1;
6253        }
6254    }
6255
6256    return 0;
6257}
6258
6259sub code_list {
6260    my ($self,$op,$cv) = @_;
6261
6262    # localise stuff relating to the current sub
6263    $cv and
6264	local($self->{'curcv'}) = $cv,
6265	local($self->{'curcvlex'}),
6266	local(@$self{qw'curstash warnings hints hinthash curcop'})
6267	    = @$self{qw'curstash warnings hints hinthash curcop'};
6268
6269    my $re;
6270    for ($op = $op->first->sibling; !null($op); $op = $op->sibling) {
6271	if ($op->name eq 'null' and $op->flags & OPf_SPECIAL) {
6272	    my $scope = $op->first;
6273	    # 0 context (last arg to scopeop) means statement context, so
6274	    # the contents of the block will not be wrapped in do{...}.
6275	    my $block = scopeop($scope->first->name eq "enter", $self,
6276				$scope, 0);
6277	    # next op is the source code of the block
6278	    $op = $op->sibling;
6279	    $re .= ($self->const_sv($op)->PV =~ m|^(\(\?\??\{)|)[0];
6280	    my $multiline = $block =~ /\n/;
6281	    $re .= $multiline ? "\n\t" : ' ';
6282	    $re .= $block;
6283	    $re .= $multiline ? "\n\b})" : " })";
6284	} else {
6285	    $re = re_dq_disambiguate($re, $self->re_dq($op));
6286	}
6287    }
6288    $re;
6289}
6290
6291sub regcomp {
6292    my $self = shift;
6293    my($op, $cx) = @_;
6294    my $kid = $op->first;
6295    $kid = $kid->first if $kid->name eq "regcmaybe";
6296    $kid = $kid->first if $kid->name eq "regcreset";
6297    my $kname = $kid->name;
6298    if ($kname eq "null" and !null($kid->first)
6299	and $kid->first->name eq 'pushmark')
6300    {
6301	my $str = '';
6302	$kid = $kid->first->sibling;
6303	while (!null($kid)) {
6304	    my $first = $str;
6305	    my $last = $self->re_dq($kid);
6306	    $str = re_dq_disambiguate($first, $last);
6307	    $kid = $kid->sibling;
6308	}
6309	return $str, 1;
6310    }
6311
6312    return ($self->re_dq($kid), 1)
6313	if $kname =~ /^(?:rv2|pad)av/ or $self->pure_string($kid);
6314    return ($self->deparse($kid, $cx), 0);
6315}
6316
6317sub pp_regcomp {
6318    my ($self, $op, $cx) = @_;
6319    return (($self->regcomp($op, $cx, 0))[0]);
6320}
6321
6322sub re_flags {
6323    my ($self, $op) = @_;
6324    my $flags = '';
6325    my $pmflags = $op->pmflags;
6326    if (!$pmflags) {
6327	my $re = $op->pmregexp;
6328	if ($$re) {
6329	    $pmflags = $re->compflags;
6330	}
6331    }
6332    $flags .= "g" if $pmflags & PMf_GLOBAL;
6333    $flags .= "i" if $pmflags & PMf_FOLD;
6334    $flags .= "m" if $pmflags & PMf_MULTILINE;
6335    $flags .= "o" if $pmflags & PMf_KEEP;
6336    $flags .= "s" if $pmflags & PMf_SINGLELINE;
6337    $flags .= "x" if $pmflags & PMf_EXTENDED;
6338    $flags .= "x" if $pmflags & PMf_EXTENDED_MORE;
6339    $flags .= "p" if $pmflags & PMf_KEEPCOPY;
6340    $flags .= "n" if $pmflags & PMf_NOCAPTURE;
6341    if (my $charset = $pmflags & PMf_CHARSET) {
6342	# Hardcoding this is fragile, but B does not yet export the
6343	# constants we need.
6344	$flags .= qw(d l u a aa)[$charset >> 7]
6345    }
6346    # The /d flag is indicated by 0; only show it if necessary.
6347    elsif ($self->{hinthash} and
6348	     $self->{hinthash}{reflags_charset}
6349	    || $self->{hinthash}{feature_unicode}
6350	or $self->{hints} & $feature::hint_mask
6351	  && ($self->{hints} & $feature::hint_mask)
6352	       != $feature::hint_mask
6353	  && $self->{hints} & $feature::hint_uni8bit
6354    ) {
6355	$flags .= 'd';
6356    }
6357    $flags;
6358}
6359
6360# osmic acid -- see osmium tetroxide
6361
6362my %matchwords;
6363map($matchwords{join "", sort split //, $_} = $_, 'cig', 'cog', 'cos', 'cogs',
6364    'cox', 'go', 'is', 'ism', 'iso', 'mig', 'mix', 'osmic', 'ox', 'sic',
6365    'sig', 'six', 'smog', 'so', 'soc', 'sog', 'xi', 'soup', 'soupmix');
6366
6367# When deparsing a regular expression with code blocks, we have to look in
6368# various places to find the blocks.
6369#
6370# For qr/(?{...})/ without interpolation, the CV is under $qr->qr_anoncv
6371# and the code list (list of blocks and constants, maybe vars) is under
6372# $cv->ROOT->first->code_list:
6373#   ./perl -Ilib -MB -e 'use O "Concise", B::svref_2object(sub {qr/(?{die})/})->ROOT->first->first->sibling->pmregexp->qr_anoncv->object_2svref'
6374#
6375# For qr/$a(?{...})/ with interpolation, the code list is more accessible,
6376# under $pmop->code_list, but the $cv is something you have to dig for in
6377# the regcomp op’s kids:
6378#   ./perl -Ilib -mO=Concise -e 'qr/$a(?{die})/'
6379#
6380# For m// and split //, things are much simpler.  There is no CV.  The code
6381# list is under $pmop->code_list.
6382
6383sub matchop {
6384    my $self = shift;
6385    my($op, $cx, $name, $delim) = @_;
6386    my $kid = $op->first;
6387    my ($binop, $var, $re) = ("", "", "");
6388    if ($op->name ne 'split' && $op->flags & OPf_STACKED) {
6389	$binop = 1;
6390	$var = $self->deparse($kid, 20);
6391	$kid = $kid->sibling;
6392    }
6393           # not $name; $name will be 'm' for both match and split
6394    elsif ($op->name eq 'match' and my $targ = $op->targ) {
6395	$binop = 1;
6396	$var = $self->padname($targ);
6397    }
6398    my $quote = 1;
6399    my $pmflags = $op->pmflags;
6400    my $rhs_bound_to_defsv;
6401    my ($cv, $bregexp);
6402    my $have_kid = !null $kid;
6403    # Check for code blocks first
6404    if (not null my $code_list = $op->code_list) {
6405	$re = $self->code_list($code_list,
6406			       $op->name eq 'qr'
6407				   ? $self->padval(
6408				         $kid->first   # ex-list
6409					     ->first   #   pushmark
6410					     ->sibling #   entersub
6411					     ->first   #     ex-list
6412					     ->first   #       pushmark
6413					     ->sibling #       anoncode
6414					     ->targ
6415				     )
6416				   : undef);
6417    } elsif (${$bregexp = $op->pmregexp} && ${$cv = $bregexp->qr_anoncv}) {
6418	my $patop = $cv->ROOT      # leavesub
6419		       ->first     #   qr
6420		       ->code_list;#     list
6421	$re = $self->code_list($patop, $cv);
6422    } elsif (!$have_kid) {
6423	$re = re_uninterp(escape_re(re_unback($op->precomp)));
6424    } elsif ($kid->name ne 'regcomp') {
6425        if ($op->name eq 'split') {
6426            # split has other kids, not just regcomp
6427            $re = re_uninterp(escape_re(re_unback($op->precomp)));
6428        }
6429        else {
6430            carp("found ".$kid->name." where regcomp expected");
6431        }
6432    } else {
6433	($re, $quote) = $self->regcomp($kid, 21);
6434    }
6435    if ($have_kid and $kid->name eq 'regcomp') {
6436	my $matchop = $kid->first;
6437	if ($matchop->name eq 'regcreset') {
6438	    $matchop = $matchop->first;
6439	}
6440	if ($matchop->name =~ /^(?:match|transr?|subst)\z/
6441	   && $matchop->flags & OPf_SPECIAL) {
6442	    $rhs_bound_to_defsv = 1;
6443	}
6444    }
6445    my $flags = "";
6446    $flags .= "c" if $pmflags & PMf_CONTINUE;
6447    $flags .= $self->re_flags($op);
6448    $flags = join '', sort split //, $flags;
6449    $flags = $matchwords{$flags} if $matchwords{$flags};
6450    if ($pmflags & PMf_ONCE) { # only one kind of delimiter works here
6451	$re =~ s/\?/\\?/g;
6452	$re = $self->keyword("m") . "?$re?";     # explicit 'm' is required
6453    } elsif ($quote) {
6454	$re = single_delim($name, $delim, $re, $self);
6455    }
6456    $re = $re . $flags if $quote;
6457    if ($binop) {
6458	return
6459	 $self->maybe_parens(
6460	  $rhs_bound_to_defsv
6461	   ? "$var =~ (\$_ =~ $re)"
6462	   : "$var =~ $re",
6463	  $cx, 20
6464	 );
6465    } else {
6466	return $re;
6467    }
6468}
6469
6470sub pp_match { matchop(@_, "m", "/") }
6471sub pp_qr { matchop(@_, "qr", "") }
6472
6473sub pp_runcv { unop(@_, "__SUB__"); }
6474
6475sub pp_split {
6476    my $self = shift;
6477    my($op, $cx) = @_;
6478    my($kid, @exprs, $ary, $expr);
6479    my $stacked = $op->flags & OPf_STACKED;
6480
6481    $kid = $op->first;
6482    $kid = $kid->sibling if $kid->name eq 'regcomp';
6483    for (; !null($kid); $kid = $kid->sibling) {
6484	push @exprs, $self->deparse($kid, 6);
6485    }
6486
6487    unshift @exprs, $self->matchop($op, $cx, "m", "/");
6488
6489    if ($op->private & OPpSPLIT_ASSIGN) {
6490        # With C<@array = split(/pat/, str);>,
6491        #  array is stored in split's pmreplroot; either
6492        # as an integer index into the pad (for a lexical array)
6493        # or as GV for a package array (which will be a pad index
6494        # on threaded builds)
6495        # With my/our @array = split(/pat/, str), the array is instead
6496        # accessed via an extra padav/rv2av op at the end of the
6497        # split's kid ops.
6498
6499        if ($stacked) {
6500            $ary = pop @exprs;
6501        }
6502        else {
6503            if ($op->private & OPpSPLIT_LEX) {
6504                $ary = $self->padname($op->pmreplroot);
6505            }
6506            else {
6507                # union with op_pmtargetoff, op_pmtargetgv
6508                my $gv = $op->pmreplroot;
6509                $gv = $self->padval($gv) if !ref($gv);
6510                $ary = $self->maybe_local(@_,
6511			      $self->stash_variable('@',
6512						     $self->gv_name($gv),
6513						     $cx))
6514            }
6515            if ($op->private & OPpLVAL_INTRO) {
6516                $ary = $op->private & OPpSPLIT_LEX ? "my $ary" : "local $ary";
6517            }
6518        }
6519    }
6520
6521    # handle special case of split(), and split(' ') that compiles to /\s+/
6522    $exprs[0] = q{' '} if ($op->reflags // 0) & RXf_SKIPWHITE();
6523
6524    $expr = "split(" . join(", ", @exprs) . ")";
6525    if ($ary) {
6526	return $self->maybe_parens("$ary = $expr", $cx, 7);
6527    } else {
6528	return $expr;
6529    }
6530}
6531
6532# oxime -- any of various compounds obtained chiefly by the action of
6533# hydroxylamine on aldehydes and ketones and characterized by the
6534# bivalent grouping C=NOH [Webster's Tenth]
6535
6536my %substwords;
6537map($substwords{join "", sort split //, $_} = $_, 'ego', 'egoism', 'em',
6538    'es', 'ex', 'exes', 'gee', 'go', 'goes', 'ie', 'ism', 'iso', 'me',
6539    'meese', 'meso', 'mig', 'mix', 'os', 'ox', 'oxime', 'see', 'seem',
6540    'seg', 'sex', 'sig', 'six', 'smog', 'sog', 'some', 'xi', 'rogue',
6541    'sir', 'rise', 'smore', 'more', 'seer', 'rome', 'gore', 'grim', 'grime',
6542    'or', 'rose', 'rosie');
6543
6544sub pp_subst {
6545    my $self = shift;
6546    my($op, $cx) = @_;
6547    my $kid = $op->first;
6548    my($binop, $var, $re, $repl) = ("", "", "", "");
6549    if ($op->flags & OPf_STACKED) {
6550	$binop = 1;
6551	$var = $self->deparse($kid, 20);
6552	$kid = $kid->sibling;
6553    }
6554    elsif (my $targ = $op->targ) {
6555	$binop = 1;
6556	$var = $self->padname($targ);
6557    }
6558    my $flags = "";
6559    my $pmflags = $op->pmflags;
6560    if (null($op->pmreplroot)) {
6561	$repl = $kid;
6562	$kid = $kid->sibling;
6563    } else {
6564	$repl = $op->pmreplroot->first; # skip substcont
6565    }
6566    while ($repl->name eq "entereval") {
6567	    $repl = $repl->first;
6568	    $flags .= "e";
6569    }
6570    {
6571	local $self->{in_subst_repl} = 1;
6572	if ($pmflags & PMf_EVAL) {
6573	    $repl = $self->deparse($repl->first, 0);
6574	} else {
6575	    $repl = $self->dq($repl);
6576	}
6577    }
6578    if (not null my $code_list = $op->code_list) {
6579	$re = $self->code_list($code_list);
6580    } elsif (null $kid) {
6581	$re = re_uninterp(escape_re(re_unback($op->precomp)));
6582    } else {
6583	($re) = $self->regcomp($kid, 1);
6584    }
6585    $flags .= "r" if $pmflags & PMf_NONDESTRUCT;
6586    $flags .= "e" if $pmflags & PMf_EVAL;
6587    $flags .= $self->re_flags($op);
6588    $flags = join '', sort split //, $flags;
6589    $flags = $substwords{$flags} if $substwords{$flags};
6590    my $core_s = $self->keyword("s"); # maybe CORE::s
6591    if ($binop) {
6592	return $self->maybe_parens("$var =~ $core_s"
6593				   . double_delim($re, $repl) . $flags,
6594				   $cx, 20);
6595    } else {
6596	return "$core_s". double_delim($re, $repl) . $flags;
6597    }
6598}
6599
6600sub is_lexical_subs {
6601    my (@ops) = shift;
6602    for my $op (@ops) {
6603        return 0 if $op->name !~ /\A(?:introcv|clonecv)\z/;
6604    }
6605    return 1;
6606}
6607
6608# Pretend these two ops do not exist.  The perl parser adds them to the
6609# beginning of any block containing my-sub declarations, whereas we handle
6610# the subs in pad_subs and next_todo.
6611*pp_clonecv = *pp_introcv;
6612sub pp_introcv {
6613    my $self = shift;
6614    my($op, $cx) = @_;
6615    # For now, deparsing doesn't worry about the distinction between introcv
6616    # and clonecv, so pretend this op doesn't exist:
6617    return '';
6618}
6619
6620sub pp_padcv {
6621    my $self = shift;
6622    my($op, $cx) = @_;
6623    return $self->padany($op);
6624}
6625
6626my %lvref_funnies = (
6627    OPpLVREF_SV, => '$',
6628    OPpLVREF_AV, => '@',
6629    OPpLVREF_HV, => '%',
6630    OPpLVREF_CV, => '&',
6631);
6632
6633sub pp_refassign {
6634    my ($self, $op, $cx) = @_;
6635    my $left;
6636    if ($op->private & OPpLVREF_ELEM) {
6637	$left = $op->first->sibling;
6638	$left = maybe_local(@_, elem($self, $left, undef,
6639				     $left->targ == OP_AELEM
6640					? qw([ ] padav)
6641					: qw({ } padhv)));
6642    } elsif ($op->flags & OPf_STACKED) {
6643	$left = maybe_local(@_,
6644			    $lvref_funnies{$op->private & OPpLVREF_TYPE}
6645			  . $self->deparse($op->first->sibling));
6646    } else {
6647	$left = &pp_padsv;
6648    }
6649    my $right = $self->deparse_binop_right($op, $op->first, 7);
6650    return $self->maybe_parens("\\$left = $right", $cx, 7);
6651}
6652
6653sub pp_lvref {
6654    my ($self, $op, $cx) = @_;
6655    my $code;
6656    if ($op->private & OPpLVREF_ELEM) {
6657	$code = $op->first->name =~ /av\z/ ? &pp_aelem : &pp_helem;
6658    } elsif ($op->flags & OPf_STACKED) {
6659	$code = maybe_local(@_,
6660			    $lvref_funnies{$op->private & OPpLVREF_TYPE}
6661			  . $self->deparse($op->first));
6662    } else {
6663	$code = &pp_padsv;
6664    }
6665    "\\$code";
6666}
6667
6668sub pp_lvrefslice {
6669    my ($self, $op, $cx) = @_;
6670    '\\' . ($op->last->name =~ /av\z/ ? &pp_aslice : &pp_hslice);
6671}
6672
6673sub pp_lvavref {
6674    my ($self, $op, $cx) = @_;
6675    '\\(' . ($op->flags & OPf_STACKED
6676		? maybe_local(@_, rv2x(@_, "\@"))
6677		: &pp_padsv)  . ')'
6678}
6679
6680
6681sub pp_argcheck {
6682    my $self = shift;
6683    my($op, $cx) = @_;
6684    my ($params, $opt_params, $slurpy) = $op->aux_list($self->{curcv});
6685    my $mandatory = $params - $opt_params;
6686    my $check = '';
6687
6688    $check .= <<EOF if !$slurpy;
6689die sprintf("Too many arguments for subroutine at %s line %d.\\n", (caller)[1, 2]) unless \@_ <= $params;
6690EOF
6691
6692    $check .= <<EOF if $mandatory > 0;
6693die sprintf("Too few arguments for subroutine at %s line %d.\\n", (caller)[1, 2]) unless \@_ >= $mandatory;
6694EOF
6695
6696    my $cond = ($params & 1) ? 'unless' : 'if';
6697    $check .= <<EOF if $slurpy eq '%';
6698die sprintf("Odd name/value argument for subroutine at %s line %d.\\n", (caller)[1, 2]) if \@_ > $params && ((\@_ - $params) & 1);
6699EOF
6700
6701    $check =~ s/;\n\z//;
6702    return $check;
6703}
6704
6705
6706sub pp_argelem {
6707    my $self = shift;
6708    my($op, $cx) = @_;
6709    my $var = $self->padname($op->targ);
6710    my $ix  = $op->string($self->{curcv});
6711    my $expr;
6712    if ($op->flags & OPf_KIDS) {
6713        $expr = $self->deparse($op->first, 7);
6714    }
6715    elsif ($var =~ /^[@%]/) {
6716        $expr = $ix ? "\@_[$ix .. \$#_]" : '@_';
6717    }
6718    else {
6719        $expr = "\$_[$ix]";
6720    }
6721    return "my $var = $expr";
6722}
6723
6724
6725sub pp_argdefelem {
6726    my $self = shift;
6727    my($op, $cx) = @_;
6728    my $ix  = $op->targ;
6729    my $expr = "\@_ >= " . ($ix+1) . " ? \$_[$ix] : ";
6730    my $def = $self->deparse($op->first, 7);
6731    $def = "($def)" if $op->first->flags & OPf_PARENS;
6732    $expr .= $self->deparse($op->first, $cx);
6733    return $expr;
6734}
6735
6736
6737sub pp_pushdefer {
6738    my $self = shift;
6739    my($op, $cx) = @_;
6740    # defer block body is stored in the ->first of an OP_NULL that is
6741    # ->first of OP_PUSHDEFER
6742    my $body = $self->deparse($op->first->first);
6743    return "defer {\n\t$body\n\b}\cK";
6744}
6745
6746sub builtin1 {
6747    my $self = shift;
6748    my ($op, $cx, $name) = @_;
6749    my $arg = $self->deparse($op->first);
6750    # TODO: work out if lexical alias is present somehow...
6751    return "builtin::$name($arg)";
6752}
6753
6754sub pp_is_bool    { builtin1(@_, "is_bool"); }
6755sub pp_is_weak    { builtin1(@_, "is_weak"); }
6756sub pp_weaken     { builtin1(@_, "weaken"); }
6757sub pp_unweaken   { builtin1(@_, "unweaken"); }
6758sub pp_blessed    { builtin1(@_, "blessed"); }
6759sub pp_refaddr    { $_[0]->maybe_targmy(@_[1,2], \&builtin1, "refaddr"); }
6760sub pp_reftype    { $_[0]->maybe_targmy(@_[1,2], \&builtin1, "reftype"); }
6761sub pp_ceil       { $_[0]->maybe_targmy(@_[1,2], \&builtin1, "ceil"); }
6762sub pp_floor      { $_[0]->maybe_targmy(@_[1,2], \&builtin1, "floor"); }
6763sub pp_is_tainted { builtin1(@_, "is_tainted"); }
6764
67651;
6766__END__
6767
6768=head1 NAME
6769
6770B::Deparse - Perl compiler backend to produce perl code
6771
6772=head1 SYNOPSIS
6773
6774B<perl> B<-MO=Deparse>[B<,-d>][B<,-f>I<FILE>][B<,-p>][B<,-q>][B<,-l>]
6775        [B<,-s>I<LETTERS>][B<,-x>I<LEVEL>] I<prog.pl>
6776
6777=head1 DESCRIPTION
6778
6779B::Deparse is a backend module for the Perl compiler that generates
6780perl source code, based on the internal compiled structure that perl
6781itself creates after parsing a program.  The output of B::Deparse won't
6782be exactly the same as the original source, since perl doesn't keep
6783track of comments or whitespace, and there isn't a one-to-one
6784correspondence between perl's syntactical constructions and their
6785compiled form, but it will often be close.  When you use the B<-p>
6786option, the output also includes parentheses even when they are not
6787required by precedence, which can make it easy to see if perl is
6788parsing your expressions the way you intended.
6789
6790While B::Deparse goes to some lengths to try to figure out what your
6791original program was doing, some parts of the language can still trip
6792it up; it still fails even on some parts of Perl's own test suite.  If
6793you encounter a failure other than the most common ones described in
6794the BUGS section below, you can help contribute to B::Deparse's
6795ongoing development by submitting a bug report with a small
6796example.
6797
6798=head1 OPTIONS
6799
6800As with all compiler backend options, these must follow directly after
6801the '-MO=Deparse', separated by a comma but not any white space.
6802
6803=over 4
6804
6805=item B<-d>
6806
6807Output data values (when they appear as constants) using Data::Dumper.
6808Without this option, B::Deparse will use some simple routines of its
6809own for the same purpose.  Currently, Data::Dumper is better for some
6810kinds of data (such as complex structures with sharing and
6811self-reference) while the built-in routines are better for others
6812(such as odd floating-point values).
6813
6814=item B<-f>I<FILE>
6815
6816Normally, B::Deparse deparses the main code of a program, and all the subs
6817defined in the same file.  To include subs defined in
6818other files, pass the B<-f> option with the filename.
6819You can pass the B<-f> option several times, to
6820include more than one secondary file.  (Most of the time you don't want to
6821use it at all.)  You can also use this option to include subs which are
6822defined in the scope of a B<#line> directive with two parameters.
6823
6824=item B<-l>
6825
6826Add '#line' declarations to the output based on the line and file
6827locations of the original code.
6828
6829=item B<-p>
6830
6831Print extra parentheses.  Without this option, B::Deparse includes
6832parentheses in its output only when they are needed, based on the
6833structure of your program.  With B<-p>, it uses parentheses (almost)
6834whenever they would be legal.  This can be useful if you are used to
6835LISP, or if you want to see how perl parses your input.  If you say
6836
6837    if ($var & 0x7f == 65) {print "Gimme an A!"}
6838    print ($which ? $a : $b), "\n";
6839    $name = $ENV{USER} or "Bob";
6840
6841C<B::Deparse,-p> will print
6842
6843    if (($var & 0)) {
6844        print('Gimme an A!')
6845    };
6846    (print(($which ? $a : $b)), '???');
6847    (($name = $ENV{'USER'}) or '???')
6848
6849which probably isn't what you intended (the C<'???'> is a sign that
6850perl optimized away a constant value).
6851
6852=item B<-P>
6853
6854Disable prototype checking.  With this option, all function calls are
6855deparsed as if no prototype was defined for them.  In other words,
6856
6857    perl -MO=Deparse,-P -e 'sub foo (\@) { 1 } foo @x'
6858
6859will print
6860
6861    sub foo (\@) {
6862	1;
6863    }
6864    &foo(\@x);
6865
6866making clear how the parameters are actually passed to C<foo>.
6867
6868=item B<-q>
6869
6870Expand double-quoted strings into the corresponding combinations of
6871concatenation, uc, ucfirst, lc, lcfirst, quotemeta, and join.  For
6872instance, print
6873
6874    print "Hello, $world, @ladies, \u$gentlemen\E, \u\L$me!";
6875
6876as
6877
6878    print 'Hello, ' . $world . ', ' . join($", @ladies) . ', '
6879          . ucfirst($gentlemen) . ', ' . ucfirst(lc $me . '!');
6880
6881Note that the expanded form represents the way perl handles such
6882constructions internally -- this option actually turns off the reverse
6883translation that B::Deparse usually does.  On the other hand, note that
6884C<$x = "$y"> is not the same as C<$x = $y>: the former makes the value
6885of $y into a string before doing the assignment.
6886
6887=item B<-s>I<LETTERS>
6888
6889Tweak the style of B::Deparse's output.  The letters should follow
6890directly after the 's', with no space or punctuation.  The following
6891options are available:
6892
6893=over 4
6894
6895=item B<C>
6896
6897Cuddle C<elsif>, C<else>, and C<continue> blocks.  For example, print
6898
6899    if (...) {
6900         ...
6901    } else {
6902         ...
6903    }
6904
6905instead of
6906
6907    if (...) {
6908         ...
6909    }
6910    else {
6911         ...
6912    }
6913
6914The default is not to cuddle.
6915
6916=item B<i>I<NUMBER>
6917
6918Indent lines by multiples of I<NUMBER> columns.  The default is 4 columns.
6919
6920=item B<T>
6921
6922Use tabs for each 8 columns of indent.  The default is to use only spaces.
6923For instance, if the style options are B<-si4T>, a line that's indented
69243 times will be preceded by one tab and four spaces; if the options were
6925B<-si8T>, the same line would be preceded by three tabs.
6926
6927=item B<v>I<STRING>B<.>
6928
6929Print I<STRING> for the value of a constant that can't be determined
6930because it was optimized away (mnemonic: this happens when a constant
6931is used in B<v>oid context).  The end of the string is marked by a period.
6932The string should be a valid perl expression, generally a constant.
6933Note that unless it's a number, it probably needs to be quoted, and on
6934a command line quotes need to be protected from the shell.  Some
6935conventional values include 0, 1, 42, '', 'foo', and
6936'Useless use of constant omitted' (which may need to be
6937B<-sv"'Useless use of constant omitted'.">
6938or something similar depending on your shell).  The default is '???'.
6939If you're using B::Deparse on a module or other file that's require'd,
6940you shouldn't use a value that evaluates to false, since the customary
6941true constant at the end of a module will be in void context when the
6942file is compiled as a main program.
6943
6944=back
6945
6946=item B<-x>I<LEVEL>
6947
6948Expand conventional syntax constructions into equivalent ones that expose
6949their internal operation.  I<LEVEL> should be a digit, with higher values
6950meaning more expansion.  As with B<-q>, this actually involves turning off
6951special cases in B::Deparse's normal operations.
6952
6953If I<LEVEL> is at least 3, C<for> loops will be translated into equivalent
6954while loops with continue blocks; for instance
6955
6956    for ($i = 0; $i < 10; ++$i) {
6957        print $i;
6958    }
6959
6960turns into
6961
6962    $i = 0;
6963    while ($i < 10) {
6964        print $i;
6965    } continue {
6966        ++$i
6967    }
6968
6969Note that in a few cases this translation can't be perfectly carried back
6970into the source code -- if the loop's initializer declares a my variable,
6971for instance, it won't have the correct scope outside of the loop.
6972
6973If I<LEVEL> is at least 5, C<use> declarations will be translated into
6974C<BEGIN> blocks containing calls to C<require> and C<import>; for
6975instance,
6976
6977    use strict 'refs';
6978
6979turns into
6980
6981    sub BEGIN {
6982        require strict;
6983        do {
6984            'strict'->import('refs')
6985        };
6986    }
6987
6988If I<LEVEL> is at least 7, C<if> statements will be translated into
6989equivalent expressions using C<&&>, C<?:> and C<do {}>; for instance
6990
6991    print 'hi' if $nice;
6992    if ($nice) {
6993        print 'hi';
6994    }
6995    if ($nice) {
6996        print 'hi';
6997    } else {
6998        print 'bye';
6999    }
7000
7001turns into
7002
7003    $nice and print 'hi';
7004    $nice and do { print 'hi' };
7005    $nice ? do { print 'hi' } : do { print 'bye' };
7006
7007Long sequences of elsifs will turn into nested ternary operators, which
7008B::Deparse doesn't know how to indent nicely.
7009
7010=back
7011
7012=head1 USING B::Deparse AS A MODULE
7013
7014=head2 Synopsis
7015
7016    use B::Deparse;
7017    $deparse = B::Deparse->new("-p", "-sC");
7018    $body = $deparse->coderef2text(\&func);
7019    eval "sub func $body"; # the inverse operation
7020
7021=head2 Description
7022
7023B::Deparse can also be used on a sub-by-sub basis from other perl
7024programs.
7025
7026=head2 new
7027
7028    $deparse = B::Deparse->new(OPTIONS)
7029
7030Create an object to store the state of a deparsing operation and any
7031options.  The options are the same as those that can be given on the
7032command line (see L</OPTIONS>); options that are separated by commas
7033after B<-MO=Deparse> should be given as separate strings.
7034
7035=head2 ambient_pragmas
7036
7037    $deparse->ambient_pragmas(strict => 'all', '$[' => $[);
7038
7039The compilation of a subroutine can be affected by a few compiler
7040directives, B<pragmas>.  These are:
7041
7042=over 4
7043
7044=item *
7045
7046use strict;
7047
7048=item *
7049
7050use warnings;
7051
7052=item *
7053
7054Assigning to the special variable $[
7055
7056=item *
7057
7058use integer;
7059
7060=item *
7061
7062use bytes;
7063
7064=item *
7065
7066use utf8;
7067
7068=item *
7069
7070use re;
7071
7072=back
7073
7074Ordinarily, if you use B::Deparse on a subroutine which has
7075been compiled in the presence of one or more of these pragmas,
7076the output will include statements to turn on the appropriate
7077directives.  So if you then compile the code returned by coderef2text,
7078it will behave the same way as the subroutine which you deparsed.
7079
7080However, you may know that you intend to use the results in a
7081particular context, where some pragmas are already in scope.  In
7082this case, you use the B<ambient_pragmas> method to describe the
7083assumptions you wish to make.
7084
7085Not all of the options currently have any useful effect.  See
7086L</BUGS> for more details.
7087
7088The parameters it accepts are:
7089
7090=over 4
7091
7092=item strict
7093
7094Takes a string, possibly containing several values separated
7095by whitespace.  The special values "all" and "none" mean what you'd
7096expect.
7097
7098    $deparse->ambient_pragmas(strict => 'subs refs');
7099
7100=item $[
7101
7102Takes a number, the value of the array base $[.
7103Obsolete: cannot be non-zero.
7104
7105=item bytes
7106
7107=item utf8
7108
7109=item integer
7110
7111If the value is true, then the appropriate pragma is assumed to
7112be in the ambient scope, otherwise not.
7113
7114=item re
7115
7116Takes a string, possibly containing a whitespace-separated list of
7117values.  The values "all" and "none" are special.  It's also permissible
7118to pass an array reference here.
7119
7120    $deparser->ambient_pragmas(re => 'eval');
7121
7122
7123=item warnings
7124
7125Takes a string, possibly containing a whitespace-separated list of
7126values.  The values "all" and "none" are special, again.  It's also
7127permissible to pass an array reference here.
7128
7129    $deparser->ambient_pragmas(warnings => [qw[void io]]);
7130
7131If one of the values is the string "FATAL", then all the warnings
7132in that list will be considered fatal, just as with the B<warnings>
7133pragma itself.  Should you need to specify that some warnings are
7134fatal, and others are merely enabled, you can pass the B<warnings>
7135parameter twice:
7136
7137    $deparser->ambient_pragmas(
7138	warnings => 'all',
7139	warnings => [FATAL => qw/void io/],
7140    );
7141
7142See L<warnings> for more information about lexical warnings.
7143
7144=item hint_bits
7145
7146=item warning_bits
7147
7148These two parameters are used to specify the ambient pragmas in
7149the format used by the special variables $^H and ${^WARNING_BITS}.
7150
7151They exist principally so that you can write code like:
7152
7153    { my ($hint_bits, $warning_bits);
7154    BEGIN {($hint_bits, $warning_bits) = ($^H, ${^WARNING_BITS})}
7155    $deparser->ambient_pragmas (
7156	hint_bits    => $hint_bits,
7157	warning_bits => $warning_bits,
7158	'$['         => 0 + $[
7159    ); }
7160
7161which specifies that the ambient pragmas are exactly those which
7162are in scope at the point of calling.
7163
7164=item %^H
7165
7166This parameter is used to specify the ambient pragmas which are
7167stored in the special hash %^H.
7168
7169=back
7170
7171=head2 coderef2text
7172
7173    $body = $deparse->coderef2text(\&func)
7174    $body = $deparse->coderef2text(sub ($$) { ... })
7175
7176Return source code for the body of a subroutine (a block, optionally
7177preceded by a prototype in parens), given a reference to the
7178sub.  Because a subroutine can have no names, or more than one name,
7179this method doesn't return a complete subroutine definition -- if you
7180want to eval the result, you should prepend "sub subname ", or "sub "
7181for an anonymous function constructor.  Unless the sub was defined in
7182the main:: package, the code will include a package declaration.
7183
7184=head1 BUGS
7185
7186=over 4
7187
7188=item *
7189
7190The only pragmas to
7191be completely supported are: C<use warnings>,
7192C<use strict>, C<use bytes>, C<use integer>
7193and C<use feature>.
7194
7195Excepting those listed above, we're currently unable to guarantee that
7196B::Deparse will produce a pragma at the correct point in the program.
7197(Specifically, pragmas at the beginning of a block often appear right
7198before the start of the block instead.)
7199Since the effects of pragmas are often lexically scoped, this can mean
7200that the pragma holds sway over a different portion of the program
7201than in the input file.
7202
7203=item *
7204
7205In fact, the above is a specific instance of a more general problem:
7206we can't guarantee to produce BEGIN blocks or C<use> declarations in
7207exactly the right place.  So if you use a module which affects compilation
7208(such as by over-riding keywords, overloading constants or whatever)
7209then the output code might not work as intended.
7210
7211=item *
7212
7213Some constants don't print correctly either with or without B<-d>.
7214For instance, neither B::Deparse nor Data::Dumper know how to print
7215dual-valued scalars correctly, as in:
7216
7217    use constant E2BIG => ($!=7); $y = E2BIG; print $y, 0+$y;
7218
7219    use constant H => { "#" => 1 }; H->{"#"};
7220
7221=item *
7222
7223An input file that uses source filtering probably won't be deparsed into
7224runnable code, because it will still include the B<use> declaration
7225for the source filtering module, even though the code that is
7226produced is already ordinary Perl which shouldn't be filtered again.
7227
7228=item *
7229
7230Optimized-away statements are rendered as
7231'???'.  This includes statements that
7232have a compile-time side-effect, such as the obscure
7233
7234    my $x if 0;
7235
7236which is not, consequently, deparsed correctly.
7237
7238    foreach my $i (@_) { 0 }
7239  =>
7240    foreach my $i (@_) { '???' }
7241
7242=item *
7243
7244Lexical (my) variables declared in scopes external to a subroutine
7245appear in coderef2text output text as package variables.  This is a tricky
7246problem, as perl has no native facility for referring to a lexical variable
7247defined within a different scope, although L<PadWalker> is a good start.
7248
7249See also L<Data::Dump::Streamer>, which combines B::Deparse and
7250L<PadWalker> to serialize closures properly.
7251
7252=item *
7253
7254There are probably many more bugs on non-ASCII platforms (EBCDIC).
7255
7256=back
7257
7258=head1 AUTHOR
7259
7260Stephen McCamant <smcc@CSUA.Berkeley.EDU>, based on an earlier version
7261by Malcolm Beattie <mbeattie@sable.ox.ac.uk>, with contributions from
7262Gisle Aas, James Duncan, Albert Dvornik, Robin Houston, Dave Mitchell,
7263Hugo van der Sanden, Gurusamy Sarathy, Nick Ing-Simmons, and Rafael
7264Garcia-Suarez.
7265
7266=cut
7267