This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [PATCH] Fix cwd.t when libpth contains symlinks
[perl5.git] / ext / B / B / Deparse.pm
CommitLineData
6e90668e 1# B::Deparse.pm
6f611a1a 2# Copyright (c) 1998, 1999, 2000 Stephen McCamant. All rights reserved.
6e90668e
SM
3# This module is free software; you can redistribute and/or modify
4# it under the same terms as Perl itself.
5
6# This is based on the module of the same name by Malcolm Beattie,
7# but essentially none of his code remains.
8
a798dbf2 9package B::Deparse;
f4a44678 10use Carp 'cluck', 'croak';
7a9b44b9 11use B qw(class main_root main_start main_cv svref_2object opnumber cstring
bd0865ec
GS
12 OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
13 OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL
14 OPpLVAL_INTRO OPpENTERSUB_AMPER OPpSLICE OPpCONST_BARE
3ed82cfc 15 OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY
7a9b44b9 16 OPpCONST_ARYBASE
bd0865ec 17 SVf_IOK SVf_NOK SVf_ROK SVf_POK
6aaf4108 18 CVf_METHOD CVf_LOCKED CVf_LVALUE
bd0865ec
GS
19 PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE
20 PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED);
58cccf98 21$VERSION = 0.60;
a798dbf2 22use strict;
a798dbf2 23
6e90668e
SM
24# Changes between 0.50 and 0.51:
25# - fixed nulled leave with live enter in sort { }
26# - fixed reference constants (\"str")
27# - handle empty programs gracefully
28# - handle infinte loops (for (;;) {}, while (1) {})
29# - differentiate between `for my $x ...' and `my $x; for $x ...'
30# - various minor cleanups
31# - moved globals into an object
32# - added `-u', like B::C
33# - package declarations using cop_stash
34# - subs, formats and code sorted by cop_seq
f6f9bdb7
SM
35# Changes between 0.51 and 0.52:
36# - added pp_threadsv (special variables under USE_THREADS)
37# - added documentation
bd0865ec 38# Changes between 0.52 and 0.53:
9d2c6865
SM
39# - many changes adding precedence contexts and associativity
40# - added `-p' and `-s' output style options
41# - various other minor fixes
bd0865ec 42# Changes between 0.53 and 0.54:
d7f5b6da
SM
43# - added support for new `for (1..100)' optimization,
44# thanks to Gisle Aas
bd0865ec 45# Changes between 0.54 and 0.55:
90be192f
SM
46# - added support for new qr// construct
47# - added support for new pp_regcreset OP
bd0865ec 48# Changes between 0.55 and 0.56:
f5aa8f4e
SM
49# - tested on base/*.t, cmd/*.t, comp/*.t, io/*.t
50# - fixed $# on non-lexicals broken in last big rewrite
51# - added temporary fix for change in opcode of OP_STRINGIFY
52# - fixed problem in 0.54's for() patch in `for (@ary)'
53# - fixed precedence in conditional of ?:
54# - tweaked list paren elimination in `my($x) = @_'
55# - made continue-block detection trickier wrt. null ops
56# - fixed various prototype problems in pp_entersub
57# - added support for sub prototypes that never get GVs
58# - added unquoting for special filehandle first arg in truncate
59# - print doubled rv2gv (a bug) as `*{*GV}' instead of illegal `**GV'
60# - added semicolons at the ends of blocks
61# - added -l `#line' declaration option -- fixes cmd/subval.t 27,28
bd0865ec
GS
62# Changes between 0.56 and 0.561:
63# - fixed multiply-declared my var in pp_truncate (thanks to Sarathy)
64# - used new B.pm symbolic constants (done by Nick Ing-Simmons)
65# Changes between 0.561 and 0.57:
66# - stylistic changes to symbolic constant stuff
67# - handled scope in s///e replacement code
68# - added unquote option for expanding "" into concats, etc.
69# - split method and proto parts of pp_entersub into separate functions
70# - various minor cleanups
f4a44678
SM
71# Changes after 0.57:
72# - added parens in \&foo (patch by Albert Dvornik)
73# Changes between 0.57 and 0.58:
74# - fixed `0' statements that weren't being printed
75# - added methods for use from other programs
76# (based on patches from James Duncan and Hugo van der Sanden)
77# - added -si and -sT to control indenting (also based on a patch from Hugo)
78# - added -sv to print something else instead of '???'
79# - preliminary version of utf8 tr/// handling
3ed82cfc
GS
80# Changes after 0.58:
81# - uses of $op->ppaddr changed to new $op->name (done by Sarathy)
82# - added support for Hugo's new OP_SETSTATE (like nextstate)
83# Changes between 0.58 and 0.59
84# - added support for Chip's OP_METHOD_NAMED
85# - added support for Ilya's OPpTARGET_MY optimization
86# - elided arrows before `()' subscripts when possible
58cccf98
SM
87# Changes between 0.59 and 0.60
88# - support for method attribues was added
89# - some warnings fixed
90# - separate recognition of constant subs
91# - rewrote continue block handling, now recoginizing for loops
92# - added more control of expanding control structures
6e90668e
SM
93
94# Todo:
f4a44678
SM
95# - finish tr/// changes
96# - add option for even more parens (generalize \&foo change)
90be192f 97# - left/right context
bd0865ec 98# - recognize `use utf8', `use integer', etc
f4a44678 99# - treat top-level block specially for incremental output
58cccf98
SM
100# - interpret high bit chars in string as utf8 \x{...} (when?)
101# - copy comments (look at real text with $^P?)
f5aa8f4e 102# - avoid semis in one-statement blocks
9d2c6865 103# - associativity of &&=, ||=, ?:
6e90668e
SM
104# - ',' => '=>' (auto-unquote?)
105# - break long lines ("\r" as discretionary break?)
f4a44678
SM
106# - configurable syntax highlighting: ANSI color, HTML, TeX, etc.
107# - more style options: brace style, hex vs. octal, quotes, ...
108# - print big ints as hex/octal instead of decimal (heuristic?)
3ed82cfc 109# - handle `my $x if 0'?
f5aa8f4e
SM
110# - include values of variables (e.g. set in BEGIN)
111# - coordinate with Data::Dumper (both directions? see previous)
6e90668e
SM
112# - version using op_next instead of op_first/sibling?
113# - avoid string copies (pass arrays, one big join?)
114# - auto-apply `-u'?
9d2c6865
SM
115# - -uPackage:: descend recursively?
116# - here-docs?
117# - <DATA>?
6e90668e 118
f5aa8f4e
SM
119# Tests that will always fail:
120# comp/redef.t -- all (redefinition happens at compile time)
121
6e90668e
SM
122# Object fields (were globals):
123#
124# avoid_local:
125# (local($a), local($b)) and local($a, $b) have the same internal
126# representation but the short form looks better. We notice we can
127# use a large-scale local when checking the list, but need to prevent
128# individual locals too. This hash holds the addresses of OPs that
129# have already had their local-ness accounted for. The same thing
130# is done with my().
131#
132# curcv:
133# CV for current sub (or main program) being deparsed
134#
135# curstash:
136# name of the current package for deparsed code
137#
138# subs_todo:
139# array of [cop_seq, GV, is_format?] for subs and formats we still
140# want to deparse
141#
f5aa8f4e
SM
142# protos_todo:
143# as above, but [name, prototype] for subs that never got a GV
144#
6e90668e
SM
145# subs_done, forms_done:
146# keys are addresses of GVs for subs and formats we've already
147# deparsed (or at least put into subs_todo)
9d2c6865
SM
148#
149# parens: -p
f5aa8f4e 150# linenums: -l
bd0865ec 151# unquote: -q
9d2c6865 152# cuddle: ` ' or `\n', depending on -sC
f4a44678
SM
153# indent_size: -si
154# use_tabs: -sT
155# ex_const: -sv
9d2c6865
SM
156
157# A little explanation of how precedence contexts and associativity
158# work:
159#
160# deparse() calls each per-op subroutine with an argument $cx (short
161# for context, but not the same as the cx* in the perl core), which is
162# a number describing the op's parents in terms of precedence, whether
f5aa8f4e 163# they're inside an expression or at statement level, etc. (see
9d2c6865
SM
164# chart below). When ops with children call deparse on them, they pass
165# along their precedence. Fractional values are used to implement
166# associativity (`($x + $y) + $z' => `$x + $y + $y') and related
167# parentheses hacks. The major disadvantage of this scheme is that
168# it doesn't know about right sides and left sides, so say if you
169# assign a listop to a variable, it can't tell it's allowed to leave
170# the parens off the listop.
171
172# Precedences:
173# 26 [TODO] inside interpolation context ("")
174# 25 left terms and list operators (leftward)
175# 24 left ->
176# 23 nonassoc ++ --
177# 22 right **
178# 21 right ! ~ \ and unary + and -
179# 20 left =~ !~
180# 19 left * / % x
181# 18 left + - .
182# 17 left << >>
183# 16 nonassoc named unary operators
184# 15 nonassoc < > <= >= lt gt le ge
185# 14 nonassoc == != <=> eq ne cmp
186# 13 left &
187# 12 left | ^
188# 11 left &&
189# 10 left ||
190# 9 nonassoc .. ...
191# 8 right ?:
192# 7 right = += -= *= etc.
193# 6 left , =>
194# 5 nonassoc list operators (rightward)
195# 4 right not
196# 3 left and
197# 2 left or xor
198# 1 statement modifiers
199# 0 statement level
200
201# Nonprinting characters with special meaning:
202# \cS - steal parens (see maybe_parens_unop)
203# \n - newline and indent
204# \t - increase indent
205# \b - decrease indent (`outdent')
f5aa8f4e 206# \f - flush left (no indent)
9d2c6865 207# \cK - kill following semicolon, if any
6e90668e
SM
208
209sub null {
210 my $op = shift;
211 return class($op) eq "NULL";
212}
213
214sub todo {
215 my $self = shift;
216 my($gv, $cv, $is_form) = @_;
217 my $seq;
218 if (!null($cv->START) and is_state($cv->START)) {
219 $seq = $cv->START->cop_seq;
220 } else {
221 $seq = 0;
222 }
223 push @{$self->{'subs_todo'}}, [$seq, $gv, $is_form];
224}
225
226sub next_todo {
227 my $self = shift;
228 my $ent = shift @{$self->{'subs_todo'}};
229 my $name = $self->gv_name($ent->[1]);
230 if ($ent->[2]) {
231 return "format $name =\n"
232 . $self->deparse_format($ent->[1]->FORM). "\n";
233 } else {
3ed82cfc 234 return "sub $name " . $self->deparse_sub($ent->[1]->CV);
6e90668e
SM
235 }
236}
237
6e90668e
SM
238sub walk_tree {
239 my($op, $sub) = @_;
240 $sub->($op);
241 if ($op->flags & OPf_KIDS) {
242 my $kid;
243 for ($kid = $op->first; not null $kid; $kid = $kid->sibling) {
244 walk_tree($kid, $sub);
245 }
246 }
247}
248
249sub walk_sub {
250 my $self = shift;
251 my $cv = shift;
252 my $op = $cv->ROOT;
253 $op = shift if null $op;
254 return if !$op or null $op;
255 walk_tree($op, sub {
256 my $op = shift;
3f872cb9 257 if ($op->name eq "gv") {
6f611a1a 258 my $gv = $self->gv_or_padgv($op);
3f872cb9 259 if ($op->next->name eq "entersub") {
6f611a1a
GS
260 return if $self->{'subs_done'}{$$gv}++;
261 return if class($gv->CV) eq "SPECIAL";
18228111
GS
262 $self->todo($gv, $gv->CV, 0);
263 $self->walk_sub($gv->CV);
3f872cb9
GS
264 } elsif ($op->next->name eq "enterwrite"
265 or ($op->next->name eq "rv2gv"
266 and $op->next->next->name eq "enterwrite")) {
6f611a1a
GS
267 return if $self->{'forms_done'}{$$gv}++;
268 return if class($gv->FORM) eq "SPECIAL";
18228111
GS
269 $self->todo($gv, $gv->FORM, 1);
270 $self->walk_sub($gv->FORM);
6e90668e
SM
271 }
272 }
273 });
274}
275
276sub stash_subs {
277 my $self = shift;
278 my $pack = shift;
279 my(%stash, @ret);
280 { no strict 'refs'; %stash = svref_2object(\%{$pack . "::"})->ARRAY }
f5aa8f4e
SM
281 if ($pack eq "main") {
282 $pack = "";
283 } else {
284 $pack = $pack . "::";
285 }
6e90668e
SM
286 my($key, $val);
287 while (($key, $val) = each %stash) {
f5aa8f4e
SM
288 my $class = class($val);
289 if ($class eq "PV") {
290 # Just a prototype
291 push @{$self->{'protos_todo'}}, [$pack . $key, $val->PV];
292 } elsif ($class eq "IV") {
293 # Just a name
294 push @{$self->{'protos_todo'}}, [$pack . $key, undef];
295 } elsif ($class eq "GV") {
296 if (class($val->CV) ne "SPECIAL") {
297 next if $self->{'subs_done'}{$$val}++;
298 $self->todo($val, $val->CV, 0);
299 $self->walk_sub($val->CV);
300 }
301 if (class($val->FORM) ne "SPECIAL") {
302 next if $self->{'forms_done'}{$$val}++;
303 $self->todo($val, $val->FORM, 1);
304 $self->walk_sub($val->FORM);
305 }
6e90668e
SM
306 }
307 }
308}
a798dbf2 309
f5aa8f4e
SM
310sub print_protos {
311 my $self = shift;
312 my $ar;
313 my @ret;
314 foreach $ar (@{$self->{'protos_todo'}}) {
315 my $proto = (defined $ar->[1] ? " (". $ar->[1] . ")" : "");
316 push @ret, "sub " . $ar->[0] . "$proto;\n";
317 }
318 delete $self->{'protos_todo'};
319 return @ret;
320}
321
9d2c6865
SM
322sub style_opts {
323 my $self = shift;
324 my $opts = shift;
325 my $opt;
326 while (length($opt = substr($opts, 0, 1))) {
327 if ($opt eq "C") {
328 $self->{'cuddle'} = " ";
f4a44678
SM
329 $opts = substr($opts, 1);
330 } elsif ($opt eq "i") {
331 $opts =~ s/^i(\d+)//;
332 $self->{'indent_size'} = $1;
333 } elsif ($opt eq "T") {
334 $self->{'use_tabs'} = 1;
335 $opts = substr($opts, 1);
336 } elsif ($opt eq "v") {
337 $opts =~ s/^v([^.]*)(.|$)//;
338 $self->{'ex_const'} = $1;
9d2c6865 339 }
9d2c6865
SM
340 }
341}
342
f4a44678
SM
343sub new {
344 my $class = shift;
345 my $self = bless {}, $class;
346 $self->{'subs_todo'} = [];
347 $self->{'curstash'} = "main";
348 $self->{'cuddle'} = "\n";
349 $self->{'indent_size'} = 4;
350 $self->{'use_tabs'} = 0;
793e2a70
RH
351 $self->{'expand'} = 0;
352 $self->{'unquote'} = 0;
353 $self->{'linenums'} = 0;
354 $self->{'parens'} = 0;
f4a44678 355 $self->{'ex_const'} = "'???'";
08c6f5ec
RH
356
357 $self->{'ambient_arybase'} = 0;
358 $self->{'ambient_warnings'} = "\0"x12;
359 $self->init();
360
f4a44678
SM
361 while (my $arg = shift @_) {
362 if (substr($arg, 0, 2) eq "-u") {
363 $self->stash_subs(substr($arg, 2));
364 } elsif ($arg eq "-p") {
365 $self->{'parens'} = 1;
366 } elsif ($arg eq "-l") {
367 $self->{'linenums'} = 1;
368 } elsif ($arg eq "-q") {
369 $self->{'unquote'} = 1;
370 } elsif (substr($arg, 0, 2) eq "-s") {
371 $self->style_opts(substr $arg, 2);
58cccf98
SM
372 } elsif ($arg =~ /^-x(\d)$/) {
373 $self->{'expand'} = $1;
f4a44678
SM
374 }
375 }
376 return $self;
377}
378
08c6f5ec
RH
379# Initialise the contextual information, either from
380# defaults provided with the ambient_pragmas method,
381# or from perl's own defaults otherwise.
382sub init {
383 my $self = shift;
384
385 $self->{'arybase'} = $self->{'ambient_arybase'};
386 $self->{'warnings'} = $self->{'ambient_warnings'};
387}
388
a798dbf2 389sub compile {
6e90668e
SM
390 my(@args) = @_;
391 return sub {
f4a44678 392 my $self = B::Deparse->new(@args);
6e90668e
SM
393 $self->stash_subs("main");
394 $self->{'curcv'} = main_cv;
6e90668e 395 $self->walk_sub(main_cv, main_start);
f5aa8f4e 396 print $self->print_protos;
6e90668e 397 @{$self->{'subs_todo'}} =
f4a44678
SM
398 sort {$a->[0] <=> $b->[0]} @{$self->{'subs_todo'}};
399 print $self->indent($self->deparse(main_root, 0)), "\n"
400 unless null main_root;
6e90668e
SM
401 my @text;
402 while (scalar(@{$self->{'subs_todo'}})) {
403 push @text, $self->next_todo;
404 }
6f611a1a 405 print $self->indent(join("", @text)), "\n" if @text;
a798dbf2 406 }
a798dbf2
MB
407}
408
f4a44678
SM
409sub coderef2text {
410 my $self = shift;
411 my $sub = shift;
412 croak "Usage: ->coderef2text(CODEREF)" unless ref($sub) eq "CODE";
08c6f5ec
RH
413
414 $self->init();
f4a44678
SM
415 return $self->indent($self->deparse_sub(svref_2object($sub)));
416}
417
08c6f5ec
RH
418sub ambient_pragmas {
419 my $self = shift;
420 my ($arybase, $hint_bits, $warning_bits) = (0, 0, "\0"x12);
421
422 while (@_ > 1) {
423 my $name = shift();
424 my $val = shift();
425
426 if ($name eq 'strict') {
427 require strict;
428
429 if ($val eq 'none') {
430 $hint_bits &= ~strict::bits(qw/refs subs vars/);
431 next();
432 }
433
434 my @names;
435 if ($val eq "all") {
436 @names = qw/refs subs vars/;
437 }
438 elsif (ref $val) {
439 @names = @$val;
440 }
441 else {
442 @names = split/\s+/, $val;
443 }
444 $hint_bits |= strict::bits(@names);
445 }
446
447 elsif ($name eq '$[') {
448 $arybase = $val;
449 }
450
451 elsif ($name eq 'integer') {
452 require integer;
453 if ($val) {
454 $hint_bits |= $integer::hint_bits;
455 }
456 else {
457 $hint_bits &= ~$integer::hint_bits;
458 }
459 }
460
461 elsif ($name eq 'warnings') {
462 require warnings;
463 if ($val eq 'none') {
464 $warning_bits = "\0"x12;
465 next();
466 }
467
468 my @names;
469 if (ref $val) {
470 @names = @$val;
471 }
472 else {
473 @names = split/\s+/, $val;
474 }
475
476 $warning_bits |= warnings::bits(@names);
477 }
478
479 elsif ($name eq 'warning_bits') {
480 $warning_bits = $val;
481 }
482
483 elsif ($name eq 'hint_bits') {
484 $hint_bits = $val;
485 }
486
487 else {
488 croak "Unknown pragma type: $name";
489 }
490 }
491 if (@_) {
492 croak "The ambient_pragmas method expects an even number of args";
493 }
494
495 $self->{'ambient_arybase'} = $arybase;
496 $self->{'ambient_warnings'} = $warning_bits;
497
498 # $^H pragmas not yet implemented here
499}
500
6e90668e
SM
501sub deparse {
502 my $self = shift;
9d2c6865
SM
503 my($op, $cx) = @_;
504# cluck if class($op) eq "NULL";
58cccf98 505# cluck unless $op;
3f872cb9 506# return $self->$ {\("pp_" . $op->name)}($op, $cx);
7a9b44b9
RH
507require Carp;
508Carp::confess() unless defined $op;
3f872cb9 509 my $meth = "pp_" . $op->name;
9d2c6865 510 return $self->$meth($op, $cx);
a798dbf2
MB
511}
512
6e90668e 513sub indent {
f4a44678 514 my $self = shift;
6e90668e
SM
515 my $txt = shift;
516 my @lines = split(/\n/, $txt);
517 my $leader = "";
f4a44678 518 my $level = 0;
6e90668e
SM
519 my $line;
520 for $line (@lines) {
f4a44678
SM
521 my $cmd = substr($line, 0, 1);
522 if ($cmd eq "\t" or $cmd eq "\b") {
523 $level += ($cmd eq "\t" ? 1 : -1) * $self->{'indent_size'};
524 if ($self->{'use_tabs'}) {
525 $leader = "\t" x ($level / 8) . " " x ($level % 8);
526 } else {
527 $leader = " " x $level;
528 }
6e90668e
SM
529 $line = substr($line, 1);
530 }
f5aa8f4e
SM
531 if (substr($line, 0, 1) eq "\f") {
532 $line = substr($line, 1); # no indent
533 } else {
534 $line = $leader . $line;
535 }
9d2c6865 536 $line =~ s/\cK;?//g;
6e90668e
SM
537 }
538 return join("\n", @lines);
539}
540
6e90668e
SM
541sub deparse_sub {
542 my $self = shift;
543 my $cv = shift;
544 my $proto = "";
545 if ($cv->FLAGS & SVf_POK) {
546 $proto = "(". $cv->PV . ") ";
547 }
6aaf4108
SC
548 if ($cv->CvFLAGS & (CVf_METHOD|CVf_LOCKED|CVf_LVALUE)) {
549 $proto .= ": ";
550 $proto .= "lvalue " if $cv->CvFLAGS & CVf_LVALUE;
551 $proto .= "locked " if $cv->CvFLAGS & CVf_LOCKED;
552 $proto .= "method " if $cv->CvFLAGS & CVf_METHOD;
553 }
554
6e90668e
SM
555 local($self->{'curcv'}) = $cv;
556 local($self->{'curstash'}) = $self->{'curstash'};
557 if (not null $cv->ROOT) {
558 # skip leavesub
559 return $proto . "{\n\t" .
9d2c6865 560 $self->deparse($cv->ROOT->first, 0) . "\n\b}\n";
de3f1649
JT
561 }
562 my $sv = $cv->const_sv;
563 if ($$sv) {
564 # uh-oh. inlinable sub... format it differently
565 return $proto . "{ " . const($sv) . " }\n";
6e90668e
SM
566 } else { # XSUB?
567 return $proto . "{}\n";
568 }
569}
570
571sub deparse_format {
572 my $self = shift;
573 my $form = shift;
574 my @text;
575 local($self->{'curcv'}) = $form;
576 local($self->{'curstash'}) = $self->{'curstash'};
577 my $op = $form->ROOT;
578 my $kid;
579 $op = $op->first->first; # skip leavewrite, lineseq
580 while (not null $op) {
581 $op = $op->sibling; # skip nextstate
582 my @exprs;
583 $kid = $op->first->sibling; # skip pushmark
18228111 584 push @text, $self->const_sv($kid)->PV;
6e90668e
SM
585 $kid = $kid->sibling;
586 for (; not null $kid; $kid = $kid->sibling) {
9d2c6865 587 push @exprs, $self->deparse($kid, 0);
6e90668e
SM
588 }
589 push @text, join(", ", @exprs)."\n" if @exprs;
590 $op = $op->sibling;
591 }
592 return join("", @text) . ".";
593}
594
6e90668e 595sub is_scope {
a798dbf2 596 my $op = shift;
3f872cb9
GS
597 return $op->name eq "leave" || $op->name eq "scope"
598 || $op->name eq "lineseq"
599 || ($op->name eq "null" && class($op) eq "UNOP"
600 && (is_scope($op->first) || $op->first->name eq "enter"));
6e90668e
SM
601}
602
603sub is_state {
3f872cb9
GS
604 my $name = $_[0]->name;
605 return $name eq "nextstate" || $name eq "dbstate" || $name eq "setstate";
6e90668e
SM
606}
607
608sub is_miniwhile { # check for one-line loop (`foo() while $y--')
609 my $op = shift;
610 return (!null($op) and null($op->sibling)
3f872cb9
GS
611 and $op->name eq "null" and class($op) eq "UNOP"
612 and (($op->first->name =~ /^(and|or)$/
613 and $op->first->first->sibling->name eq "lineseq")
614 or ($op->first->name eq "lineseq"
6e90668e 615 and not null $op->first->first->sibling
3f872cb9 616 and $op->first->first->sibling->name eq "unstack")
6e90668e
SM
617 ));
618}
619
620sub is_scalar {
621 my $op = shift;
3f872cb9
GS
622 return ($op->name eq "rv2sv" or
623 $op->name eq "padsv" or
624 $op->name eq "gv" or # only in array/hash constructs
bd0865ec 625 $op->flags & OPf_KIDS && !null($op->first)
3f872cb9 626 && $op->first->name eq "gvsv");
6e90668e
SM
627}
628
9d2c6865
SM
629sub maybe_parens {
630 my $self = shift;
631 my($text, $cx, $prec) = @_;
632 if ($prec < $cx # unary ops nest just fine
633 or $prec == $cx and $cx != 4 and $cx != 16 and $cx != 21
634 or $self->{'parens'})
635 {
636 $text = "($text)";
637 # In a unop, let parent reuse our parens; see maybe_parens_unop
638 $text = "\cS" . $text if $cx == 16;
639 return $text;
640 } else {
641 return $text;
642 }
643}
644
645# same as above, but get around the `if it looks like a function' rule
646sub maybe_parens_unop {
647 my $self = shift;
648 my($name, $kid, $cx) = @_;
649 if ($cx > 16 or $self->{'parens'}) {
650 return "$name(" . $self->deparse($kid, 1) . ")";
651 } else {
652 $kid = $self->deparse($kid, 16);
653 if (substr($kid, 0, 1) eq "\cS") {
654 # use kid's parens
655 return $name . substr($kid, 1);
656 } elsif (substr($kid, 0, 1) eq "(") {
657 # avoid looks-like-a-function trap with extra parens
658 # (`+' can lead to ambiguities)
659 return "$name(" . $kid . ")";
660 } else {
661 return "$name $kid";
662 }
663 }
664}
665
666sub maybe_parens_func {
667 my $self = shift;
668 my($func, $text, $cx, $prec) = @_;
669 if ($prec <= $cx or substr($text, 0, 1) eq "(" or $self->{'parens'}) {
670 return "$func($text)";
671 } else {
672 return "$func $text";
673 }
674}
675
6e90668e
SM
676sub maybe_local {
677 my $self = shift;
9d2c6865 678 my($op, $cx, $text) = @_;
4c1f658f 679 if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {
e8d3f51b
RH
680 if (want_scalar($op)) {
681 return "local $text";
682 } else {
683 return $self->maybe_parens_func("local", $text, $cx, 16);
684 }
6e90668e
SM
685 } else {
686 return $text;
a798dbf2 687 }
a798dbf2
MB
688}
689
3ed82cfc
GS
690sub maybe_targmy {
691 my $self = shift;
692 my($op, $cx, $func, @args) = @_;
693 if ($op->private & OPpTARGET_MY) {
694 my $var = $self->padname($op->targ);
695 my $val = $func->($self, $op, 7, @args);
696 return $self->maybe_parens("$var = $val", $cx, 7);
697 } else {
698 return $func->($self, $op, $cx, @args);
699 }
700}
701
6e90668e
SM
702sub padname_sv {
703 my $self = shift;
704 my $targ = shift;
705 return (($self->{'curcv'}->PADLIST->ARRAY)[0]->ARRAY)[$targ];
706}
707
708sub maybe_my {
709 my $self = shift;
9d2c6865 710 my($op, $cx, $text) = @_;
4c1f658f 711 if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {
e8d3f51b
RH
712 if (want_scalar($op)) {
713 return "my $text";
714 } else {
715 return $self->maybe_parens_func("my", $text, $cx, 16);
716 }
6e90668e
SM
717 } else {
718 return $text;
719 }
720}
721
9d2c6865
SM
722# The following OPs don't have functions:
723
724# pp_padany -- does not exist after parsing
725# pp_rcatline -- does not exist
726
727sub pp_enter { # see also leave
728 cluck "unexpected OP_ENTER";
729 return "XXX";
730}
731
732sub pp_pushmark { # see also list
733 cluck "unexpected OP_PUSHMARK";
734 return "XXX";
735}
736
737sub pp_leavesub { # see also deparse_sub
738 cluck "unexpected OP_LEAVESUB";
739 return "XXX";
740}
741
742sub pp_leavewrite { # see also deparse_format
743 cluck "unexpected OP_LEAVEWRITE";
744 return "XXX";
745}
746
747sub pp_method { # see also entersub
748 cluck "unexpected OP_METHOD";
749 return "XXX";
750}
751
752sub pp_regcmaybe { # see also regcomp
753 cluck "unexpected OP_REGCMAYBE";
754 return "XXX";
755}
756
90be192f
SM
757sub pp_regcreset { # see also regcomp
758 cluck "unexpected OP_REGCRESET";
759 return "XXX";
760}
761
9d2c6865
SM
762sub pp_substcont { # see also subst
763 cluck "unexpected OP_SUBSTCONT";
764 return "XXX";
765}
766
767sub pp_grepstart { # see also grepwhile
768 cluck "unexpected OP_GREPSTART";
769 return "XXX";
770}
771
772sub pp_mapstart { # see also mapwhile
773 cluck "unexpected OP_MAPSTART";
774 return "XXX";
775}
776
777sub pp_flip { # see also flop
778 cluck "unexpected OP_FLIP";
779 return "XXX";
780}
781
782sub pp_iter { # see also leaveloop
783 cluck "unexpected OP_ITER";
784 return "XXX";
785}
786
787sub pp_enteriter { # see also leaveloop
788 cluck "unexpected OP_ENTERITER";
789 return "XXX";
790}
791
792sub pp_enterloop { # see also leaveloop
793 cluck "unexpected OP_ENTERLOOP";
794 return "XXX";
795}
796
797sub pp_leaveeval { # see also entereval
798 cluck "unexpected OP_LEAVEEVAL";
799 return "XXX";
800}
801
802sub pp_entertry { # see also leavetry
803 cluck "unexpected OP_ENTERTRY";
804 return "XXX";
805}
6e90668e 806
58cccf98 807sub lineseq {
6e90668e 808 my $self = shift;
58cccf98
SM
809 my(@ops) = @_;
810 my($expr, @exprs);
811 for (my $i = 0; $i < @ops; $i++) {
6e90668e 812 $expr = "";
58cccf98
SM
813 if (is_state $ops[$i]) {
814 $expr = $self->deparse($ops[$i], 0);
815 $i++;
816 last if $i > $#ops;
817 }
818 if (!is_state $ops[$i] and $ops[$i+1] and !null($ops[$i+1]) and
819 $ops[$i+1]->name eq "leaveloop" and $self->{'expand'} < 3)
820 {
821 push @exprs, $expr . $self->for_loop($ops[$i], 0);
822 $i++;
823 next;
6e90668e 824 }
58cccf98 825 $expr .= $self->deparse($ops[$i], 0);
f4a44678 826 push @exprs, $expr if length $expr;
6e90668e 827 }
7a9b44b9 828 for(@exprs[0..@exprs-1]) { s/;\n\z// }
58cccf98 829 return join(";\n", @exprs);
6e90668e
SM
830}
831
58cccf98
SM
832sub scopeop {
833 my($real_block, $self, $op, $cx) = @_;
834 my $kid;
835 my @kids;
836 local($self->{'curstash'}) = $self->{'curstash'} if $real_block;
837 if ($real_block) {
838 $kid = $op->first->sibling; # skip enter
839 if (is_miniwhile($kid)) {
840 my $top = $kid->first;
841 my $name = $top->name;
842 if ($name eq "and") {
843 $name = "while";
844 } elsif ($name eq "or") {
845 $name = "until";
846 } else { # no conditional -> while 1 or until 0
847 return $self->deparse($top->first, 1) . " while 1";
848 }
849 my $cond = $top->first;
850 my $body = $cond->sibling->first; # skip lineseq
851 $cond = $self->deparse($cond, 1);
852 $body = $self->deparse($body, 1);
853 return "$body $name $cond";
6e90668e 854 }
58cccf98
SM
855 } else {
856 $kid = $op->first;
857 }
858 for (; !null($kid); $kid = $kid->sibling) {
859 push @kids, $kid;
6e90668e 860 }
9d2c6865 861 if ($cx > 0) { # inside an expression, (a do {} while for lineseq)
58cccf98 862 return "do { " . $self->lineseq(@kids) . " }";
9d2c6865 863 } else {
7a9b44b9
RH
864 my $lineseq = $self->lineseq(@kids);
865 return (length ($lineseq) ? "$lineseq;" : "");
6e90668e 866 }
6e90668e
SM
867}
868
58cccf98
SM
869sub pp_scope { scopeop(0, @_); }
870sub pp_lineseq { scopeop(0, @_); }
871sub pp_leave { scopeop(1, @_); }
9d2c6865 872
6e90668e
SM
873# The BEGIN {} is used here because otherwise this code isn't executed
874# when you run B::Deparse on itself.
875my %globalnames;
876BEGIN { map($globalnames{$_}++, "SIG", "STDIN", "STDOUT", "STDERR", "INC",
877 "ENV", "ARGV", "ARGVOUT", "_"); }
878
879sub gv_name {
880 my $self = shift;
881 my $gv = shift;
882 my $stash = $gv->STASH->NAME;
d9963e60 883 my $name = $gv->SAFENAME;
9d2c6865
SM
884 if ($stash eq $self->{'curstash'} or $globalnames{$name}
885 or $name =~ /^[^A-Za-z_]/)
886 {
6e90668e
SM
887 $stash = "";
888 } else {
889 $stash = $stash . "::";
a798dbf2 890 }
d9963e60
RH
891 if ($name =~ /^\^../) {
892 $name = "{$name}"; # ${^WARNING_BITS} etc
6e90668e
SM
893 }
894 return $stash . $name;
a798dbf2
MB
895}
896
08c6f5ec
RH
897# Notice how subs and formats are inserted between statements here;
898# also $[ assignments and the warnings pragma.
6e90668e
SM
899sub pp_nextstate {
900 my $self = shift;
9d2c6865 901 my($op, $cx) = @_;
6e90668e
SM
902 my @text;
903 @text = $op->label . ": " if $op->label;
904 my $seq = $op->cop_seq;
905 while (scalar(@{$self->{'subs_todo'}})
906 and $seq > $self->{'subs_todo'}[0][0]) {
907 push @text, $self->next_todo;
908 }
11faa288 909 my $stash = $op->stashpv;
6e90668e
SM
910 if ($stash ne $self->{'curstash'}) {
911 push @text, "package $stash;\n";
912 $self->{'curstash'} = $stash;
913 }
f5aa8f4e
SM
914 if ($self->{'linenums'}) {
915 push @text, "\f#line " . $op->line .
57843af0 916 ' "' . $op->file, qq'"\n';
f5aa8f4e 917 }
08c6f5ec 918
7a9b44b9
RH
919 if ($self->{'arybase'} != $op->arybase) {
920 push @text, '$[ = '. $op->arybase .";\n";
921 $self->{'arybase'} = $op->arybase;
922 }
923
924 my $warnings = $op->warnings;
925 my $warning_bits;
926 if ($warnings->isa("B::SPECIAL") && $$warnings == 4) {
927 $warning_bits = $warnings::Bits{"all"};
928 }
929 elsif ($warnings->isa("B::SPECIAL")) {
930 $warning_bits = "\0"x12;
931 }
932 else {
933 $warning_bits = $warnings->PV;
934 }
935
936 if ($self->{'warnings'} ne $warning_bits) {
08c6f5ec 937 push @text, declare_warnings($self->{'warnings'}, $warning_bits);
7a9b44b9
RH
938 $self->{'warnings'} = $warning_bits;
939 }
940
6e90668e
SM
941 return join("", @text);
942}
943
08c6f5ec
RH
944sub declare_warnings {
945 my ($from, $to) = @_;
946 return "BEGIN {\${^WARNING_BITS} = ".cstring($to)."};\n";
947}
948
6e90668e 949sub pp_dbstate { pp_nextstate(@_) }
3f872cb9 950sub pp_setstate { pp_nextstate(@_) }
6e90668e
SM
951
952sub pp_unstack { return "" } # see also leaveloop
953
954sub baseop {
955 my $self = shift;
9d2c6865 956 my($op, $cx, $name) = @_;
6e90668e
SM
957 return $name;
958}
959
960sub pp_stub { baseop(@_, "()") }
961sub pp_wantarray { baseop(@_, "wantarray") }
962sub pp_fork { baseop(@_, "fork") }
3ed82cfc
GS
963sub pp_wait { maybe_targmy(@_, \&baseop, "wait") }
964sub pp_getppid { maybe_targmy(@_, \&baseop, "getppid") }
965sub pp_time { maybe_targmy(@_, \&baseop, "time") }
6e90668e
SM
966sub pp_tms { baseop(@_, "times") }
967sub pp_ghostent { baseop(@_, "gethostent") }
968sub pp_gnetent { baseop(@_, "getnetent") }
969sub pp_gprotoent { baseop(@_, "getprotoent") }
970sub pp_gservent { baseop(@_, "getservent") }
971sub pp_ehostent { baseop(@_, "endhostent") }
972sub pp_enetent { baseop(@_, "endnetent") }
973sub pp_eprotoent { baseop(@_, "endprotoent") }
974sub pp_eservent { baseop(@_, "endservent") }
975sub pp_gpwent { baseop(@_, "getpwent") }
976sub pp_spwent { baseop(@_, "setpwent") }
977sub pp_epwent { baseop(@_, "endpwent") }
978sub pp_ggrent { baseop(@_, "getgrent") }
979sub pp_sgrent { baseop(@_, "setgrent") }
980sub pp_egrent { baseop(@_, "endgrent") }
981sub pp_getlogin { baseop(@_, "getlogin") }
982
983sub POSTFIX () { 1 }
984
9d2c6865
SM
985# I couldn't think of a good short name, but this is the category of
986# symbolic unary operators with interesting precedence
987
988sub pfixop {
989 my $self = shift;
990 my($op, $cx, $name, $prec, $flags) = (@_, 0);
991 my $kid = $op->first;
992 $kid = $self->deparse($kid, $prec);
993 return $self->maybe_parens(($flags & POSTFIX) ? "$kid$name" : "$name$kid",
994 $cx, $prec);
995}
996
997sub pp_preinc { pfixop(@_, "++", 23) }
998sub pp_predec { pfixop(@_, "--", 23) }
3ed82cfc
GS
999sub pp_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
1000sub pp_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
9d2c6865
SM
1001sub pp_i_preinc { pfixop(@_, "++", 23) }
1002sub pp_i_predec { pfixop(@_, "--", 23) }
3ed82cfc
GS
1003sub pp_i_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
1004sub pp_i_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
68cc8748 1005sub pp_complement { maybe_targmy(@_, \&pfixop, "~", 21) }
9d2c6865 1006
3ed82cfc
GS
1007sub pp_negate { maybe_targmy(@_, \&real_negate) }
1008sub real_negate {
9d2c6865
SM
1009 my $self = shift;
1010 my($op, $cx) = @_;
3f872cb9 1011 if ($op->first->name =~ /^(i_)?negate$/) {
9d2c6865
SM
1012 # avoid --$x
1013 $self->pfixop($op, $cx, "-", 21.5);
1014 } else {
1015 $self->pfixop($op, $cx, "-", 21);
1016 }
1017}
1018sub pp_i_negate { pp_negate(@_) }
1019
1020sub pp_not {
1021 my $self = shift;
1022 my($op, $cx) = @_;
1023 if ($cx <= 4) {
1024 $self->pfixop($op, $cx, "not ", 4);
1025 } else {
1026 $self->pfixop($op, $cx, "!", 21);
1027 }
1028}
1029
6e90668e
SM
1030sub unop {
1031 my $self = shift;
f4a44678 1032 my($op, $cx, $name) = @_;
6e90668e 1033 my $kid;
9d2c6865 1034 if ($op->flags & OPf_KIDS) {
6e90668e 1035 $kid = $op->first;
9d2c6865 1036 return $self->maybe_parens_unop($name, $kid, $cx);
6e90668e 1037 } else {
9d2c6865 1038 return $name . ($op->flags & OPf_SPECIAL ? "()" : "");
6e90668e 1039 }
6e90668e
SM
1040}
1041
3ed82cfc
GS
1042sub pp_chop { maybe_targmy(@_, \&unop, "chop") }
1043sub pp_chomp { maybe_targmy(@_, \&unop, "chomp") }
1044sub pp_schop { maybe_targmy(@_, \&unop, "chop") }
1045sub pp_schomp { maybe_targmy(@_, \&unop, "chomp") }
6e90668e
SM
1046sub pp_defined { unop(@_, "defined") }
1047sub pp_undef { unop(@_, "undef") }
1048sub pp_study { unop(@_, "study") }
6e90668e
SM
1049sub pp_ref { unop(@_, "ref") }
1050sub pp_pos { maybe_local(@_, unop(@_, "pos")) }
1051
3ed82cfc
GS
1052sub pp_sin { maybe_targmy(@_, \&unop, "sin") }
1053sub pp_cos { maybe_targmy(@_, \&unop, "cos") }
1054sub pp_rand { maybe_targmy(@_, \&unop, "rand") }
6e90668e 1055sub pp_srand { unop(@_, "srand") }
3ed82cfc
GS
1056sub pp_exp { maybe_targmy(@_, \&unop, "exp") }
1057sub pp_log { maybe_targmy(@_, \&unop, "log") }
1058sub pp_sqrt { maybe_targmy(@_, \&unop, "sqrt") }
1059sub pp_int { maybe_targmy(@_, \&unop, "int") }
1060sub pp_hex { maybe_targmy(@_, \&unop, "hex") }
1061sub pp_oct { maybe_targmy(@_, \&unop, "oct") }
1062sub pp_abs { maybe_targmy(@_, \&unop, "abs") }
1063
1064sub pp_length { maybe_targmy(@_, \&unop, "length") }
1065sub pp_ord { maybe_targmy(@_, \&unop, "ord") }
1066sub pp_chr { maybe_targmy(@_, \&unop, "chr") }
6e90668e
SM
1067
1068sub pp_each { unop(@_, "each") }
1069sub pp_values { unop(@_, "values") }
1070sub pp_keys { unop(@_, "keys") }
1071sub pp_pop { unop(@_, "pop") }
1072sub pp_shift { unop(@_, "shift") }
1073
1074sub pp_caller { unop(@_, "caller") }
1075sub pp_reset { unop(@_, "reset") }
1076sub pp_exit { unop(@_, "exit") }
1077sub pp_prototype { unop(@_, "prototype") }
1078
1079sub pp_close { unop(@_, "close") }
1080sub pp_fileno { unop(@_, "fileno") }
1081sub pp_umask { unop(@_, "umask") }
6e90668e
SM
1082sub pp_untie { unop(@_, "untie") }
1083sub pp_tied { unop(@_, "tied") }
1084sub pp_dbmclose { unop(@_, "dbmclose") }
1085sub pp_getc { unop(@_, "getc") }
1086sub pp_eof { unop(@_, "eof") }
1087sub pp_tell { unop(@_, "tell") }
1088sub pp_getsockname { unop(@_, "getsockname") }
1089sub pp_getpeername { unop(@_, "getpeername") }
1090
3ed82cfc
GS
1091sub pp_chdir { maybe_targmy(@_, \&unop, "chdir") }
1092sub pp_chroot { maybe_targmy(@_, \&unop, "chroot") }
6e90668e 1093sub pp_readlink { unop(@_, "readlink") }
3ed82cfc 1094sub pp_rmdir { maybe_targmy(@_, \&unop, "rmdir") }
6e90668e
SM
1095sub pp_readdir { unop(@_, "readdir") }
1096sub pp_telldir { unop(@_, "telldir") }
1097sub pp_rewinddir { unop(@_, "rewinddir") }
1098sub pp_closedir { unop(@_, "closedir") }
3ed82cfc 1099sub pp_getpgrp { maybe_targmy(@_, \&unop, "getpgrp") }
6e90668e
SM
1100sub pp_localtime { unop(@_, "localtime") }
1101sub pp_gmtime { unop(@_, "gmtime") }
1102sub pp_alarm { unop(@_, "alarm") }
3ed82cfc 1103sub pp_sleep { maybe_targmy(@_, \&unop, "sleep") }
6e90668e
SM
1104
1105sub pp_dofile { unop(@_, "do") }
1106sub pp_entereval { unop(@_, "eval") }
1107
1108sub pp_ghbyname { unop(@_, "gethostbyname") }
1109sub pp_gnbyname { unop(@_, "getnetbyname") }
1110sub pp_gpbyname { unop(@_, "getprotobyname") }
1111sub pp_shostent { unop(@_, "sethostent") }
1112sub pp_snetent { unop(@_, "setnetent") }
1113sub pp_sprotoent { unop(@_, "setprotoent") }
1114sub pp_sservent { unop(@_, "setservent") }
1115sub pp_gpwnam { unop(@_, "getpwnam") }
1116sub pp_gpwuid { unop(@_, "getpwuid") }
1117sub pp_ggrnam { unop(@_, "getgrnam") }
1118sub pp_ggrgid { unop(@_, "getgrgid") }
1119
1120sub pp_lock { unop(@_, "lock") }
1121
1122sub pp_exists {
1123 my $self = shift;
9d2c6865
SM
1124 my($op, $cx) = @_;
1125 return $self->maybe_parens_func("exists", $self->pp_helem($op->first, 16),
1126 $cx, 16);
6e90668e
SM
1127}
1128
6e90668e
SM
1129sub pp_delete {
1130 my $self = shift;
9d2c6865 1131 my($op, $cx) = @_;
6e90668e
SM
1132 my $arg;
1133 if ($op->private & OPpSLICE) {
9d2c6865
SM
1134 return $self->maybe_parens_func("delete",
1135 $self->pp_hslice($op->first, 16),
1136 $cx, 16);
6e90668e 1137 } else {
9d2c6865
SM
1138 return $self->maybe_parens_func("delete",
1139 $self->pp_helem($op->first, 16),
1140 $cx, 16);
6e90668e 1141 }
6e90668e
SM
1142}
1143
6e90668e
SM
1144sub pp_require {
1145 my $self = shift;
9d2c6865 1146 my($op, $cx) = @_;
3f872cb9 1147 if (class($op) eq "UNOP" and $op->first->name eq "const"
4c1f658f 1148 and $op->first->private & OPpCONST_BARE)
6e90668e 1149 {
18228111 1150 my $name = $self->const_sv($op->first)->PV;
6e90668e
SM
1151 $name =~ s[/][::]g;
1152 $name =~ s/\.pm//g;
1153 return "require($name)";
1154 } else {
9d2c6865 1155 $self->unop($op, $cx, "require");
6e90668e
SM
1156 }
1157}
1158
9d2c6865
SM
1159sub pp_scalar {
1160 my $self = shift;
1161 my($op, $cv) = @_;
1162 my $kid = $op->first;
1163 if (not null $kid->sibling) {
1164 # XXX Was a here-doc
1165 return $self->dquote($op);
1166 }
1167 $self->unop(@_, "scalar");
1168}
1169
1170
6e90668e
SM
1171sub padval {
1172 my $self = shift;
1173 my $targ = shift;
18228111 1174 #cluck "curcv was undef" unless $self->{curcv};
6e90668e
SM
1175 return (($self->{'curcv'}->PADLIST->ARRAY)[1]->ARRAY)[$targ];
1176}
1177
1178sub pp_refgen {
1179 my $self = shift;
9d2c6865 1180 my($op, $cx) = @_;
6e90668e 1181 my $kid = $op->first;
3f872cb9 1182 if ($kid->name eq "null") {
6e90668e 1183 $kid = $kid->first;
3f872cb9
GS
1184 if ($kid->name eq "anonlist" || $kid->name eq "anonhash") {
1185 my($pre, $post) = @{{"anonlist" => ["[","]"],
1186 "anonhash" => ["{","}"]}->{$kid->name}};
6e90668e
SM
1187 my($expr, @exprs);
1188 $kid = $kid->first->sibling; # skip pushmark
1189 for (; !null($kid); $kid = $kid->sibling) {
9d2c6865 1190 $expr = $self->deparse($kid, 6);
6e90668e
SM
1191 push @exprs, $expr;
1192 }
1193 return $pre . join(", ", @exprs) . $post;
1194 } elsif (!null($kid->sibling) and
3f872cb9 1195 $kid->sibling->name eq "anoncode") {
6e90668e
SM
1196 return "sub " .
1197 $self->deparse_sub($self->padval($kid->sibling->targ));
3f872cb9
GS
1198 } elsif ($kid->name eq "pushmark") {
1199 my $sib_name = $kid->sibling->name;
1200 if ($sib_name =~ /^(pad|rv2)[ah]v$/
c8c62db7
AD
1201 and not $kid->sibling->flags & OPf_REF)
1202 {
1203 # The @a in \(@a) isn't in ref context, but only when the
1204 # parens are there.
1205 return "\\(" . $self->deparse($kid->sibling, 1) . ")";
3f872cb9 1206 } elsif ($sib_name eq 'entersub') {
c8c62db7
AD
1207 my $text = $self->deparse($kid->sibling, 1);
1208 # Always show parens for \(&func()), but only with -p otherwise
1209 $text = "($text)" if $self->{'parens'}
1210 or $kid->sibling->private & OPpENTERSUB_AMPER;
1211 return "\\$text";
1212 }
1213 }
6e90668e 1214 }
9d2c6865 1215 $self->pfixop($op, $cx, "\\", 20);
6e90668e
SM
1216}
1217
1218sub pp_srefgen { pp_refgen(@_) }
1219
1220sub pp_readline {
1221 my $self = shift;
9d2c6865 1222 my($op, $cx) = @_;
6e90668e 1223 my $kid = $op->first;
3f872cb9 1224 $kid = $kid->first if $kid->name eq "rv2gv"; # <$fh>
9d2c6865 1225 return "<" . $self->deparse($kid, 1) . ">";
6e90668e
SM
1226}
1227
bd0865ec
GS
1228# Unary operators that can occur as pseudo-listops inside double quotes
1229sub dq_unop {
1230 my $self = shift;
1231 my($op, $cx, $name, $prec, $flags) = (@_, 0, 0);
1232 my $kid;
1233 if ($op->flags & OPf_KIDS) {
1234 $kid = $op->first;
1235 # If there's more than one kid, the first is an ex-pushmark.
1236 $kid = $kid->sibling if not null $kid->sibling;
1237 return $self->maybe_parens_unop($name, $kid, $cx);
1238 } else {
1239 return $name . ($op->flags & OPf_SPECIAL ? "()" : "");
1240 }
1241}
1242
1243sub pp_ucfirst { dq_unop(@_, "ucfirst") }
1244sub pp_lcfirst { dq_unop(@_, "lcfirst") }
1245sub pp_uc { dq_unop(@_, "uc") }
1246sub pp_lc { dq_unop(@_, "lc") }
3ed82cfc 1247sub pp_quotemeta { maybe_targmy(@_, \&dq_unop, "quotemeta") }
bd0865ec 1248
6e90668e
SM
1249sub loopex {
1250 my $self = shift;
9d2c6865 1251 my ($op, $cx, $name) = @_;
6e90668e 1252 if (class($op) eq "PVOP") {
9d2c6865
SM
1253 return "$name " . $op->pv;
1254 } elsif (class($op) eq "OP") {
1255 return $name;
6e90668e 1256 } elsif (class($op) eq "UNOP") {
9d2c6865
SM
1257 # Note -- loop exits are actually exempt from the
1258 # looks-like-a-func rule, but a few extra parens won't hurt
1259 return $self->maybe_parens_unop($name, $op->first, $cx);
6e90668e 1260 }
6e90668e
SM
1261}
1262
1263sub pp_last { loopex(@_, "last") }
1264sub pp_next { loopex(@_, "next") }
1265sub pp_redo { loopex(@_, "redo") }
1266sub pp_goto { loopex(@_, "goto") }
1267sub pp_dump { loopex(@_, "dump") }
1268
1269sub ftst {
1270 my $self = shift;
9d2c6865 1271 my($op, $cx, $name) = @_;
6e90668e 1272 if (class($op) eq "UNOP") {
9d2c6865
SM
1273 # Genuine `-X' filetests are exempt from the LLAFR, but not
1274 # l?stat(); for the sake of clarity, give'em all parens
1275 return $self->maybe_parens_unop($name, $op->first, $cx);
7934575e 1276 } elsif (class($op) eq "SVOP") {
9d2c6865 1277 return $self->maybe_parens_func($name, $self->pp_gv($op, 1), $cx, 16);
6e90668e 1278 } else { # I don't think baseop filetests ever survive ck_ftst, but...
9d2c6865 1279 return $name;
6e90668e 1280 }
6e90668e
SM
1281}
1282
1283sub pp_lstat { ftst(@_, "lstat") }
1284sub pp_stat { ftst(@_, "stat") }
1285sub pp_ftrread { ftst(@_, "-R") }
1286sub pp_ftrwrite { ftst(@_, "-W") }
1287sub pp_ftrexec { ftst(@_, "-X") }
1288sub pp_fteread { ftst(@_, "-r") }
1289sub pp_ftewrite { ftst(@_, "-r") }
1290sub pp_fteexec { ftst(@_, "-r") }
1291sub pp_ftis { ftst(@_, "-e") }
1292sub pp_fteowned { ftst(@_, "-O") }
1293sub pp_ftrowned { ftst(@_, "-o") }
1294sub pp_ftzero { ftst(@_, "-z") }
1295sub pp_ftsize { ftst(@_, "-s") }
1296sub pp_ftmtime { ftst(@_, "-M") }
1297sub pp_ftatime { ftst(@_, "-A") }
1298sub pp_ftctime { ftst(@_, "-C") }
1299sub pp_ftsock { ftst(@_, "-S") }
1300sub pp_ftchr { ftst(@_, "-c") }
1301sub pp_ftblk { ftst(@_, "-b") }
1302sub pp_ftfile { ftst(@_, "-f") }
1303sub pp_ftdir { ftst(@_, "-d") }
1304sub pp_ftpipe { ftst(@_, "-p") }
1305sub pp_ftlink { ftst(@_, "-l") }
1306sub pp_ftsuid { ftst(@_, "-u") }
1307sub pp_ftsgid { ftst(@_, "-g") }
1308sub pp_ftsvtx { ftst(@_, "-k") }
1309sub pp_fttty { ftst(@_, "-t") }
1310sub pp_fttext { ftst(@_, "-T") }
1311sub pp_ftbinary { ftst(@_, "-B") }
1312
a798dbf2 1313sub SWAP_CHILDREN () { 1 }
6e90668e
SM
1314sub ASSIGN () { 2 } # has OP= variant
1315
9d2c6865
SM
1316my(%left, %right);
1317
1318sub assoc_class {
1319 my $op = shift;
3f872cb9
GS
1320 my $name = $op->name;
1321 if ($name eq "concat" and $op->first->name eq "concat") {
9d2c6865 1322 # avoid spurious `=' -- see comment in pp_concat
3f872cb9 1323 return "concat";
9d2c6865 1324 }
3f872cb9
GS
1325 if ($name eq "null" and class($op) eq "UNOP"
1326 and $op->first->name =~ /^(and|x?or)$/
9d2c6865
SM
1327 and null $op->first->sibling)
1328 {
1329 # Like all conditional constructs, OP_ANDs and OP_ORs are topped
1330 # with a null that's used as the common end point of the two
1331 # flows of control. For precedence purposes, ignore it.
1332 # (COND_EXPRs have these too, but we don't bother with
1333 # their associativity).
1334 return assoc_class($op->first);
1335 }
1336 return $name . ($op->flags & OPf_STACKED ? "=" : "");
1337}
1338
1339# Left associative operators, like `+', for which
1340# $a + $b + $c is equivalent to ($a + $b) + $c
1341
1342BEGIN {
3f872cb9
GS
1343 %left = ('multiply' => 19, 'i_multiply' => 19,
1344 'divide' => 19, 'i_divide' => 19,
1345 'modulo' => 19, 'i_modulo' => 19,
1346 'repeat' => 19,
1347 'add' => 18, 'i_add' => 18,
1348 'subtract' => 18, 'i_subtract' => 18,
1349 'concat' => 18,
1350 'left_shift' => 17, 'right_shift' => 17,
1351 'bit_and' => 13,
1352 'bit_or' => 12, 'bit_xor' => 12,
1353 'and' => 3,
1354 'or' => 2, 'xor' => 2,
9d2c6865
SM
1355 );
1356}
1357
1358sub deparse_binop_left {
1359 my $self = shift;
1360 my($op, $left, $prec) = @_;
58231d39 1361 if ($left{assoc_class($op)} && $left{assoc_class($left)}
9d2c6865
SM
1362 and $left{assoc_class($op)} == $left{assoc_class($left)})
1363 {
1364 return $self->deparse($left, $prec - .00001);
1365 } else {
1366 return $self->deparse($left, $prec);
1367 }
1368}
1369
1370# Right associative operators, like `=', for which
1371# $a = $b = $c is equivalent to $a = ($b = $c)
1372
1373BEGIN {
3f872cb9
GS
1374 %right = ('pow' => 22,
1375 'sassign=' => 7, 'aassign=' => 7,
1376 'multiply=' => 7, 'i_multiply=' => 7,
1377 'divide=' => 7, 'i_divide=' => 7,
1378 'modulo=' => 7, 'i_modulo=' => 7,
1379 'repeat=' => 7,
1380 'add=' => 7, 'i_add=' => 7,
1381 'subtract=' => 7, 'i_subtract=' => 7,
1382 'concat=' => 7,
1383 'left_shift=' => 7, 'right_shift=' => 7,
1384 'bit_and=' => 7,
1385 'bit_or=' => 7, 'bit_xor=' => 7,
1386 'andassign' => 7,
1387 'orassign' => 7,
9d2c6865
SM
1388 );
1389}
1390
1391sub deparse_binop_right {
1392 my $self = shift;
1393 my($op, $right, $prec) = @_;
58231d39 1394 if ($right{assoc_class($op)} && $right{assoc_class($right)}
9d2c6865
SM
1395 and $right{assoc_class($op)} == $right{assoc_class($right)})
1396 {
1397 return $self->deparse($right, $prec - .00001);
1398 } else {
1399 return $self->deparse($right, $prec);
1400 }
1401}
1402
a798dbf2 1403sub binop {
6e90668e 1404 my $self = shift;
9d2c6865 1405 my ($op, $cx, $opname, $prec, $flags) = (@_, 0);
a798dbf2
MB
1406 my $left = $op->first;
1407 my $right = $op->last;
9d2c6865
SM
1408 my $eq = "";
1409 if ($op->flags & OPf_STACKED && $flags & ASSIGN) {
1410 $eq = "=";
1411 $prec = 7;
1412 }
a798dbf2
MB
1413 if ($flags & SWAP_CHILDREN) {
1414 ($left, $right) = ($right, $left);
1415 }
9d2c6865
SM
1416 $left = $self->deparse_binop_left($op, $left, $prec);
1417 $right = $self->deparse_binop_right($op, $right, $prec);
1418 return $self->maybe_parens("$left $opname$eq $right", $cx, $prec);
1419}
1420
3ed82cfc
GS
1421sub pp_add { maybe_targmy(@_, \&binop, "+", 18, ASSIGN) }
1422sub pp_multiply { maybe_targmy(@_, \&binop, "*", 19, ASSIGN) }
1423sub pp_subtract { maybe_targmy(@_, \&binop, "-",18, ASSIGN) }
1424sub pp_divide { maybe_targmy(@_, \&binop, "/", 19, ASSIGN) }
1425sub pp_modulo { maybe_targmy(@_, \&binop, "%", 19, ASSIGN) }
1426sub pp_i_add { maybe_targmy(@_, \&binop, "+", 18, ASSIGN) }
1427sub pp_i_multiply { maybe_targmy(@_, \&binop, "*", 19, ASSIGN) }
1428sub pp_i_subtract { maybe_targmy(@_, \&binop, "-", 18, ASSIGN) }
1429sub pp_i_divide { maybe_targmy(@_, \&binop, "/", 19, ASSIGN) }
1430sub pp_i_modulo { maybe_targmy(@_, \&binop, "%", 19, ASSIGN) }
1431sub pp_pow { maybe_targmy(@_, \&binop, "**", 22, ASSIGN) }
1432
1433sub pp_left_shift { maybe_targmy(@_, \&binop, "<<", 17, ASSIGN) }
1434sub pp_right_shift { maybe_targmy(@_, \&binop, ">>", 17, ASSIGN) }
1435sub pp_bit_and { maybe_targmy(@_, \&binop, "&", 13, ASSIGN) }
1436sub pp_bit_or { maybe_targmy(@_, \&binop, "|", 12, ASSIGN) }
1437sub pp_bit_xor { maybe_targmy(@_, \&binop, "^", 12, ASSIGN) }
9d2c6865
SM
1438
1439sub pp_eq { binop(@_, "==", 14) }
1440sub pp_ne { binop(@_, "!=", 14) }
1441sub pp_lt { binop(@_, "<", 15) }
1442sub pp_gt { binop(@_, ">", 15) }
1443sub pp_ge { binop(@_, ">=", 15) }
1444sub pp_le { binop(@_, "<=", 15) }
1445sub pp_ncmp { binop(@_, "<=>", 14) }
1446sub pp_i_eq { binop(@_, "==", 14) }
1447sub pp_i_ne { binop(@_, "!=", 14) }
1448sub pp_i_lt { binop(@_, "<", 15) }
1449sub pp_i_gt { binop(@_, ">", 15) }
1450sub pp_i_ge { binop(@_, ">=", 15) }
1451sub pp_i_le { binop(@_, "<=", 15) }
1452sub pp_i_ncmp { binop(@_, "<=>", 14) }
1453
1454sub pp_seq { binop(@_, "eq", 14) }
1455sub pp_sne { binop(@_, "ne", 14) }
1456sub pp_slt { binop(@_, "lt", 15) }
1457sub pp_sgt { binop(@_, "gt", 15) }
1458sub pp_sge { binop(@_, "ge", 15) }
1459sub pp_sle { binop(@_, "le", 15) }
1460sub pp_scmp { binop(@_, "cmp", 14) }
1461
1462sub pp_sassign { binop(@_, "=", 7, SWAP_CHILDREN) }
1463sub pp_aassign { binop(@_, "=", 7, SWAP_CHILDREN) }
6e90668e
SM
1464
1465# `.' is special because concats-of-concats are optimized to save copying
1466# by making all but the first concat stacked. The effect is as if the
1467# programmer had written `($a . $b) .= $c', except legal.
3ed82cfc
GS
1468sub pp_concat { maybe_targmy(@_, \&real_concat) }
1469sub real_concat {
6e90668e 1470 my $self = shift;
9d2c6865 1471 my($op, $cx) = @_;
6e90668e
SM
1472 my $left = $op->first;
1473 my $right = $op->last;
1474 my $eq = "";
9d2c6865 1475 my $prec = 18;
3f872cb9 1476 if ($op->flags & OPf_STACKED and $op->first->name ne "concat") {
6e90668e 1477 $eq = "=";
9d2c6865 1478 $prec = 7;
6e90668e 1479 }
9d2c6865
SM
1480 $left = $self->deparse_binop_left($op, $left, $prec);
1481 $right = $self->deparse_binop_right($op, $right, $prec);
1482 return $self->maybe_parens("$left .$eq $right", $cx, $prec);
6e90668e
SM
1483}
1484
1485# `x' is weird when the left arg is a list
1486sub pp_repeat {
1487 my $self = shift;
9d2c6865 1488 my($op, $cx) = @_;
6e90668e
SM
1489 my $left = $op->first;
1490 my $right = $op->last;
9d2c6865
SM
1491 my $eq = "";
1492 my $prec = 19;
1493 if ($op->flags & OPf_STACKED) {
1494 $eq = "=";
1495 $prec = 7;
1496 }
6e90668e
SM
1497 if (null($right)) { # list repeat; count is inside left-side ex-list
1498 my $kid = $left->first->sibling; # skip pushmark
1499 my @exprs;
1500 for (; !null($kid->sibling); $kid = $kid->sibling) {
9d2c6865 1501 push @exprs, $self->deparse($kid, 6);
6e90668e
SM
1502 }
1503 $right = $kid;
1504 $left = "(" . join(", ", @exprs). ")";
1505 } else {
9d2c6865 1506 $left = $self->deparse_binop_left($op, $left, $prec);
6e90668e 1507 }
9d2c6865
SM
1508 $right = $self->deparse_binop_right($op, $right, $prec);
1509 return $self->maybe_parens("$left x$eq $right", $cx, $prec);
6e90668e
SM
1510}
1511
1512sub range {
1513 my $self = shift;
9d2c6865 1514 my ($op, $cx, $type) = @_;
6e90668e
SM
1515 my $left = $op->first;
1516 my $right = $left->sibling;
9d2c6865
SM
1517 $left = $self->deparse($left, 9);
1518 $right = $self->deparse($right, 9);
1519 return $self->maybe_parens("$left $type $right", $cx, 9);
6e90668e
SM
1520}
1521
1522sub pp_flop {
1523 my $self = shift;
9d2c6865 1524 my($op, $cx) = @_;
6e90668e
SM
1525 my $flip = $op->first;
1526 my $type = ($flip->flags & OPf_SPECIAL) ? "..." : "..";
9d2c6865 1527 return $self->range($flip->first, $cx, $type);
6e90668e
SM
1528}
1529
1530# one-line while/until is handled in pp_leave
1531
1532sub logop {
1533 my $self = shift;
9d2c6865 1534 my ($op, $cx, $lowop, $lowprec, $highop, $highprec, $blockname) = @_;
6e90668e
SM
1535 my $left = $op->first;
1536 my $right = $op->first->sibling;
58cccf98
SM
1537 if ($cx == 0 and is_scope($right) and $blockname
1538 and $self->{'expand'} < 7)
1539 { # if ($a) {$b}
9d2c6865
SM
1540 $left = $self->deparse($left, 1);
1541 $right = $self->deparse($right, 0);
1542 return "$blockname ($left) {\n\t$right\n\b}\cK";
58cccf98
SM
1543 } elsif ($cx == 0 and $blockname and not $self->{'parens'}
1544 and $self->{'expand'} < 7) { # $b if $a
9d2c6865
SM
1545 $right = $self->deparse($right, 1);
1546 $left = $self->deparse($left, 1);
1547 return "$right $blockname $left";
1548 } elsif ($cx > $lowprec and $highop) { # $a && $b
1549 $left = $self->deparse_binop_left($op, $left, $highprec);
1550 $right = $self->deparse_binop_right($op, $right, $highprec);
1551 return $self->maybe_parens("$left $highop $right", $cx, $highprec);
1552 } else { # $a and $b
1553 $left = $self->deparse_binop_left($op, $left, $lowprec);
1554 $right = $self->deparse_binop_right($op, $right, $lowprec);
1555 return $self->maybe_parens("$left $lowop $right", $cx, $lowprec);
1556 }
1557}
1558
1559sub pp_and { logop(@_, "and", 3, "&&", 11, "if") }
f4a44678 1560sub pp_or { logop(@_, "or", 2, "||", 10, "unless") }
3ed82cfc
GS
1561
1562# xor is syntactically a logop, but it's really a binop (contrary to
1563# old versions of opcode.pl). Syntax is what matters here.
9d2c6865 1564sub pp_xor { logop(@_, "xor", 2, "", 0, "") }
6e90668e
SM
1565
1566sub logassignop {
1567 my $self = shift;
9d2c6865 1568 my ($op, $cx, $opname) = @_;
6e90668e
SM
1569 my $left = $op->first;
1570 my $right = $op->first->sibling->first; # skip sassign
9d2c6865
SM
1571 $left = $self->deparse($left, 7);
1572 $right = $self->deparse($right, 7);
1573 return $self->maybe_parens("$left $opname $right", $cx, 7);
a798dbf2
MB
1574}
1575
6e90668e
SM
1576sub pp_andassign { logassignop(@_, "&&=") }
1577sub pp_orassign { logassignop(@_, "||=") }
1578
1579sub listop {
1580 my $self = shift;
9d2c6865
SM
1581 my($op, $cx, $name) = @_;
1582 my(@exprs);
1583 my $parens = ($cx >= 5) || $self->{'parens'};
1584 my $kid = $op->first->sibling;
1585 return $name if null $kid;
1586 my $first = $self->deparse($kid, 6);
1587 $first = "+$first" if not $parens and substr($first, 0, 1) eq "(";
1588 push @exprs, $first;
1589 $kid = $kid->sibling;
1590 for (; !null($kid); $kid = $kid->sibling) {
1591 push @exprs, $self->deparse($kid, 6);
1592 }
1593 if ($parens) {
1594 return "$name(" . join(", ", @exprs) . ")";
1595 } else {
1596 return "$name " . join(", ", @exprs);
6e90668e 1597 }
6e90668e 1598}
a798dbf2 1599
6e90668e 1600sub pp_bless { listop(@_, "bless") }
3ed82cfc 1601sub pp_atan2 { maybe_targmy(@_, \&listop, "atan2") }
6e90668e
SM
1602sub pp_substr { maybe_local(@_, listop(@_, "substr")) }
1603sub pp_vec { maybe_local(@_, listop(@_, "vec")) }
3ed82cfc
GS
1604sub pp_index { maybe_targmy(@_, \&listop, "index") }
1605sub pp_rindex { maybe_targmy(@_, \&listop, "rindex") }
1606sub pp_sprintf { maybe_targmy(@_, \&listop, "sprintf") }
6e90668e 1607sub pp_formline { listop(@_, "formline") } # see also deparse_format
3ed82cfc 1608sub pp_crypt { maybe_targmy(@_, \&listop, "crypt") }
6e90668e
SM
1609sub pp_unpack { listop(@_, "unpack") }
1610sub pp_pack { listop(@_, "pack") }
3ed82cfc 1611sub pp_join { maybe_targmy(@_, \&listop, "join") }
6e90668e 1612sub pp_splice { listop(@_, "splice") }
3ed82cfc
GS
1613sub pp_push { maybe_targmy(@_, \&listop, "push") }
1614sub pp_unshift { maybe_targmy(@_, \&listop, "unshift") }
6e90668e
SM
1615sub pp_reverse { listop(@_, "reverse") }
1616sub pp_warn { listop(@_, "warn") }
1617sub pp_die { listop(@_, "die") }
9d2c6865
SM
1618# Actually, return is exempt from the LLAFR (see examples in this very
1619# module!), but for consistency's sake, ignore that fact
6e90668e
SM
1620sub pp_return { listop(@_, "return") }
1621sub pp_open { listop(@_, "open") }
1622sub pp_pipe_op { listop(@_, "pipe") }
1623sub pp_tie { listop(@_, "tie") }
82bafd27 1624sub pp_binmode { listop(@_, "binmode") }
6e90668e
SM
1625sub pp_dbmopen { listop(@_, "dbmopen") }
1626sub pp_sselect { listop(@_, "select") }
1627sub pp_select { listop(@_, "select") }
1628sub pp_read { listop(@_, "read") }
1629sub pp_sysopen { listop(@_, "sysopen") }
1630sub pp_sysseek { listop(@_, "sysseek") }
1631sub pp_sysread { listop(@_, "sysread") }
1632sub pp_syswrite { listop(@_, "syswrite") }
1633sub pp_send { listop(@_, "send") }
1634sub pp_recv { listop(@_, "recv") }
1635sub pp_seek { listop(@_, "seek") }
6e90668e
SM
1636sub pp_fcntl { listop(@_, "fcntl") }
1637sub pp_ioctl { listop(@_, "ioctl") }
3ed82cfc 1638sub pp_flock { maybe_targmy(@_, \&listop, "flock") }
6e90668e
SM
1639sub pp_socket { listop(@_, "socket") }
1640sub pp_sockpair { listop(@_, "sockpair") }
1641sub pp_bind { listop(@_, "bind") }
1642sub pp_connect { listop(@_, "connect") }
1643sub pp_listen { listop(@_, "listen") }
1644sub pp_accept { listop(@_, "accept") }
1645sub pp_shutdown { listop(@_, "shutdown") }
1646sub pp_gsockopt { listop(@_, "getsockopt") }
1647sub pp_ssockopt { listop(@_, "setsockopt") }
3ed82cfc
GS
1648sub pp_chown { maybe_targmy(@_, \&listop, "chown") }
1649sub pp_unlink { maybe_targmy(@_, \&listop, "unlink") }
1650sub pp_chmod { maybe_targmy(@_, \&listop, "chmod") }
1651sub pp_utime { maybe_targmy(@_, \&listop, "utime") }
1652sub pp_rename { maybe_targmy(@_, \&listop, "rename") }
1653sub pp_link { maybe_targmy(@_, \&listop, "link") }
1654sub pp_symlink { maybe_targmy(@_, \&listop, "symlink") }
1655sub pp_mkdir { maybe_targmy(@_, \&listop, "mkdir") }
6e90668e
SM
1656sub pp_open_dir { listop(@_, "opendir") }
1657sub pp_seekdir { listop(@_, "seekdir") }
3ed82cfc
GS
1658sub pp_waitpid { maybe_targmy(@_, \&listop, "waitpid") }
1659sub pp_system { maybe_targmy(@_, \&listop, "system") }
1660sub pp_exec { maybe_targmy(@_, \&listop, "exec") }
1661sub pp_kill { maybe_targmy(@_, \&listop, "kill") }
1662sub pp_setpgrp { maybe_targmy(@_, \&listop, "setpgrp") }
1663sub pp_getpriority { maybe_targmy(@_, \&listop, "getpriority") }
1664sub pp_setpriority { maybe_targmy(@_, \&listop, "setpriority") }
6e90668e
SM
1665sub pp_shmget { listop(@_, "shmget") }
1666sub pp_shmctl { listop(@_, "shmctl") }
1667sub pp_shmread { listop(@_, "shmread") }
1668sub pp_shmwrite { listop(@_, "shmwrite") }
1669sub pp_msgget { listop(@_, "msgget") }
1670sub pp_msgctl { listop(@_, "msgctl") }
1671sub pp_msgsnd { listop(@_, "msgsnd") }
1672sub pp_msgrcv { listop(@_, "msgrcv") }
1673sub pp_semget { listop(@_, "semget") }
1674sub pp_semctl { listop(@_, "semctl") }
1675sub pp_semop { listop(@_, "semop") }
1676sub pp_ghbyaddr { listop(@_, "gethostbyaddr") }
1677sub pp_gnbyaddr { listop(@_, "getnetbyaddr") }
1678sub pp_gpbynumber { listop(@_, "getprotobynumber") }
1679sub pp_gsbyname { listop(@_, "getservbyname") }
1680sub pp_gsbyport { listop(@_, "getservbyport") }
1681sub pp_syscall { listop(@_, "syscall") }
1682
1683sub pp_glob {
1684 my $self = shift;
9d2c6865 1685 my($op, $cx) = @_;
6e90668e
SM
1686 my $text = $self->dq($op->first->sibling); # skip pushmark
1687 if ($text =~ /^\$?(\w|::|\`)+$/ # could look like a readline
1688 or $text =~ /[<>]/) {
1689 return 'glob(' . single_delim('qq', '"', $text) . ')';
1690 } else {
1691 return '<' . $text . '>';
1692 }
1693}
1694
f5aa8f4e
SM
1695# Truncate is special because OPf_SPECIAL makes a bareword first arg
1696# be a filehandle. This could probably be better fixed in the core
1697# by moving the GV lookup into ck_truc.
1698
1699sub pp_truncate {
1700 my $self = shift;
1701 my($op, $cx) = @_;
1702 my(@exprs);
1703 my $parens = ($cx >= 5) || $self->{'parens'};
1704 my $kid = $op->first->sibling;
acba1d67 1705 my $fh;
f5aa8f4e
SM
1706 if ($op->flags & OPf_SPECIAL) {
1707 # $kid is an OP_CONST
18228111 1708 $fh = $self->const_sv($kid)->PV;
f5aa8f4e
SM
1709 } else {
1710 $fh = $self->deparse($kid, 6);
1711 $fh = "+$fh" if not $parens and substr($fh, 0, 1) eq "(";
1712 }
1713 my $len = $self->deparse($kid->sibling, 6);
1714 if ($parens) {
1715 return "truncate($fh, $len)";
1716 } else {
1717 return "truncate $fh, $len";
1718 }
f5aa8f4e
SM
1719}
1720
6e90668e
SM
1721sub indirop {
1722 my $self = shift;
9d2c6865 1723 my($op, $cx, $name) = @_;
6e90668e
SM
1724 my($expr, @exprs);
1725 my $kid = $op->first->sibling;
1726 my $indir = "";
1727 if ($op->flags & OPf_STACKED) {
1728 $indir = $kid;
1729 $indir = $indir->first; # skip rv2gv
1730 if (is_scope($indir)) {
9d2c6865 1731 $indir = "{" . $self->deparse($indir, 0) . "}";
6e90668e 1732 } else {
9d2c6865 1733 $indir = $self->deparse($indir, 24);
6e90668e
SM
1734 }
1735 $indir = $indir . " ";
1736 $kid = $kid->sibling;
1737 }
1738 for (; !null($kid); $kid = $kid->sibling) {
9d2c6865 1739 $expr = $self->deparse($kid, 6);
6e90668e
SM
1740 push @exprs, $expr;
1741 }
3ed82cfc 1742 return $self->maybe_parens_func($name, $indir . join(", ", @exprs),
9d2c6865 1743 $cx, 5);
6e90668e
SM
1744}
1745
1746sub pp_prtf { indirop(@_, "printf") }
1747sub pp_print { indirop(@_, "print") }
1748sub pp_sort { indirop(@_, "sort") }
1749
1750sub mapop {
1751 my $self = shift;
9d2c6865 1752 my($op, $cx, $name) = @_;
6e90668e
SM
1753 my($expr, @exprs);
1754 my $kid = $op->first; # this is the (map|grep)start
1755 $kid = $kid->first->sibling; # skip a pushmark
1756 my $code = $kid->first; # skip a null
1757 if (is_scope $code) {
f4a44678 1758 $code = "{" . $self->deparse($code, 0) . "} ";
6e90668e 1759 } else {
9d2c6865 1760 $code = $self->deparse($code, 24) . ", ";
6e90668e
SM
1761 }
1762 $kid = $kid->sibling;
1763 for (; !null($kid); $kid = $kid->sibling) {
9d2c6865 1764 $expr = $self->deparse($kid, 6);
6e90668e
SM
1765 push @exprs, $expr if $expr;
1766 }
9d2c6865 1767 return $self->maybe_parens_func($name, $code . join(", ", @exprs), $cx, 5);
6e90668e
SM
1768}
1769
1770sub pp_mapwhile { mapop(@_, "map") }
1771sub pp_grepwhile { mapop(@_, "grep") }
1772
1773sub pp_list {
1774 my $self = shift;
9d2c6865 1775 my($op, $cx) = @_;
6e90668e
SM
1776 my($expr, @exprs);
1777 my $kid = $op->first->sibling; # skip pushmark
1778 my $lop;
1779 my $local = "either"; # could be local(...) or my(...)
1780 for ($lop = $kid; !null($lop); $lop = $lop->sibling) {
1781 # This assumes that no other private flags equal 128, and that
1782 # OPs that store things other than flags in their op_private,
1783 # like OP_AELEMFAST, won't be immediate children of a list.
3f872cb9 1784 unless ($lop->private & OPpLVAL_INTRO or $lop->name eq "undef")
6e90668e
SM
1785 {
1786 $local = ""; # or not
1787 last;
1788 }
3f872cb9 1789 if ($lop->name =~ /^pad[ash]v$/) { # my()
6e90668e
SM
1790 ($local = "", last) if $local eq "local";
1791 $local = "my";
3f872cb9 1792 } elsif ($lop->name ne "undef") { # local()
6e90668e
SM
1793 ($local = "", last) if $local eq "my";
1794 $local = "local";
1795 }
1796 }
1797 $local = "" if $local eq "either"; # no point if it's all undefs
f5aa8f4e 1798 return $self->deparse($kid, $cx) if null $kid->sibling and not $local;
6e90668e
SM
1799 for (; !null($kid); $kid = $kid->sibling) {
1800 if ($local) {
3f872cb9 1801 if (class($kid) eq "UNOP" and $kid->first->name eq "gvsv") {
6e90668e
SM
1802 $lop = $kid->first;
1803 } else {
1804 $lop = $kid;
1805 }
1806 $self->{'avoid_local'}{$$lop}++;
9d2c6865 1807 $expr = $self->deparse($kid, 6);
6e90668e
SM
1808 delete $self->{'avoid_local'}{$$lop};
1809 } else {
9d2c6865 1810 $expr = $self->deparse($kid, 6);
6e90668e
SM
1811 }
1812 push @exprs, $expr;
1813 }
9d2c6865
SM
1814 if ($local) {
1815 return "$local(" . join(", ", @exprs) . ")";
1816 } else {
1817 return $self->maybe_parens( join(", ", @exprs), $cx, 6);
1818 }
6e90668e
SM
1819}
1820
6f611a1a
GS
1821sub is_ifelse_cont {
1822 my $op = shift;
1823 return ($op->name eq "null" and class($op) eq "UNOP"
1824 and $op->first->name =~ /^(and|cond_expr)$/
1825 and is_scope($op->first->first->sibling));
1826}
1827
6e90668e
SM
1828sub pp_cond_expr {
1829 my $self = shift;
9d2c6865 1830 my($op, $cx) = @_;
6e90668e
SM
1831 my $cond = $op->first;
1832 my $true = $cond->sibling;
1833 my $false = $true->sibling;
9d2c6865 1834 my $cuddle = $self->{'cuddle'};
6f611a1a 1835 unless ($cx == 0 and (is_scope($true) and $true->name ne "null") and
58cccf98
SM
1836 (is_scope($false) || is_ifelse_cont($false))
1837 and $self->{'expand'} < 7) {
f5aa8f4e 1838 $cond = $self->deparse($cond, 8);
9d2c6865
SM
1839 $true = $self->deparse($true, 8);
1840 $false = $self->deparse($false, 8);
1841 return $self->maybe_parens("$cond ? $true : $false", $cx, 8);
6f611a1a
GS
1842 }
1843
f5aa8f4e 1844 $cond = $self->deparse($cond, 1);
9d2c6865 1845 $true = $self->deparse($true, 0);
6f611a1a
GS
1846 my $head = "if ($cond) {\n\t$true\n\b}";
1847 my @elsifs;
1848 while (!null($false) and is_ifelse_cont($false)) {
1849 my $newop = $false->first;
1850 my $newcond = $newop->first;
1851 my $newtrue = $newcond->sibling;
1852 $false = $newtrue->sibling; # last in chain is OP_AND => no else
1853 $newcond = $self->deparse($newcond, 1);
1854 $newtrue = $self->deparse($newtrue, 0);
1855 push @elsifs, "elsif ($newcond) {\n\t$newtrue\n\b}";
1856 }
1857 if (!null($false)) {
1858 $false = $cuddle . "else {\n\t" .
1859 $self->deparse($false, 0) . "\n\b}\cK";
1860 } else {
1861 $false = "\cK";
6e90668e 1862 }
6f611a1a 1863 return $head . join($cuddle, "", @elsifs) . $false;
6e90668e
SM
1864}
1865
58cccf98 1866sub loop_common {
6e90668e 1867 my $self = shift;
58cccf98 1868 my($op, $cx, $init) = @_;
6e90668e
SM
1869 my $enter = $op->first;
1870 my $kid = $enter->sibling;
1871 local($self->{'curstash'}) = $self->{'curstash'};
1872 my $head = "";
9d2c6865 1873 my $bare = 0;
58cccf98
SM
1874 my $body;
1875 my $cond = undef;
3f872cb9 1876 if ($kid->name eq "lineseq") { # bare or infinite loop
6e90668e
SM
1877 if (is_state $kid->last) { # infinite
1878 $head = "for (;;) "; # shorter than while (1)
58cccf98 1879 $cond = "";
9d2c6865
SM
1880 } else {
1881 $bare = 1;
6e90668e 1882 }
58cccf98 1883 $body = $kid;
3f872cb9 1884 } elsif ($enter->name eq "enteriter") { # foreach
6e90668e
SM
1885 my $ary = $enter->first->sibling; # first was pushmark
1886 my $var = $ary->sibling;
f5aa8f4e
SM
1887 if ($enter->flags & OPf_STACKED
1888 and not null $ary->first->sibling->sibling)
1889 {
d7f5b6da
SM
1890 $ary = $self->deparse($ary->first->sibling, 9) . " .. " .
1891 $self->deparse($ary->first->sibling->sibling, 9);
d8d95777
GA
1892 } else {
1893 $ary = $self->deparse($ary, 1);
1894 }
6e90668e 1895 if (null $var) {
f6f9bdb7 1896 if ($enter->flags & OPf_SPECIAL) { # thread special var
9d2c6865 1897 $var = $self->pp_threadsv($enter, 1);
f6f9bdb7 1898 } else { # regular my() variable
9d2c6865 1899 $var = $self->pp_padsv($enter, 1);
f6f9bdb7
SM
1900 if ($self->padname_sv($enter->targ)->IVX ==
1901 $kid->first->first->sibling->last->cop_seq)
1902 {
1903 # If the scope of this variable closes at the last
1904 # statement of the loop, it must have been
1905 # declared here.
1906 $var = "my " . $var;
1907 }
6e90668e 1908 }
3f872cb9 1909 } elsif ($var->name eq "rv2gv") {
9d2c6865 1910 $var = $self->pp_rv2sv($var, 1);
3f872cb9 1911 } elsif ($var->name eq "gv") {
9d2c6865 1912 $var = "\$" . $self->deparse($var, 1);
6e90668e 1913 }
9d2c6865 1914 $head = "foreach $var ($ary) ";
58cccf98 1915 $body = $kid->first->first->sibling; # skip OP_AND and OP_ITER
3f872cb9 1916 } elsif ($kid->name eq "null") { # while/until
6e90668e 1917 $kid = $kid->first;
58cccf98
SM
1918 my $name = {"and" => "while", "or" => "until"}->{$kid->name};
1919 $cond = $self->deparse($kid->first, 1);
1920 $head = "$name ($cond) ";
1921 $body = $kid->first->sibling;
3f872cb9 1922 } elsif ($kid->name eq "stub") { # bare and empty
9d2c6865 1923 return "{;}"; # {} could be a hashref
6e90668e 1924 }
58cccf98
SM
1925 # If there isn't a continue block, then the next pointer for the loop
1926 # will point to the unstack, which is kid's penultimate child, except
1927 # in a bare loop, when it will point to the leaveloop. When neither of
1928 # these conditions hold, then the third-to-last child in the continue
1929 # block (or the last in a bare loop).
1930 my $cont_start = $enter->nextop;
1931 my $cont;
1932 if ($$cont_start != $$op and $ {$cont_start->sibling} != $ {$body->last}) {
1933 if ($bare) {
1934 $cont = $body->last;
1935 } else {
1936 $cont = $body->first;
1937 while (!null($cont->sibling->sibling->sibling)) {
1938 $cont = $cont->sibling;
1939 }
1940 }
1941 my $state = $body->first;
1942 my $cuddle = $self->{'cuddle'};
1943 my @states;
1944 for (; $$state != $$cont; $state = $state->sibling) {
1945 push @states, $state;
1946 }
1947 $body = $self->lineseq(@states);
1948 if (defined $cond and not is_scope $cont and $self->{'expand'} < 3) {
1949 $head = "for ($init; $cond; " . $self->deparse($cont, 1) .") ";
1950 $cont = "\cK";
1951 } else {
1952 $cont = $cuddle . "continue {\n\t" .
1953 $self->deparse($cont, 0) . "\n\b}\cK";
6e90668e 1954 }
6e90668e 1955 } else {
7a9b44b9 1956 return "" if !defined $body;
9d2c6865 1957 $cont = "\cK";
58cccf98 1958 $body = $self->deparse($body, 0);
6e90668e 1959 }
58cccf98
SM
1960 return $head . "{\n\t" . $body . "\n\b}" . $cont;
1961}
1962
1963sub pp_leaveloop { loop_common(@_, "") }
1964
1965sub for_loop {
1966 my $self = shift;
1967 my($op, $cx) = @_;
1968 my $init = $self->deparse($op, 1);
1969 return $self->loop_common($op->sibling, $cx, $init);
6e90668e
SM
1970}
1971
1972sub pp_leavetry {
1973 my $self = shift;
9d2c6865 1974 return "eval {\n\t" . $self->pp_leave(@_) . "\n\b}";
bd0865ec 1975}
6e90668e 1976
bd0865ec
GS
1977BEGIN { eval "sub OP_CONST () {" . opnumber("const") . "}" }
1978BEGIN { eval "sub OP_STRINGIFY () {" . opnumber("stringify") . "}" }
f5aa8f4e 1979
a798dbf2 1980sub pp_null {
6e90668e 1981 my $self = shift;
9d2c6865 1982 my($op, $cx) = @_;
6e90668e 1983 if (class($op) eq "OP") {
f4a44678
SM
1984 # old value is lost
1985 return $self->{'ex_const'} if $op->targ == OP_CONST;
3f872cb9 1986 } elsif ($op->first->name eq "pushmark") {
9d2c6865 1987 return $self->pp_list($op, $cx);
3f872cb9 1988 } elsif ($op->first->name eq "enter") {
9d2c6865 1989 return $self->pp_leave($op, $cx);
bd0865ec 1990 } elsif ($op->targ == OP_STRINGIFY) {
6f611a1a 1991 return $self->dquote($op, $cx);
6e90668e 1992 } elsif (!null($op->first->sibling) and
3f872cb9 1993 $op->first->sibling->name eq "readline" and
6e90668e 1994 $op->first->sibling->flags & OPf_STACKED) {
9d2c6865
SM
1995 return $self->maybe_parens($self->deparse($op->first, 7) . " = "
1996 . $self->deparse($op->first->sibling, 7),
1997 $cx, 7);
6e90668e 1998 } elsif (!null($op->first->sibling) and
3f872cb9 1999 $op->first->sibling->name eq "trans" and
6e90668e 2000 $op->first->sibling->flags & OPf_STACKED) {
9d2c6865
SM
2001 return $self->maybe_parens($self->deparse($op->first, 20) . " =~ "
2002 . $self->deparse($op->first->sibling, 20),
2003 $cx, 20);
6e90668e 2004 } else {
9d2c6865 2005 return $self->deparse($op->first, $cx);
6e90668e 2006 }
a798dbf2
MB
2007}
2008
6e90668e
SM
2009sub padname {
2010 my $self = shift;
2011 my $targ = shift;
68223ea3 2012 return $self->padname_sv($targ)->PVX;
6e90668e
SM
2013}
2014
2015sub padany {
2016 my $self = shift;
2017 my $op = shift;
2018 return substr($self->padname($op->targ), 1); # skip $/@/%
2019}
2020
2021sub pp_padsv {
2022 my $self = shift;
9d2c6865
SM
2023 my($op, $cx) = @_;
2024 return $self->maybe_my($op, $cx, $self->padname($op->targ));
6e90668e
SM
2025}
2026
2027sub pp_padav { pp_padsv(@_) }
2028sub pp_padhv { pp_padsv(@_) }
2029
9d2c6865
SM
2030my @threadsv_names;
2031
2032BEGIN {
2033 @threadsv_names = ("_", "1", "2", "3", "4", "5", "6", "7", "8", "9",
2034 "&", "`", "'", "+", "/", ".", ",", "\\", '"', ";",
2035 "^", "-", "%", "=", "|", "~", ":", "^A", "^E",
2036 "!", "@");
2037}
f6f9bdb7
SM
2038
2039sub pp_threadsv {
2040 my $self = shift;
9d2c6865
SM
2041 my($op, $cx) = @_;
2042 return $self->maybe_local($op, $cx, "\$" . $threadsv_names[$op->targ]);
f6f9bdb7
SM
2043}
2044
6f611a1a 2045sub gv_or_padgv {
18228111
GS
2046 my $self = shift;
2047 my $op = shift;
6f611a1a
GS
2048 if (class($op) eq "PADOP") {
2049 return $self->padval($op->padix);
2050 } else { # class($op) eq "SVOP"
2051 return $op->gv;
18228111 2052 }
18228111
GS
2053}
2054
6e90668e
SM
2055sub pp_gvsv {
2056 my $self = shift;
9d2c6865 2057 my($op, $cx) = @_;
6f611a1a 2058 my $gv = $self->gv_or_padgv($op);
18228111 2059 return $self->maybe_local($op, $cx, "\$" . $self->gv_name($gv));
6e90668e
SM
2060}
2061
2062sub pp_gv {
2063 my $self = shift;
9d2c6865 2064 my($op, $cx) = @_;
6f611a1a 2065 my $gv = $self->gv_or_padgv($op);
18228111 2066 return $self->gv_name($gv);
6e90668e
SM
2067}
2068
2069sub pp_aelemfast {
2070 my $self = shift;
9d2c6865 2071 my($op, $cx) = @_;
6f611a1a 2072 my $gv = $self->gv_or_padgv($op);
7a9b44b9
RH
2073 return "\$" . $self->gv_name($gv) . "[" .
2074 ($op->private + $self->{'arybase'}) . "]";
6e90668e
SM
2075}
2076
2077sub rv2x {
2078 my $self = shift;
9d2c6865 2079 my($op, $cx, $type) = @_;
6e90668e 2080 my $kid = $op->first;
f5aa8f4e
SM
2081 my $str = $self->deparse($kid, 0);
2082 return $type . (is_scalar($kid) ? $str : "{$str}");
6e90668e
SM
2083}
2084
2085sub pp_rv2sv { maybe_local(@_, rv2x(@_, "\$")) }
2086sub pp_rv2hv { maybe_local(@_, rv2x(@_, "%")) }
2087sub pp_rv2gv { maybe_local(@_, rv2x(@_, "*")) }
2088
2089# skip rv2av
2090sub pp_av2arylen {
2091 my $self = shift;
9d2c6865 2092 my($op, $cx) = @_;
3f872cb9 2093 if ($op->first->name eq "padav") {
9d2c6865 2094 return $self->maybe_local($op, $cx, '$#' . $self->padany($op->first));
6e90668e 2095 } else {
f5aa8f4e
SM
2096 return $self->maybe_local($op, $cx,
2097 $self->rv2x($op->first, $cx, '$#'));
6e90668e
SM
2098 }
2099}
2100
2101# skip down to the old, ex-rv2cv
9d2c6865 2102sub pp_rv2cv { $_[0]->rv2x($_[1]->first->first->sibling, $_[2], "&") }
6e90668e
SM
2103
2104sub pp_rv2av {
2105 my $self = shift;
9d2c6865 2106 my($op, $cx) = @_;
6e90668e 2107 my $kid = $op->first;
3f872cb9 2108 if ($kid->name eq "const") { # constant list
18228111 2109 my $av = $self->const_sv($kid);
6e90668e
SM
2110 return "(" . join(", ", map(const($_), $av->ARRAY)) . ")";
2111 } else {
9d2c6865 2112 return $self->maybe_local($op, $cx, $self->rv2x($op, $cx, "\@"));
6e90668e
SM
2113 }
2114 }
2115
3ed82cfc
GS
2116sub is_subscriptable {
2117 my $op = shift;
2118 if ($op->name =~ /^[ahg]elem/) {
2119 return 1;
2120 } elsif ($op->name eq "entersub") {
2121 my $kid = $op->first;
2122 return 0 unless null $kid->sibling;
2123 $kid = $kid->first;
2124 $kid = $kid->sibling until null $kid->sibling;
2125 return 0 if is_scope($kid);
2126 $kid = $kid->first;
2127 return 0 if $kid->name eq "gv";
2128 return 0 if is_scalar($kid);
2129 return is_subscriptable($kid);
2130 } else {
2131 return 0;
2132 }
2133}
6e90668e
SM
2134
2135sub elem {
2136 my $self = shift;
9d2c6865 2137 my ($op, $cx, $left, $right, $padname) = @_;
6e90668e 2138 my($array, $idx) = ($op->first, $op->first->sibling);
3f872cb9 2139 unless ($array->name eq $padname) { # Maybe this has been fixed
6e90668e
SM
2140 $array = $array->first; # skip rv2av (or ex-rv2av in _53+)
2141 }
3f872cb9 2142 if ($array->name eq $padname) {
6e90668e
SM
2143 $array = $self->padany($array);
2144 } elsif (is_scope($array)) { # ${expr}[0]
9d2c6865 2145 $array = "{" . $self->deparse($array, 0) . "}";
6e90668e 2146 } elsif (is_scalar $array) { # $x[0], $$x[0], ...
9d2c6865 2147 $array = $self->deparse($array, 24);
6e90668e
SM
2148 } else {
2149 # $x[20][3]{hi} or expr->[20]
3ed82cfc 2150 my $arrow = is_subscriptable($array) ? "" : "->";
9d2c6865
SM
2151 return $self->deparse($array, 24) . $arrow .
2152 $left . $self->deparse($idx, 1) . $right;
6e90668e 2153 }
9d2c6865 2154 $idx = $self->deparse($idx, 1);
7a9b44b9
RH
2155
2156 # Outer parens in an array index will confuse perl
2157 # if we're interpolating in a regular expression, i.e.
2158 # /$x$foo[(-1)]/ is *not* the same as /$x$foo[-1]/
2159 #
2160 # If $self->{parens}, then an initial '(' will
2161 # definitely be paired with a final ')'. If
2162 # !$self->{parens}, the misleading parens won't
2163 # have been added in the first place.
2164 #
2165 # [You might think that we could get "(...)...(...)"
2166 # where the initial and final parens do not match
2167 # each other. But we can't, because the above would
2168 # only happen if there's an infix binop between the
2169 # two pairs of parens, and *that* means that the whole
2170 # expression would be parenthesized as well.]
2171 #
2172 $idx =~ s/^\((.*)\)$/$1/ if $self->{'parens'};
2173
6e90668e
SM
2174 return "\$" . $array . $left . $idx . $right;
2175}
2176
3f872cb9
GS
2177sub pp_aelem { maybe_local(@_, elem(@_, "[", "]", "padav")) }
2178sub pp_helem { maybe_local(@_, elem(@_, "{", "}", "padhv")) }
6e90668e
SM
2179
2180sub pp_gelem {
2181 my $self = shift;
9d2c6865 2182 my($op, $cx) = @_;
6e90668e
SM
2183 my($glob, $part) = ($op->first, $op->last);
2184 $glob = $glob->first; # skip rv2gv
3f872cb9 2185 $glob = $glob->first if $glob->name eq "rv2gv"; # this one's a bug
9d2c6865
SM
2186 my $scope = is_scope($glob);
2187 $glob = $self->deparse($glob, 0);
2188 $part = $self->deparse($part, 1);
6e90668e
SM
2189 return "*" . ($scope ? "{$glob}" : $glob) . "{$part}";
2190}
2191
2192sub slice {
2193 my $self = shift;
9d2c6865 2194 my ($op, $cx, $left, $right, $regname, $padname) = @_;
6e90668e
SM
2195 my $last;
2196 my(@elems, $kid, $array, $list);
2197 if (class($op) eq "LISTOP") {
2198 $last = $op->last;
2199 } else { # ex-hslice inside delete()
2200 for ($kid = $op->first; !null $kid->sibling; $kid = $kid->sibling) {}
2201 $last = $kid;
2202 }
2203 $array = $last;
2204 $array = $array->first
3f872cb9 2205 if $array->name eq $regname or $array->name eq "null";
6e90668e 2206 if (is_scope($array)) {
9d2c6865 2207 $array = "{" . $self->deparse($array, 0) . "}";
3f872cb9 2208 } elsif ($array->name eq $padname) {
6e90668e
SM
2209 $array = $self->padany($array);
2210 } else {
9d2c6865 2211 $array = $self->deparse($array, 24);
6e90668e
SM
2212 }
2213 $kid = $op->first->sibling; # skip pushmark
3f872cb9 2214 if ($kid->name eq "list") {
6e90668e
SM
2215 $kid = $kid->first->sibling; # skip list, pushmark
2216 for (; !null $kid; $kid = $kid->sibling) {
9d2c6865 2217 push @elems, $self->deparse($kid, 6);
6e90668e
SM
2218 }
2219 $list = join(", ", @elems);
2220 } else {
9d2c6865 2221 $list = $self->deparse($kid, 1);
6e90668e
SM
2222 }
2223 return "\@" . $array . $left . $list . $right;
2224}
2225
3ed82cfc
GS
2226sub pp_aslice { maybe_local(@_, slice(@_, "[", "]", "rv2av", "padav")) }
2227sub pp_hslice { maybe_local(@_, slice(@_, "{", "}", "rv2hv", "padhv")) }
6e90668e
SM
2228
2229sub pp_lslice {
2230 my $self = shift;
9d2c6865 2231 my($op, $cx) = @_;
6e90668e
SM
2232 my $idx = $op->first;
2233 my $list = $op->last;
2234 my(@elems, $kid);
9d2c6865
SM
2235 $list = $self->deparse($list, 1);
2236 $idx = $self->deparse($idx, 1);
2237 return "($list)" . "[$idx]";
6e90668e
SM
2238}
2239
6e90668e
SM
2240sub want_scalar {
2241 my $op = shift;
2242 return ($op->flags & OPf_WANT) == OPf_WANT_SCALAR;
2243}
2244
bd0865ec
GS
2245sub want_list {
2246 my $op = shift;
2247 return ($op->flags & OPf_WANT) == OPf_WANT_LIST;
2248}
2249
2250sub method {
6e90668e 2251 my $self = shift;
9d2c6865 2252 my($op, $cx) = @_;
bd0865ec
GS
2253 my $kid = $op->first->sibling; # skip pushmark
2254 my($meth, $obj, @exprs);
3f872cb9 2255 if ($kid->name eq "list" and want_list $kid) {
bd0865ec
GS
2256 # When an indirect object isn't a bareword but the args are in
2257 # parens, the parens aren't part of the method syntax (the LLAFR
2258 # doesn't apply), but they make a list with OPf_PARENS set that
2259 # doesn't get flattened by the append_elem that adds the method,
2260 # making a (object, arg1, arg2, ...) list where the object
2261 # usually is. This can be distinguished from
2262 # `($obj, $arg1, $arg2)->meth()' (which is legal if $arg2 is an
2263 # object) because in the later the list is in scalar context
2264 # as the left side of -> always is, while in the former
2265 # the list is in list context as method arguments always are.
2266 # (Good thing there aren't method prototypes!)
3ed82cfc 2267 $meth = $kid->sibling;
bd0865ec
GS
2268 $kid = $kid->first->sibling; # skip pushmark
2269 $obj = $kid;
6e90668e 2270 $kid = $kid->sibling;
bd0865ec 2271 for (; not null $kid; $kid = $kid->sibling) {
9d2c6865 2272 push @exprs, $self->deparse($kid, 6);
6e90668e 2273 }
bd0865ec
GS
2274 } else {
2275 $obj = $kid;
2276 $kid = $kid->sibling;
2277 for (; not null $kid->sibling; $kid = $kid->sibling) {
2278 push @exprs, $self->deparse($kid, 6);
6e90668e 2279 }
3ed82cfc 2280 $meth = $kid;
bd0865ec
GS
2281 }
2282 $obj = $self->deparse($obj, 24);
3ed82cfc 2283 if ($meth->name eq "method_named") {
18228111 2284 $meth = $self->const_sv($meth)->PV;
bd0865ec 2285 } else {
3ed82cfc
GS
2286 $meth = $meth->first;
2287 if ($meth->name eq "const") {
2288 # As of 5.005_58, this case is probably obsoleted by the
2289 # method_named case above
18228111 2290 $meth = $self->const_sv($meth)->PV; # needs to be bare
3ed82cfc
GS
2291 } else {
2292 $meth = $self->deparse($meth, 1);
2293 }
bd0865ec
GS
2294 }
2295 my $args = join(", ", @exprs);
2296 $kid = $obj . "->" . $meth;
2297 if ($args) {
2298 return $kid . "(" . $args . ")"; # parens mandatory
2299 } else {
2300 return $kid;
2301 }
2302}
2303
2304# returns "&" if the prototype doesn't match the args,
2305# or ("", $args_after_prototype_demunging) if it does.
2306sub check_proto {
2307 my $self = shift;
2308 my($proto, @args) = @_;
2309 my($arg, $real);
2310 my $doneok = 0;
2311 my @reals;
2312 # An unbackslashed @ or % gobbles up the rest of the args
2313 $proto =~ s/([^\\]|^)([@%])(.*)$/$1$2/;
2314 while ($proto) {
2315 $proto =~ s/^ *([\\]?[\$\@&%*]|;)//;
2316 my $chr = $1;
2317 if ($chr eq "") {
2318 return "&" if @args;
2319 } elsif ($chr eq ";") {
2320 $doneok = 1;
2321 } elsif ($chr eq "@" or $chr eq "%") {
2322 push @reals, map($self->deparse($_, 6), @args);
2323 @args = ();
6e90668e 2324 } else {
bd0865ec
GS
2325 $arg = shift @args;
2326 last unless $arg;
2327 if ($chr eq "\$") {
2328 if (want_scalar $arg) {
2329 push @reals, $self->deparse($arg, 6);
2330 } else {
2331 return "&";
2332 }
2333 } elsif ($chr eq "&") {
3f872cb9 2334 if ($arg->name =~ /^(s?refgen|undef)$/) {
bd0865ec
GS
2335 push @reals, $self->deparse($arg, 6);
2336 } else {
2337 return "&";
2338 }
2339 } elsif ($chr eq "*") {
3f872cb9
GS
2340 if ($arg->name =~ /^s?refgen$/
2341 and $arg->first->first->name eq "rv2gv")
bd0865ec
GS
2342 {
2343 $real = $arg->first->first; # skip refgen, null
3f872cb9 2344 if ($real->first->name eq "gv") {
bd0865ec
GS
2345 push @reals, $self->deparse($real, 6);
2346 } else {
2347 push @reals, $self->deparse($real->first, 6);
2348 }
2349 } else {
2350 return "&";
2351 }
2352 } elsif (substr($chr, 0, 1) eq "\\") {
2353 $chr = substr($chr, 1);
3f872cb9 2354 if ($arg->name =~ /^s?refgen$/ and
bd0865ec
GS
2355 !null($real = $arg->first) and
2356 ($chr eq "\$" && is_scalar($real->first)
2357 or ($chr eq "\@"
3f872cb9
GS
2358 && $real->first->sibling->name
2359 =~ /^(rv2|pad)av$/)
bd0865ec 2360 or ($chr eq "%"
3f872cb9
GS
2361 && $real->first->sibling->name
2362 =~ /^(rv2|pad)hv$/)
bd0865ec 2363 #or ($chr eq "&" # This doesn't work
3f872cb9 2364 # && $real->first->name eq "rv2cv")
bd0865ec 2365 or ($chr eq "*"
3f872cb9 2366 && $real->first->name eq "rv2gv")))
bd0865ec
GS
2367 {
2368 push @reals, $self->deparse($real, 6);
2369 } else {
2370 return "&";
2371 }
2372 }
2373 }
9d2c6865 2374 }
bd0865ec
GS
2375 return "&" if $proto and !$doneok; # too few args and no `;'
2376 return "&" if @args; # too many args
2377 return ("", join ", ", @reals);
2378}
2379
2380sub pp_entersub {
2381 my $self = shift;
2382 my($op, $cx) = @_;
2383 return $self->method($op, $cx) unless null $op->first->sibling;
2384 my $prefix = "";
2385 my $amper = "";
2386 my($kid, @exprs);
9d2c6865
SM
2387 if ($op->flags & OPf_SPECIAL) {
2388 $prefix = "do ";
2389 } elsif ($op->private & OPpENTERSUB_AMPER) {
2390 $amper = "&";
2391 }
2392 $kid = $op->first;
2393 $kid = $kid->first->sibling; # skip ex-list, pushmark
2394 for (; not null $kid->sibling; $kid = $kid->sibling) {
2395 push @exprs, $kid;
2396 }
bd0865ec
GS
2397 my $simple = 0;
2398 my $proto = undef;
9d2c6865
SM
2399 if (is_scope($kid)) {
2400 $amper = "&";
2401 $kid = "{" . $self->deparse($kid, 0) . "}";
3f872cb9 2402 } elsif ($kid->first->name eq "gv") {
6f611a1a 2403 my $gv = $self->gv_or_padgv($kid->first);
9d2c6865
SM
2404 if (class($gv->CV) ne "SPECIAL") {
2405 $proto = $gv->CV->PV if $gv->CV->FLAGS & SVf_POK;
2406 }
bd0865ec 2407 $simple = 1; # only calls of named functions can be prototyped
9d2c6865
SM
2408 $kid = $self->deparse($kid, 24);
2409 } elsif (is_scalar $kid->first) {
2410 $amper = "&";
2411 $kid = $self->deparse($kid, 24);
2412 } else {
2413 $prefix = "";
3ed82cfc
GS
2414 my $arrow = is_subscriptable($kid->first) ? "" : "->";
2415 $kid = $self->deparse($kid, 24) . $arrow;
9d2c6865 2416 }
bd0865ec 2417 my $args;
9d2c6865 2418 if (defined $proto and not $amper) {
bd0865ec
GS
2419 ($amper, $args) = $self->check_proto($proto, @exprs);
2420 if ($amper eq "&") {
9d2c6865
SM
2421 $args = join(", ", map($self->deparse($_, 6), @exprs));
2422 }
2423 } else {
2424 $args = join(", ", map($self->deparse($_, 6), @exprs));
6e90668e 2425 }
9d2c6865
SM
2426 if ($prefix or $amper) {
2427 if ($op->flags & OPf_STACKED) {
2428 return $prefix . $amper . $kid . "(" . $args . ")";
2429 } else {
2430 return $prefix . $amper. $kid;
2431 }
6e90668e 2432 } else {
9d2c6865
SM
2433 if (defined $proto and $proto eq "") {
2434 return $kid;
6f611a1a 2435 } elsif (defined $proto and $proto eq "\$") {
9d2c6865 2436 return $self->maybe_parens_func($kid, $args, $cx, 16);
6f611a1a 2437 } elsif (defined($proto) && $proto or $simple) {
9d2c6865
SM
2438 return $self->maybe_parens_func($kid, $args, $cx, 5);
2439 } else {
2440 return "$kid(" . $args . ")";
2441 }
6e90668e
SM
2442 }
2443}
2444
2445sub pp_enterwrite { unop(@_, "write") }
2446
2447# escape things that cause interpolation in double quotes,
2448# but not character escapes
2449sub uninterp {
2450 my($str) = @_;
9d2c6865
SM
2451 $str =~ s/(^|[^\\])([\$\@]|\\[uUlLQE])/$1\\$2/g;
2452 return $str;
2453}
2454
2455# the same, but treat $|, $), and $ at the end of the string differently
2456sub re_uninterp {
2457 my($str) = @_;
2458 $str =~ s/(^|[^\\])(\@|\\[uUlLQE])/$1\\$2/g;
2459 $str =~ s/(^|[^\\])(\$[^)|])/$1\\$2/g;
6e90668e
SM
2460 return $str;
2461}
2462
2463# character escapes, but not delimiters that might need to be escaped
2464sub escape_str { # ASCII
2465 my($str) = @_;
6e90668e
SM
2466 $str =~ s/\a/\\a/g;
2467# $str =~ s/\cH/\\b/g; # \b means someting different in a regex
2468 $str =~ s/\t/\\t/g;
2469 $str =~ s/\n/\\n/g;
2470 $str =~ s/\e/\\e/g;
2471 $str =~ s/\f/\\f/g;
2472 $str =~ s/\r/\\r/g;
2473 $str =~ s/([\cA-\cZ])/'\\c' . chr(ord('@') + ord($1))/ge;
2474 $str =~ s/([\0\033-\037\177-\377])/'\\' . sprintf("%03o", ord($1))/ge;
2475 return $str;
2476}
2477
9d2c6865
SM
2478# Don't do this for regexen
2479sub unback {
2480 my($str) = @_;
2481 $str =~ s/\\/\\\\/g;
2482 return $str;
2483}
2484
08c6f5ec
RH
2485# Remove backslashes which precede literal control characters,
2486# to avoid creating ambiguity when we escape the latter.
2487sub re_unback {
2488 my($str) = @_;
2489
2490 # the insane complexity here is due to the behaviour of "\c\"
2491 $str =~ s/(^|[^\\]|\\c\\)(?<!\\c)\\(\\\\)*(?=[\0-\031\177-\377])/$1$2/g;
2492 return $str;
2493}
2494
6e90668e
SM
2495sub balanced_delim {
2496 my($str) = @_;
2497 my @str = split //, $str;
2498 my($ar, $open, $close, $fail, $c, $cnt);
2499 for $ar (['[',']'], ['(',')'], ['<','>'], ['{','}']) {
2500 ($open, $close) = @$ar;
2501 $fail = 0; $cnt = 0;
2502 for $c (@str) {
2503 if ($c eq $open) {
2504 $cnt++;
2505 } elsif ($c eq $close) {
2506 $cnt--;
2507 if ($cnt < 0) {
bd0865ec 2508 # qq()() isn't ")("
6e90668e
SM
2509 $fail = 1;
2510 last;
2511 }
2512 }
2513 }
2514 $fail = 1 if $cnt != 0;
2515 return ($open, "$open$str$close") if not $fail;
2516 }
2517 return ("", $str);
2518}
2519
2520sub single_delim {
2521 my($q, $default, $str) = @_;
90be192f 2522 return "$default$str$default" if $default and index($str, $default) == -1;
6e90668e
SM
2523 my($succeed, $delim);
2524 ($succeed, $str) = balanced_delim($str);
2525 return "$q$str" if $succeed;
2526 for $delim ('/', '"', '#') {
2527 return "$q$delim" . $str . $delim if index($str, $delim) == -1;
2528 }
90be192f
SM
2529 if ($default) {
2530 $str =~ s/$default/\\$default/g;
2531 return "$default$str$default";
2532 } else {
2533 $str =~ s[/][\\/]g;
2534 return "$q/$str/";
2535 }
6e90668e
SM
2536}
2537
6e90668e
SM
2538sub const {
2539 my $sv = shift;
2540 if (class($sv) eq "SPECIAL") {
bd0865ec 2541 return ('undef', '1', '0')[$$sv-1]; # sv_undef, sv_yes, sv_no
7a9b44b9
RH
2542 } elsif (class($sv) eq "NULL") {
2543 return 'undef';
6e90668e 2544 } elsif ($sv->FLAGS & SVf_IOK) {
d9963e60 2545 return $sv->int_value;
6e90668e 2546 } elsif ($sv->FLAGS & SVf_NOK) {
a798dbf2 2547 return $sv->NV;
7a9b44b9 2548 } elsif ($sv->FLAGS & SVf_ROK && $sv->can("RV")) {
6e90668e 2549 return "\\(" . const($sv->RV) . ")"; # constant folded
a798dbf2 2550 } else {
6e90668e 2551 my $str = $sv->PV;
bd0865ec 2552 if ($str =~ /[^ -~]/) { # ASCII for non-printing
9d2c6865 2553 return single_delim("qq", '"', uninterp escape_str unback $str);
6e90668e 2554 } else {
bd0865ec 2555 return single_delim("q", "'", unback $str);
6e90668e 2556 }
a798dbf2
MB
2557 }
2558}
2559
18228111
GS
2560sub const_sv {
2561 my $self = shift;
2562 my $op = shift;
2563 my $sv = $op->sv;
2564 # the constant could be in the pad (under useithreads)
2565 $sv = $self->padval($op->targ) unless $$sv;
2566 return $sv;
2567}
2568
6e90668e
SM
2569sub pp_const {
2570 my $self = shift;
9d2c6865 2571 my($op, $cx) = @_;
4c1f658f 2572# if ($op->private & OPpCONST_BARE) { # trouble with `=>' autoquoting
18228111 2573# return $self->const_sv($op)->PV;
6e90668e 2574# }
18228111 2575 my $sv = $self->const_sv($op);
d5ae42cc 2576# return const($sv);
7a9b44b9
RH
2577 if ($op->private & OPpCONST_ARYBASE) {
2578 return '$[';
2579 }
d5ae42cc 2580 my $c = const $sv;
76ef7183 2581 return $c =~ /^-\d/ ? $self->maybe_parens($c, $cx, 21) : $c;
6e90668e
SM
2582}
2583
2584sub dq {
2585 my $self = shift;
2586 my $op = shift;
3f872cb9
GS
2587 my $type = $op->name;
2588 if ($type eq "const") {
18228111 2589 return uninterp(escape_str(unback($self->const_sv($op)->PV)));
3f872cb9 2590 } elsif ($type eq "concat") {
8fed1104
RH
2591 my $first = $self->dq($op->first);
2592 my $last = $self->dq($op->last);
2593 # Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]"
2594 if ($last =~ /^[{\[\w]/) {
2595 $first =~ s/([%\$@])([A-Za-z_]\w*)$/${1}{$2}/;
2596 }
2597 return $first . $last;
3f872cb9 2598 } elsif ($type eq "uc") {
6e90668e 2599 return '\U' . $self->dq($op->first->sibling) . '\E';
3f872cb9 2600 } elsif ($type eq "lc") {
6e90668e 2601 return '\L' . $self->dq($op->first->sibling) . '\E';
3f872cb9 2602 } elsif ($type eq "ucfirst") {
6e90668e 2603 return '\u' . $self->dq($op->first->sibling);
3f872cb9 2604 } elsif ($type eq "lcfirst") {
6e90668e 2605 return '\l' . $self->dq($op->first->sibling);
3f872cb9 2606 } elsif ($type eq "quotemeta") {
6e90668e 2607 return '\Q' . $self->dq($op->first->sibling) . '\E';
3f872cb9 2608 } elsif ($type eq "join") {
9d2c6865 2609 return $self->deparse($op->last, 26); # was join($", @ary)
a798dbf2 2610 } else {
9d2c6865 2611 return $self->deparse($op, 26);
6e90668e
SM
2612 }
2613}
2614
2615sub pp_backtick {
2616 my $self = shift;
9d2c6865 2617 my($op, $cx) = @_;
6e90668e
SM
2618 # skip pushmark
2619 return single_delim("qx", '`', $self->dq($op->first->sibling));
2620}
2621
2622sub dquote {
2623 my $self = shift;
6f611a1a 2624 my($op, $cx) = @_;
3ed82cfc
GS
2625 my $kid = $op->first->sibling; # skip ex-stringify, pushmark
2626 return $self->deparse($kid, $cx) if $self->{'unquote'};
2627 $self->maybe_targmy($kid, $cx,
2628 sub {single_delim("qq", '"', $self->dq($_[1]))});
6e90668e
SM
2629}
2630
bd0865ec 2631# OP_STRINGIFY is a listop, but it only ever has one arg
3ed82cfc 2632sub pp_stringify { maybe_targmy(@_, \&dquote) }
6e90668e
SM
2633
2634# tr/// and s/// (and tr[][], tr[]//, tr###, etc)
2635# note that tr(from)/to/ is OK, but not tr/from/(to)
2636sub double_delim {
2637 my($from, $to) = @_;
2638 my($succeed, $delim);
2639 if ($from !~ m[/] and $to !~ m[/]) {
2640 return "/$from/$to/";
2641 } elsif (($succeed, $from) = balanced_delim($from) and $succeed) {
2642 if (($succeed, $to) = balanced_delim($to) and $succeed) {
2643 return "$from$to";
2644 } else {
2645 for $delim ('/', '"', '#') { # note no `'' -- s''' is special
2646 return "$from$delim$to$delim" if index($to, $delim) == -1;
2647 }
2648 $to =~ s[/][\\/]g;
2649 return "$from/$to/";
2650 }
2651 } else {
2652 for $delim ('/', '"', '#') { # note no '
2653 return "$delim$from$delim$to$delim"
2654 if index($to . $from, $delim) == -1;
2655 }
2656 $from =~ s[/][\\/]g;
2657 $to =~ s[/][\\/]g;
2658 return "/$from/$to/";
2659 }
2660}
2661
2662sub pchr { # ASCII
2663 my($n) = @_;
2664 if ($n == ord '\\') {
2665 return '\\\\';
2666 } elsif ($n >= ord(' ') and $n <= ord('~')) {
2667 return chr($n);
2668 } elsif ($n == ord "\a") {
2669 return '\\a';
2670 } elsif ($n == ord "\b") {
2671 return '\\b';
2672 } elsif ($n == ord "\t") {
2673 return '\\t';
2674 } elsif ($n == ord "\n") {
2675 return '\\n';
2676 } elsif ($n == ord "\e") {
2677 return '\\e';
2678 } elsif ($n == ord "\f") {
2679 return '\\f';
2680 } elsif ($n == ord "\r") {
2681 return '\\r';
2682 } elsif ($n >= ord("\cA") and $n <= ord("\cZ")) {
2683 return '\\c' . chr(ord("@") + $n);
2684 } else {
2685# return '\x' . sprintf("%02x", $n);
2686 return '\\' . sprintf("%03o", $n);
2687 }
2688}
2689
2690sub collapse {
2691 my(@chars) = @_;
23db111c 2692 my($str, $c, $tr) = ("");
6e90668e
SM
2693 for ($c = 0; $c < @chars; $c++) {
2694 $tr = $chars[$c];
2695 $str .= pchr($tr);
2696 if ($c <= $#chars - 2 and $chars[$c + 1] == $tr + 1 and
2697 $chars[$c + 2] == $tr + 2)
2698 {
f4a44678
SM
2699 for (; $c <= $#chars-1 and $chars[$c + 1] == $chars[$c] + 1; $c++)
2700 {}
6e90668e
SM
2701 $str .= "-";
2702 $str .= pchr($chars[$c]);
2703 }
2704 }
2705 return $str;
2706}
2707
f4a44678
SM
2708# XXX This has trouble with hyphens in the replacement (tr/bac/-AC/),
2709# and backslashes.
2710
2711sub tr_decode_byte {
2712 my($table, $flags) = @_;
2713 my(@table) = unpack("s256", $table);
6e90668e
SM
2714 my($c, $tr, @from, @to, @delfrom, $delhyphen);
2715 if ($table[ord "-"] != -1 and
2716 $table[ord("-") - 1] == -1 || $table[ord("-") + 1] == -1)
2717 {
2718 $tr = $table[ord "-"];
2719 $table[ord "-"] = -1;
2720 if ($tr >= 0) {
2721 @from = ord("-");
2722 @to = $tr;
2723 } else { # -2 ==> delete
2724 $delhyphen = 1;
2725 }
2726 }
2727 for ($c = 0; $c < 256; $c++) {
2728 $tr = $table[$c];
2729 if ($tr >= 0) {
2730 push @from, $c; push @to, $tr;
2731 } elsif ($tr == -2) {
2732 push @delfrom, $c;
2733 }
2734 }
6e90668e 2735 @from = (@from, @delfrom);
f4a44678 2736 if ($flags & OPpTRANS_COMPLEMENT) {
6e90668e
SM
2737 my @newfrom = ();
2738 my %from;
2739 @from{@from} = (1) x @from;
2740 for ($c = 0; $c < 256; $c++) {
2741 push @newfrom, $c unless $from{$c};
2742 }
2743 @from = @newfrom;
2744 }
56d8b52c 2745 unless ($flags & OPpTRANS_DELETE || !@to) {
6e90668e
SM
2746 pop @to while $#to and $to[$#to] == $to[$#to -1];
2747 }
6e90668e
SM
2748 my($from, $to);
2749 $from = collapse(@from);
2750 $to = collapse(@to);
2751 $from .= "-" if $delhyphen;
f4a44678
SM
2752 return ($from, $to);
2753}
2754
2755sub tr_chr {
2756 my $x = shift;
2757 if ($x == ord "-") {
2758 return "\\-";
2759 } else {
2760 return chr $x;
2761 }
2762}
2763
2764# XXX This doesn't yet handle all cases correctly either
2765
2766sub tr_decode_utf8 {
2767 my($swash_hv, $flags) = @_;
2768 my %swash = $swash_hv->ARRAY;
2769 my $final = undef;
2770 $final = $swash{'FINAL'}->IV if exists $swash{'FINAL'};
2771 my $none = $swash{"NONE"}->IV;
2772 my $extra = $none + 1;
2773 my(@from, @delfrom, @to);
2774 my $line;
2775 foreach $line (split /\n/, $swash{'LIST'}->PV) {
2776 my($min, $max, $result) = split(/\t/, $line);
2777 $min = hex $min;
2778 if (length $max) {
2779 $max = hex $max;
2780 } else {
2781 $max = $min;
2782 }
2783 $result = hex $result;
2784 if ($result == $extra) {
2785 push @delfrom, [$min, $max];
2786 } else {
2787 push @from, [$min, $max];
2788 push @to, [$result, $result + $max - $min];
2789 }
2790 }
2791 for my $i (0 .. $#from) {
2792 if ($from[$i][0] == ord '-') {
2793 unshift @from, splice(@from, $i, 1);
2794 unshift @to, splice(@to, $i, 1);
2795 last;
2796 } elsif ($from[$i][1] == ord '-') {
2797 $from[$i][1]--;
2798 $to[$i][1]--;
2799 unshift @from, ord '-';
2800 unshift @to, ord '-';
2801 last;
2802 }
2803 }
2804 for my $i (0 .. $#delfrom) {
2805 if ($delfrom[$i][0] == ord '-') {
2806 push @delfrom, splice(@delfrom, $i, 1);
2807 last;
2808 } elsif ($delfrom[$i][1] == ord '-') {
2809 $delfrom[$i][1]--;
2810 push @delfrom, ord '-';
2811 last;
2812 }
2813 }
2814 if (defined $final and $to[$#to][1] != $final) {
2815 push @to, [$final, $final];
2816 }
2817 push @from, @delfrom;
2818 if ($flags & OPpTRANS_COMPLEMENT) {
2819 my @newfrom;
2820 my $next = 0;
2821 for my $i (0 .. $#from) {
2822 push @newfrom, [$next, $from[$i][0] - 1];
2823 $next = $from[$i][1] + 1;
2824 }
2825 @from = ();
2826 for my $range (@newfrom) {
2827 if ($range->[0] <= $range->[1]) {
2828 push @from, $range;
2829 }
2830 }
2831 }
2832 my($from, $to, $diff);
2833 for my $chunk (@from) {
2834 $diff = $chunk->[1] - $chunk->[0];
2835 if ($diff > 1) {
2836 $from .= tr_chr($chunk->[0]) . "-" . tr_chr($chunk->[1]);
2837 } elsif ($diff == 1) {
2838 $from .= tr_chr($chunk->[0]) . tr_chr($chunk->[1]);
2839 } else {
2840 $from .= tr_chr($chunk->[0]);
2841 }
2842 }
2843 for my $chunk (@to) {
2844 $diff = $chunk->[1] - $chunk->[0];
2845 if ($diff > 1) {
2846 $to .= tr_chr($chunk->[0]) . "-" . tr_chr($chunk->[1]);
2847 } elsif ($diff == 1) {
2848 $to .= tr_chr($chunk->[0]) . tr_chr($chunk->[1]);
2849 } else {
2850 $to .= tr_chr($chunk->[0]);
2851 }
2852 }
2853 #$final = sprintf("%04x", $final) if defined $final;
2854 #$none = sprintf("%04x", $none) if defined $none;
2855 #$extra = sprintf("%04x", $extra) if defined $extra;
2856 #print STDERR "final: $final\n none: $none\nextra: $extra\n";
2857 #print STDERR $swash{'LIST'}->PV;
2858 return (escape_str($from), escape_str($to));
2859}
2860
2861sub pp_trans {
2862 my $self = shift;
2863 my($op, $cx) = @_;
2864 my($from, $to);
2865 if (class($op) eq "PVOP") {
2866 ($from, $to) = tr_decode_byte($op->pv, $op->private);
2867 } else { # class($op) eq "SVOP"
2868 ($from, $to) = tr_decode_utf8($op->sv->RV, $op->private);
2869 }
2870 my $flags = "";
2871 $flags .= "c" if $op->private & OPpTRANS_COMPLEMENT;
2872 $flags .= "d" if $op->private & OPpTRANS_DELETE;
2873 $to = "" if $from eq $to and $flags eq "";
2874 $flags .= "s" if $op->private & OPpTRANS_SQUASH;
6e90668e
SM
2875 return "tr" . double_delim($from, $to) . $flags;
2876}
2877
2878# Like dq(), but different
2879sub re_dq {
2880 my $self = shift;
2881 my $op = shift;
3f872cb9
GS
2882 my $type = $op->name;
2883 if ($type eq "const") {
08c6f5ec 2884 return re_uninterp(escape_str(re_unback($self->const_sv($op)->PV)));
3f872cb9 2885 } elsif ($type eq "concat") {
a0e66df8
RH
2886 my $first = $self->re_dq($op->first);
2887 my $last = $self->re_dq($op->last);
2888 # Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]"
2889 if ($last =~ /^[{\[\w]/) {
2890 $first =~ s/([%\$@])([A-Za-z_]\w*)$/${1}{$2}/;
2891 }
2892 return $first . $last;
3f872cb9 2893 } elsif ($type eq "uc") {
6e90668e 2894 return '\U' . $self->re_dq($op->first->sibling) . '\E';
3f872cb9 2895 } elsif ($type eq "lc") {
6e90668e 2896 return '\L' . $self->re_dq($op->first->sibling) . '\E';
3f872cb9 2897 } elsif ($type eq "ucfirst") {
6e90668e 2898 return '\u' . $self->re_dq($op->first->sibling);
3f872cb9 2899 } elsif ($type eq "lcfirst") {
6e90668e 2900 return '\l' . $self->re_dq($op->first->sibling);
3f872cb9 2901 } elsif ($type eq "quotemeta") {
6e90668e 2902 return '\Q' . $self->re_dq($op->first->sibling) . '\E';
3f872cb9 2903 } elsif ($type eq "join") {
9d2c6865 2904 return $self->deparse($op->last, 26); # was join($", @ary)
6e90668e 2905 } else {
9d2c6865 2906 return $self->deparse($op, 26);
6e90668e
SM
2907 }
2908}
2909
2910sub pp_regcomp {
2911 my $self = shift;
9d2c6865 2912 my($op, $cx) = @_;
6e90668e 2913 my $kid = $op->first;
3f872cb9
GS
2914 $kid = $kid->first if $kid->name eq "regcmaybe";
2915 $kid = $kid->first if $kid->name eq "regcreset";
6e90668e
SM
2916 return $self->re_dq($kid);
2917}
2918
6e90668e
SM
2919# osmic acid -- see osmium tetroxide
2920
2921my %matchwords;
2922map($matchwords{join "", sort split //, $_} = $_, 'cig', 'cog', 'cos', 'cogs',
2923 'cox', 'go', 'is', 'ism', 'iso', 'mig', 'mix', 'osmic', 'ox', 'sic',
2924 'sig', 'six', 'smog', 'so', 'soc', 'sog', 'xi');
2925
90be192f 2926sub matchop {
6e90668e 2927 my $self = shift;
90be192f 2928 my($op, $cx, $name, $delim) = @_;
6e90668e 2929 my $kid = $op->first;
9d2c6865 2930 my ($binop, $var, $re) = ("", "", "");
6e90668e 2931 if ($op->flags & OPf_STACKED) {
9d2c6865
SM
2932 $binop = 1;
2933 $var = $self->deparse($kid, 20);
6e90668e
SM
2934 $kid = $kid->sibling;
2935 }
2936 if (null $kid) {
08c6f5ec 2937 $re = re_uninterp(escape_str(re_unback($op->precomp)));
6e90668e 2938 } else {
9d2c6865 2939 $re = $self->deparse($kid, 1);
6e90668e
SM
2940 }
2941 my $flags = "";
2942 $flags .= "c" if $op->pmflags & PMf_CONTINUE;
2943 $flags .= "g" if $op->pmflags & PMf_GLOBAL;
2944 $flags .= "i" if $op->pmflags & PMf_FOLD;
2945 $flags .= "m" if $op->pmflags & PMf_MULTILINE;
2946 $flags .= "o" if $op->pmflags & PMf_KEEP;
2947 $flags .= "s" if $op->pmflags & PMf_SINGLELINE;
2948 $flags .= "x" if $op->pmflags & PMf_EXTENDED;
2949 $flags = $matchwords{$flags} if $matchwords{$flags};
2950 if ($op->pmflags & PMf_ONCE) { # only one kind of delimiter works here
2951 $re =~ s/\?/\\?/g;
9d2c6865
SM
2952 $re = "?$re?";
2953 } else {
90be192f 2954 $re = single_delim($name, $delim, $re);
9d2c6865
SM
2955 }
2956 $re = $re . $flags;
2957 if ($binop) {
2958 return $self->maybe_parens("$var =~ $re", $cx, 20);
2959 } else {
2960 return $re;
6e90668e 2961 }
6e90668e
SM
2962}
2963
90be192f
SM
2964sub pp_match { matchop(@_, "m", "/") }
2965sub pp_pushre { matchop(@_, "m", "/") }
2966sub pp_qr { matchop(@_, "qr", "") }
6e90668e
SM
2967
2968sub pp_split {
2969 my $self = shift;
9d2c6865 2970 my($op, $cx) = @_;
6e90668e
SM
2971 my($kid, @exprs, $ary, $expr);
2972 $kid = $op->first;
2973 if ($ {$kid->pmreplroot}) {
2974 $ary = '@' . $self->gv_name($kid->pmreplroot);
2975 }
2976 for (; !null($kid); $kid = $kid->sibling) {
9d2c6865 2977 push @exprs, $self->deparse($kid, 6);
6e90668e
SM
2978 }
2979 $expr = "split(" . join(", ", @exprs) . ")";
2980 if ($ary) {
9d2c6865 2981 return $self->maybe_parens("$ary = $expr", $cx, 7);
6e90668e
SM
2982 } else {
2983 return $expr;
2984 }
2985}
2986
2987# oxime -- any of various compounds obtained chiefly by the action of
2988# hydroxylamine on aldehydes and ketones and characterized by the
2989# bivalent grouping C=NOH [Webster's Tenth]
2990
2991my %substwords;
2992map($substwords{join "", sort split //, $_} = $_, 'ego', 'egoism', 'em',
2993 'es', 'ex', 'exes', 'gee', 'go', 'goes', 'ie', 'ism', 'iso', 'me',
2994 'meese', 'meso', 'mig', 'mix', 'os', 'ox', 'oxime', 'see', 'seem',
2995 'seg', 'sex', 'sig', 'six', 'smog', 'sog', 'some', 'xi');
2996
2997sub pp_subst {
2998 my $self = shift;
9d2c6865 2999 my($op, $cx) = @_;
6e90668e 3000 my $kid = $op->first;
9d2c6865 3001 my($binop, $var, $re, $repl) = ("", "", "", "");
6e90668e 3002 if ($op->flags & OPf_STACKED) {
9d2c6865
SM
3003 $binop = 1;
3004 $var = $self->deparse($kid, 20);
6e90668e
SM
3005 $kid = $kid->sibling;
3006 }
3007 my $flags = "";
3008 if (null($op->pmreplroot)) {
3009 $repl = $self->dq($kid);
3010 $kid = $kid->sibling;
3011 } else {
3012 $repl = $op->pmreplroot->first; # skip substcont
3f872cb9 3013 while ($repl->name eq "entereval") {
6e90668e
SM
3014 $repl = $repl->first;
3015 $flags .= "e";
3016 }
bd0865ec
GS
3017 if ($op->pmflags & PMf_EVAL) {
3018 $repl = $self->deparse($repl, 0);
3019 } else {
3020 $repl = $self->dq($repl);
3021 }
6e90668e
SM
3022 }
3023 if (null $kid) {
08c6f5ec 3024 $re = re_uninterp(escape_str(re_unback($op->precomp)));
6e90668e 3025 } else {
9d2c6865 3026 $re = $self->deparse($kid, 1);
a798dbf2 3027 }
6e90668e
SM
3028 $flags .= "e" if $op->pmflags & PMf_EVAL;
3029 $flags .= "g" if $op->pmflags & PMf_GLOBAL;
3030 $flags .= "i" if $op->pmflags & PMf_FOLD;
3031 $flags .= "m" if $op->pmflags & PMf_MULTILINE;
3032 $flags .= "o" if $op->pmflags & PMf_KEEP;
3033 $flags .= "s" if $op->pmflags & PMf_SINGLELINE;
3034 $flags .= "x" if $op->pmflags & PMf_EXTENDED;
3035 $flags = $substwords{$flags} if $substwords{$flags};
9d2c6865
SM
3036 if ($binop) {
3037 return $self->maybe_parens("$var =~ s"
3038 . double_delim($re, $repl) . $flags,
3039 $cx, 20);
3040 } else {
3041 return "s". double_delim($re, $repl) . $flags;
3042 }
a798dbf2
MB
3043}
3044
30451;
f6f9bdb7
SM
3046__END__
3047
3048=head1 NAME
3049
3050B::Deparse - Perl compiler backend to produce perl code
3051
3052=head1 SYNOPSIS
3053
646bba82
SM
3054B<perl> B<-MO=Deparse>[B<,-u>I<PACKAGE>][B<,-p>][B<,-q>][B<,-l>]
3055 [B<,-s>I<LETTERS>][B<,-x>I<LEVEL>] I<prog.pl>
f6f9bdb7
SM
3056
3057=head1 DESCRIPTION
3058
3059B::Deparse is a backend module for the Perl compiler that generates
3060perl source code, based on the internal compiled structure that perl
3061itself creates after parsing a program. The output of B::Deparse won't
3062be exactly the same as the original source, since perl doesn't keep
3063track of comments or whitespace, and there isn't a one-to-one
3064correspondence between perl's syntactical constructions and their
9d2c6865
SM
3065compiled form, but it will often be close. When you use the B<-p>
3066option, the output also includes parentheses even when they are not
3067required by precedence, which can make it easy to see if perl is
3068parsing your expressions the way you intended.
f6f9bdb7
SM
3069
3070Please note that this module is mainly new and untested code and is
3071still under development, so it may change in the future.
3072
3073=head1 OPTIONS
3074
9d2c6865
SM
3075As with all compiler backend options, these must follow directly after
3076the '-MO=Deparse', separated by a comma but not any white space.
f6f9bdb7
SM
3077
3078=over 4
3079
bd0865ec
GS
3080=item B<-l>
3081
3082Add '#line' declarations to the output based on the line and file
3083locations of the original code.
3084
9d2c6865
SM
3085=item B<-p>
3086
3087Print extra parentheses. Without this option, B::Deparse includes
3088parentheses in its output only when they are needed, based on the
3089structure of your program. With B<-p>, it uses parentheses (almost)
3090whenever they would be legal. This can be useful if you are used to
3091LISP, or if you want to see how perl parses your input. If you say
3092
3093 if ($var & 0x7f == 65) {print "Gimme an A!"}
3094 print ($which ? $a : $b), "\n";
3095 $name = $ENV{USER} or "Bob";
3096
3097C<B::Deparse,-p> will print
3098
3099 if (($var & 0)) {
3100 print('Gimme an A!')
3101 };
3102 (print(($which ? $a : $b)), '???');
3103 (($name = $ENV{'USER'}) or '???')
3104
3105which probably isn't what you intended (the C<'???'> is a sign that
3106perl optimized away a constant value).
3107
bd0865ec
GS
3108=item B<-q>
3109
3110Expand double-quoted strings into the corresponding combinations of
3111concatenation, uc, ucfirst, lc, lcfirst, quotemeta, and join. For
3112instance, print
3113
3114 print "Hello, $world, @ladies, \u$gentlemen\E, \u\L$me!";
3115
3116as
3117
3118 print 'Hello, ' . $world . ', ' . join($", @ladies) . ', '
3119 . ucfirst($gentlemen) . ', ' . ucfirst(lc $me . '!');
3120
3121Note that the expanded form represents the way perl handles such
3122constructions internally -- this option actually turns off the reverse
3123translation that B::Deparse usually does. On the other hand, note that
3124C<$x = "$y"> is not the same as C<$x = $y>: the former makes the value
3125of $y into a string before doing the assignment.
3126
9d2c6865 3127=item B<-u>I<PACKAGE>
f6f9bdb7
SM
3128
3129Normally, B::Deparse deparses the main code of a program, all the subs
3130called by the main program (and all the subs called by them,
3131recursively), and any other subs in the main:: package. To include
3132subs in other packages that aren't called directly, such as AUTOLOAD,
f4a44678
SM
3133DESTROY, other subs called automatically by perl, and methods (which
3134aren't resolved to subs until runtime), use the B<-u> option. The
f6f9bdb7
SM
3135argument to B<-u> is the name of a package, and should follow directly
3136after the 'u'. Multiple B<-u> options may be given, separated by
3137commas. Note that unlike some other backends, B::Deparse doesn't
3138(yet) try to guess automatically when B<-u> is needed -- you must
3139invoke it yourself.
3140
9d2c6865
SM
3141=item B<-s>I<LETTERS>
3142
f4a44678
SM
3143Tweak the style of B::Deparse's output. The letters should follow
3144directly after the 's', with no space or punctuation. The following
3145options are available:
9d2c6865
SM
3146
3147=over 4
3148
3149=item B<C>
3150
3151Cuddle C<elsif>, C<else>, and C<continue> blocks. For example, print
3152
3153 if (...) {
3154 ...
3155 } else {
3156 ...
3157 }
3158
3159instead of
3160
3161 if (...) {
3162 ...
3163 }
3164 else {
3165 ...
3166 }
3167
3168The default is not to cuddle.
3169
f4a44678
SM
3170=item B<i>I<NUMBER>
3171
3172Indent lines by multiples of I<NUMBER> columns. The default is 4 columns.
3173
3174=item B<T>
3175
3176Use tabs for each 8 columns of indent. The default is to use only spaces.
3177For instance, if the style options are B<-si4T>, a line that's indented
31783 times will be preceded by one tab and four spaces; if the options were
3179B<-si8T>, the same line would be preceded by three tabs.
3180
3181=item B<v>I<STRING>B<.>
3182
3183Print I<STRING> for the value of a constant that can't be determined
3184because it was optimized away (mnemonic: this happens when a constant
3185is used in B<v>oid context). The end of the string is marked by a period.
3186The string should be a valid perl expression, generally a constant.
3187Note that unless it's a number, it probably needs to be quoted, and on
3188a command line quotes need to be protected from the shell. Some
3189conventional values include 0, 1, 42, '', 'foo', and
3190'Useless use of constant omitted' (which may need to be
3191B<-sv"'Useless use of constant omitted'.">
3192or something similar depending on your shell). The default is '???'.
3193If you're using B::Deparse on a module or other file that's require'd,
3194you shouldn't use a value that evaluates to false, since the customary
3195true constant at the end of a module will be in void context when the
3196file is compiled as a main program.
3197
9d2c6865
SM
3198=back
3199
58cccf98
SM
3200=item B<-x>I<LEVEL>
3201
3202Expand conventional syntax constructions into equivalent ones that expose
3203their internal operation. I<LEVEL> should be a digit, with higher values
3204meaning more expansion. As with B<-q>, this actually involves turning off
3205special cases in B::Deparse's normal operations.
3206
3207If I<LEVEL> is at least 3, for loops will be translated into equivalent
646bba82 3208while loops with continue blocks; for instance
58cccf98
SM
3209
3210 for ($i = 0; $i < 10; ++$i) {
3211 print $i;
3212 }
3213
3214turns into
3215
3216 $i = 0;
3217 while ($i < 10) {
3218 print $i;
3219 } continue {
3220 ++$i
3221 }
3222
3223Note that in a few cases this translation can't be perfectly carried back
646bba82 3224into the source code -- if the loop's initializer declares a my variable,
58cccf98
SM
3225for instance, it won't have the correct scope outside of the loop.
3226
3227If I<LEVEL> is at least 7, if statements will be translated into equivalent
3228expressions using C<&&>, C<?:> and C<do {}>; for instance
3229
3230 print 'hi' if $nice;
3231 if ($nice) {
3232 print 'hi';
3233 }
3234 if ($nice) {
3235 print 'hi';
3236 } else {
3237 print 'bye';
3238 }
3239
3240turns into
3241
3242 $nice and print 'hi';
3243 $nice and do { print 'hi' };
3244 $nice ? do { print 'hi' } : do { print 'bye' };
3245
3246Long sequences of elsifs will turn into nested ternary operators, which
3247B::Deparse doesn't know how to indent nicely.
3248
f6f9bdb7
SM
3249=back
3250
f4a44678
SM
3251=head1 USING B::Deparse AS A MODULE
3252
3253=head2 Synopsis
3254
3255 use B::Deparse;
3256 $deparse = B::Deparse->new("-p", "-sC");
3257 $body = $deparse->coderef2text(\&func);
3258 eval "sub func $body"; # the inverse operation
3259
3260=head2 Description
3261
3262B::Deparse can also be used on a sub-by-sub basis from other perl
3263programs.
3264
3265=head2 new
3266
3267 $deparse = B::Deparse->new(OPTIONS)
3268
3269Create an object to store the state of a deparsing operation and any
3270options. The options are the same as those that can be given on the
3271command line (see L</OPTIONS>); options that are separated by commas
3272after B<-MO=Deparse> should be given as separate strings. Some
3273options, like B<-u>, don't make sense for a single subroutine, so
3274don't pass them.
3275
08c6f5ec
RH
3276=head2 ambient_pragmas
3277
3278 $deparse->ambient_pragmas(strict => 'all', '$[' => $[);
3279
3280The compilation of a subroutine can be affected by a few compiler
3281directives, B<pragmas>. These are:
3282
3283=over 4
3284
3285=item *
3286
3287use strict;
3288
3289=item *
3290
3291use warnings;
3292
3293=item *
3294
3295Assigning to the special variable $[
3296
3297=item *
3298
3299use integer;
3300
3301=back
3302
3303Ordinarily, if you use B::Deparse on a subroutine which has
3304been compiled in the presence of one or more of these pragmas,
3305the output will include statements to turn on the appropriate
3306directives. So if you then compile the code returned by coderef2text,
3307it will behave the same way as the subroutine which you deparsed.
3308
3309However, you may know that you intend to use the results in a
3310particular context, where some pragmas are already in scope. In
3311this case, you use the B<ambient_pragmas> method to describe the
3312assumptions you wish to make.
3313
3314The parameters it accepts are:
3315
3316=over 4
3317
3318=item strict
3319
3320Takes a string, possibly containing several values separated
3321by whitespace. The special values "all" and "none" mean what you'd
3322expect.
3323
3324 $deparse->ambient_pragmas(strict => 'subs refs');
3325
3326=item $[
3327
3328Takes a number, the value of the array base $[.
3329
3330=item integer
3331
3332If the value is true, then the B<integer> pragma is assumed to
3333be in the ambient scope, otherwise not.
3334
3335=item warnings
3336
3337Takes a string, possibly containing a whitespace-separated list of
3338values. The values "all" and "none" are special, again. It's also
3339permissible to pass an array reference here.
3340
3341 $deparser->ambient_pragmas(warnings => [qw[void io]]);
3342
3343If one of the values is the string "FATAL", then all the warnings
3344in that list will be considered fatal, just as with the B<warnings>
3345pragma itself. Should you need to specify that some warnings are
3346fatal, and others are merely enabled, you can pass the B<warnings>
3347parameter twice:
3348
3349 $deparser->ambient_pragmas(
3350 warnings => 'all',
3351 warnings => [FATAL => qw/void io/],
3352 );
3353
3354See L<perllexwarn> for more information about lexical warnings.
3355
3356=item hint_bits
3357
3358=item warning_bits
3359
3360These two parameters are used to specify the ambient pragmas in
3361the format used by the special variables $^H and ${^WARNING_BITS}.
3362
3363They exist principally so that you can write code like:
3364
3365 { my ($hint_bits, $warning_bits);
3366 BEGIN {($hint_bits, $warning_bits) = ($^H, ${^WARNING_BITS})}
3367 $deparser->ambient_pragmas (
3368 hint_bits => $hint_bits,
3369 warning_bits => $warning_bits,
3370 '$[' => 0 + $[
3371 ); }
3372
3373which specifies that the ambient pragmas are exactly those which
3374are in scope at the point of calling.
3375
3376=back
3377
f4a44678
SM
3378=head2 coderef2text
3379
3380 $body = $deparse->coderef2text(\&func)
3381 $body = $deparse->coderef2text(sub ($$) { ... })
3382
3383Return source code for the body of a subroutine (a block, optionally
3384preceded by a prototype in parens), given a reference to the
3385sub. Because a subroutine can have no names, or more than one name,
3386this method doesn't return a complete subroutine definition -- if you
3387want to eval the result, you should prepend "sub subname ", or "sub "
3388for an anonymous function constructor. Unless the sub was defined in
3389the main:: package, the code will include a package declaration.
3390
f6f9bdb7
SM
3391=head1 BUGS
3392
3393See the 'to do' list at the beginning of the module file.
3394
3395=head1 AUTHOR
3396
58cccf98 3397Stephen McCamant <smcc@CSUA.Berkeley.EDU>, based on an earlier
f4a44678
SM
3398version by Malcolm Beattie <mbeattie@sable.ox.ac.uk>, with
3399contributions from Gisle Aas, James Duncan, Albert Dvornik, Hugo van
3400der Sanden, Gurusamy Sarathy, and Nick Ing-Simmons.
f6f9bdb7
SM
3401
3402=cut