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