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