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