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