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