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