File Coverage

lib/B/DeparseTree/PP.pm
Criterion Covered Total %
statement 299 511 58.5
branch 92 184 50.0
condition 58 150 38.6
subroutine 100 145 68.9
pod 0 132 0.0
total 549 1122 48.9


line stmt bran cond sub pod time code
1             # Copyright (c) 2015, 2018 Rocky Bernstein
2              
3             # Common PP (push-pull) opcodes methods. Most of these are called
4             # from the method dispatch in Common.
5             #
6             # Specifc Perl versions can override these. Note some PP opcodes are
7             # handled via table lookup to their underlying base-handling function,
8             # e.g. binop, listop, unop, ....
9              
10 3     3   17 use strict;
  3         5  
  3         86  
11 3     3   12 use warnings ();
  3         5  
  3         115  
12             require feature;
13              
14             my %feature_keywords = (
15             # keyword => 'feature',
16             state => 'state',
17             say => 'say',
18             given => 'switch',
19             when => 'switch',
20             default => 'switch',
21             break => 'switch',
22             evalbytes=>'evalbytes',
23             __SUB__ => '__SUB__',
24             fc => 'fc',
25             );
26              
27 3     3   13 use rlib '../..';
  3         5  
  3         16  
28              
29             package B::DeparseTree::PP;
30              
31 3     3   896 use B::DeparseTree::SyntaxTree;
  3         5  
  3         228  
32 3     3   15 use B::DeparseTree::PPfns;
  3         4  
  3         674  
33 3     3   19 use B::DeparseTree::Node;
  3         4  
  3         244  
34 3     3   17 use B::Deparse;
  3         4  
  3         371  
35             our($VERSION, @EXPORT, @ISA);
36             $VERSION = '3.2.0';
37              
38             @ISA = qw(Exporter B::Deparse );
39              
40             # Copy unchanged functions from B::Deparse
41             *lex_in_scope = *B::Deparse::lex_in_scope;
42             *padany = *B::Deparse::padany;
43             *padname = *B::Deparse::padname;
44             *pp_anonhash = *B::Deparse::pp_anonhash;
45             *pp_anonlist = *B::Deparse::pp_anonlist;
46             *pp_i_negate = *B::Deparse::pp_i_negate;
47             *pp_negate = *B::Deparse::pp_negate;
48             *real_negate = *B::Deparse::real_negate;
49              
50 3         510 use B qw(
51             OPf_MOD OPpENTERSUB_AMPER
52             OPf_SPECIAL
53             OPf_STACKED
54             OPpEXISTS_SUB
55             OPpTRANS_COMPLEMENT
56             OPpTRANS_DELETE
57             OPpTRANS_SQUASH
58             SVf_POK
59             SVf_ROK
60             class
61             opnumber
62 3     3   17 );
  3         6  
63              
64             @EXPORT = qw(
65             feature_enabled
66             pp_aassign
67             pp_abs
68             pp_aelem
69             pp_and
70             pp_anonhash
71             pp_anonlist
72             pp_aslice
73             pp_atan2
74             pp_avalues
75             pp_backtick
76             pp_boolkeys
77             pp_chmod
78             pp_chomp
79             pp_chop
80             pp_chown
81             pp_clonecv
82             pp_cmp
83             pp_complement
84             pp_cond_expr
85             pp_connect
86             pp_const
87             pp_cos
88             pp_crypt
89             pp_dbmopen
90             pp_delete
91             pp_dofile
92             pp_dor
93             pp_entereval
94             pp_entersub
95             pp_eq
96             pp_exec
97             pp_exists
98             pp_exp
99             pp_flock
100             pp_flop
101             pp_formline
102             pp_ge
103             pp_getppid
104             pp_getpriority
105             pp_glob
106             pp_gnbyaddr
107             pp_gpbynumber
108             pp_grepwhile
109             pp_gt
110             pp_gv
111             pp_gvsv
112             pp_helem
113             pp_hex
114             pp_hslice
115             pp_i_cmp
116             pp_i_eq
117             pp_i_ge
118             pp_i_gt
119             pp_i_le
120             pp_i_lt
121             pp_i_ne
122             pp_i_negate
123             pp_i_predec
124             pp_i_preinc
125             pp_index
126             pp_int
127             pp_introcv
128             pp_ioctl
129             pp_join
130             pp_kill
131             pp_kvaslice
132             pp_kvhslice
133             pp_le
134             pp_leave
135             pp_leavegiven
136             pp_leaveloop
137             pp_leavetry
138             pp_leavewhen
139             pp_lineseq
140             pp_link
141             pp_list
142             pp_log
143             pp_lt
144             pp_mapstart
145             pp_mapwhile
146             pp_mkdir
147             pp_msgsnd
148             pp_ne
149             pp_negate
150             pp_not
151             pp_null
152             pp_oct
153             pp_once
154             pp_open_dir
155             pp_or
156             pp_padcv
157             pp_pos
158             pp_pos
159             pp_postdec
160             pp_postinc
161             pp_predec
162             pp_preinc
163             pp_print
164             pp_prtf
165             pp_push
166             pp_rand
167             pp_ref
168             pp_refgen
169             pp_rename
170             pp_repeat
171             pp_require
172             pp_return
173             pp_rindex
174             pp_rv2cv
175             pp_sassign
176             pp_scalar
177             pp_schomp
178             pp_schop
179             pp_scmp
180             pp_scope
181             pp_seekdir
182             pp_seq
183             pp_setpgrp
184             pp_setpriority
185             pp_sge
186             pp_sgt
187             pp_sin
188             pp_sle
189             pp_slt
190             pp_sne
191             pp_sockpair
192             pp_slice
193             pp_sprintf
194             pp_sqrt
195             pp_sselect
196             pp_ssockopt
197             pp_stub
198             pp_subst
199             pp_substr
200             pp_symlink
201             pp_sysread
202             pp_sysseek
203             pp_system
204             pp_time
205             pp_trans
206             pp_transr
207             pp_truncate
208             pp_unlink
209             pp_unpack
210             pp_unshift
211             pp_unstack
212             pp_utime
213             pp_values
214             pp_vec
215             pp_wait
216             pp_waitpid
217             pp_wantarray
218             pp_xor
219             );
220              
221             BEGIN {
222             # List version-specific constants here.
223             # Easiest way to keep this code portable between version looks to
224             # be to fake up a dummy constant that will never actually be true.
225 3     3   14 foreach (qw(OPpCONST_ARYBASE OPpEVAL_BYTES)) {
226 6         11 eval { import B $_ };
  6         1141  
227 3     3   17 no strict 'refs';
  3         4  
  3         197  
228 6 100       13 *{$_} = sub () {0} unless *{$_}{CODE};
  3         10  
  6         203  
229             }
230             }
231              
232 3     3   9 BEGIN { for (qw[ const stringify rv2sv list glob pushmark null aelem
233             nextstate dbstate rv2av rv2hv helem custom ]) {
234 42         16039 eval "sub OP_\U$_ () { " . opnumber($_) . "}"
235             }}
236              
237             sub feature_enabled {
238 25     25 0 63 my($self,$name) = @_;
239 25         30 my $hh;
240 25         62 my $hints = $self->{hints} & $feature::hint_mask;
241 25 100 100     99 if ($hints && $hints != $feature::hint_mask) {
    100          
242 6         62 $hh = B::Deparse::_features_from_bundle($hints);
243             }
244 7         15 elsif ($hints) { $hh = $self->{'hinthash'} }
245 25   66     3219 return $hh && $hh->{"feature_$feature_keywords{$name}"}
246             }
247              
248             # Convert these to table entries...
249 0     0 0 0 sub pp_aelem { maybe_local(@_, elem(@_, "[", "]", "padav")) }
250 1     1 0 8 sub pp_aslice { maybe_local(@_, slice(@_, "[", "]", "rv2av", "padav")) }
251 0     0 0 0 sub pp_cmp { binop(@_, "<=>", 14) }
252 0     0 0 0 sub pp_eq { binop(@_, "==", 14) }
253 0     0 0 0 sub pp_ge { binop(@_, ">=", 15) }
254 0     0 0 0 sub pp_gt { binop(@_, ">", 15) }
255 1     1 0 5 sub pp_helem { maybe_local(@_, elem(@_, "{", "}", "padhv")) }
256 1     1 0 6 sub pp_hslice { maybe_local(@_, slice(@_, "{", "}", "rv2hv", "padhv")) }
257 0     0 0 0 sub pp_i_cmp { maybe_targmy(@_, \&binop, "<=>", 14) }
258 0     0 0 0 sub pp_i_eq { binop(@_, "==", 14) }
259 0     0 0 0 sub pp_i_ge { binop(@_, ">=", 15) }
260 0     0 0 0 sub pp_i_gt { binop(@_, ">", 15) }
261 0     0 0 0 sub pp_i_le { binop(@_, "<=", 15) }
262 0     0 0 0 sub pp_i_lt { binop(@_, "<", 15) }
263 0     0 0 0 sub pp_i_ne { binop(@_, "!=", 14) }
264 0     0 0 0 sub pp_kvaslice { slice(@_, "[", "]", "rv2av", "padav") }
265 0     0 0 0 sub pp_kvhslice { slice(@_, "{", "}", "rv2hv", "padhv") }
266 0     0 0 0 sub pp_le { binop(@_, "<=", 15) }
267 0     0 0 0 sub pp_lt { binop(@_, "<", 15) }
268 0     0 0 0 sub pp_ne { binop(@_, "!=", 14) }
269              
270             # Note that we need to add undef and 1 (nollr)
271 2     2 0 17 sub pp_return { listop(@_, "return", undef, 1) } # llafr does not apply
272              
273 12     12 0 51 sub pp_sassign { binop(@_, "=", 7, SWAP_CHILDREN) }
274 10     10 0 44 sub pp_scmp { binop(@_, "cmp", 14) }
275 0     0 0 0 sub pp_seekdir { listop(@_, "seekdir") }
276 8     8 0 34 sub pp_seq { binop(@_, "eq", 14) }
277 8     8 0 38 sub pp_sge { binop(@_, "ge", 15) }
278 8     8 0 28 sub pp_sgt { binop(@_, "gt", 15) }
279 8     8 0 30 sub pp_sle { binop(@_, "le", 15) }
280 8     8 0 26 sub pp_slt { binop(@_, "lt", 15) }
281 8     8 0 25 sub pp_sne { binop(@_, "ne", 14) }
282              
283             # FIXME: These don't seem to be able to go into the table.
284             # PPfns calls pp_sockpair for example?
285 2     2 0 7 sub pp_sockpair { listop(@_, "socketpair") }
286 2     2 0 7 sub pp_values { unop(@_, "values") }
287 2     2 0 7 sub pp_avalues { unop(@_, "values") }
288              
289              
290              
291 1310     1310 0 4654 sub pp_aassign { binop(@_, "=", 7, SWAP_CHILDREN | LIST_CONTEXT, 'array assign') }
292 4     4 0 21 sub pp_abs { maybe_targmy(@_, \&unop, "abs") }
293              
294             sub pp_backtick
295             {
296 3     3 0 8 my($self, $op, $cx) = @_;
297             # skip pushmark if it exists (readpipe() vs ``)
298 3 50       45 my $child = $op->first->sibling->isa('B::NULL')
299             ? $op->first : $op->first->sibling;
300 3 50       18 if ($self->pure_string($child)) {
301 0         0 return $self->single_delim($op, "qx", '`', $self->dq($child, 1)->{text});
302             }
303 3         30 unop($self, $op, $cx, "readpipe");
304             }
305              
306             sub pp_boolkeys
307             {
308             # no name because its an optimisation op that has no keyword
309 0     0 0 0 unop(@_,"");
310             }
311              
312 6     6 0 32 sub pp_chmod { maybe_targmy(@_, \&listop, "chmod") }
313 6     6 0 27 sub pp_chown { maybe_targmy(@_, \&listop, "chown") }
314 4     4 0 19 sub pp_cos { maybe_targmy(@_, \&unop, "cos") }
315 2     2 0 9 sub pp_crypt { maybe_targmy(@_, \&listop, "crypt") }
316              
317             sub pp_dofile
318             {
319 0     0 0 0 my $code = unop(@_, "do", 1); # llafr does not apply
320 0 0       0 if ($code =~ s/^((?:CORE::)?do) \{/$1({/) { $code .= ')' }
  0         0  
321 0         0 $code;
322             }
323              
324 8     8 0 32 sub pp_exec { maybe_targmy(@_, \&listop, "exec") }
325 4     4 0 20 sub pp_exp { maybe_targmy(@_, \&unop, "exp") }
326 2     2 0 10 sub pp_flock { maybe_targmy(@_, \&listop, "flock") }
327 2     2 0 10 sub pp_getpriority { maybe_targmy(@_, \&listop, "getpriority") }
328 4     4 0 46 sub pp_hex { maybe_targmy(@_, \&unop, "hex") }
329 4     4 0 21 sub pp_index { maybe_targmy(@_, \&listop, "index") }
330 4     4 0 16 sub pp_int { maybe_targmy(@_, \&unop, "int") }
331 4     4 0 28 sub pp_join { maybe_targmy(@_, \&listop, "join") }
332 6     6 0 39 sub pp_kill { maybe_targmy(@_, \&listop, "kill") }
333 2     2 0 27 sub pp_link { maybe_targmy(@_, \&listop, "link") }
334              
335 0     0 0 0 sub pp_leavegiven { givwhen(@_, $_[0]->keyword("given")); }
336 0     0 0 0 sub pp_leavewhen { givwhen(@_, $_[0]->keyword("when")); }
337              
338 4     4 0 16 sub pp_log { maybe_targmy(@_, \&unop, "log") }
339 6     6 0 25 sub pp_mkdir { maybe_targmy(@_, \&listop, "mkdir") }
340              
341             sub pp_not
342             {
343 27     27 0 61 my($self, $op, $cx) = @_;
344 27 50       52 if ($cx <= 4) {
345 27         150 $self->listop($op, $cx, "not", $op->first);
346             } else {
347 0         0 $self->pfixop($op, $cx, "!", 21);
348             }
349             }
350              
351              
352 4     4 0 18 sub pp_oct { maybe_targmy(@_, \&unop, "oct") }
353 2     2 0 9 sub pp_open_dir { listop(@_, "opendir") }
354 8     8 0 26 sub pp_pos { maybe_local(@_, unop(@_, "pos")) }
355 6     6 0 24 sub pp_push { maybe_targmy(@_, \&listop, "push") }
356 2     2 0 8 sub pp_rename { maybe_targmy(@_, \&listop, "rename") }
357 4     4 0 12 sub pp_rindex { maybe_targmy(@_, \&listop, "rindex") }
358              
359             # skip down to the old, ex-rv2cv
360             sub pp_rv2cv {
361 0     0 0 0 my ($self, $op, $cx) = @_;
362 0 0 0     0 if (!B::Deparse::null($op->first) && $op->first->name eq 'null' &&
      0        
363             $op->first->targ == OP_LIST)
364             {
365 0         0 return $self->rv2x($op->first->first->sibling, $cx, "&")
366             }
367             else {
368 0         0 return $self->rv2x($op, $cx, "")
369             }
370             }
371              
372              
373             sub pp_scalar
374             {
375 4     4 0 9 my($self, $op, $cx) = @_;
376 4         14 my $kid = $op->first;
377 4 50       29 if (not B::Deparse::null $kid->sibling) {
378             # XXX Was a here-doc
379 0         0 return $self->dquote($op);
380             }
381 4         15 $self->unop($op, $cx, "scalar");
382             }
383              
384 3     3 0 16 sub pp_setpgrp { maybe_targmy(@_, \&listop, "setpgrp") }
385 2     2 0 7 sub pp_setpriority { maybe_targmy(@_, \&listop, "setpriority") }
386 4     4 0 17 sub pp_sin { maybe_targmy(@_, \&unop, "sin") }
387 6     6 0 27 sub pp_sprintf { maybe_targmy(@_, \&listop, "sprintf") }
388 4     4 0 16 sub pp_sqrt { maybe_targmy(@_, \&unop, "sqrt") }
389             sub pp_symlink { maybe_targmy(@_, \&listop, "symlink") }
390 8     8 0 43 sub pp_system { maybe_targmy(@_, \&listop, "system") }
391              
392             sub pp_truncate
393             {
394 2     2 0 6 my($self, $op, $cx) = @_;
395 2         2 my(@exprs);
396 2   33     6 my $parens = ($cx >= 5) || $self->{'parens'};
397 2         16 my $opts = {'other_ops' => [$op->first]};
398 2         10 my $kid = $op->first->sibling;
399 2         3 my $fh;
400 2 50       17 if ($op->flags & B::OPf_SPECIAL) {
401             # $kid is an OP_CONST
402 0         0 $fh = $self->const_sv($kid)->PV;
403             } else {
404 2         7 $fh = $self->deparse($kid, 6, $op);
405 2 50 33     6 $fh = "+$fh" if not $parens and substr($fh, 0, 1) eq "(";
406             }
407 2         9 my $len = $self->deparse($kid->sibling, 6, $op);
408 2         48 my $name = $self->keyword('truncate');
409 2         7 my $args = "$fh->{text}, $len->{text}";
410 2 50       4 if ($parens) {
411 2         8 return info_from_list($op, $self, [$name, '(', $args, ')'], '',
412             'truncate_parens', $opts);
413             } else {
414 0         0 return info_from_list($op, $self, [$name, $args], '', 'truncate', $opts);
415             }
416             }
417              
418 6     6 0 39 sub pp_unlink { maybe_targmy(@_, \&listop, "unlink") }
419 6     6 0 25 sub pp_unshift { maybe_targmy(@_, \&listop, "unshift") }
420 6     6 0 29 sub pp_utime { maybe_targmy(@_, \&listop, "utime") }
421              
422 2     2 0 8 sub pp_vec { maybe_local(@_, listop(@_, "vec")) }
423 2     2 0 8 sub pp_waitpid { maybe_targmy(@_, \&listop, "waitpid") }
424              
425             sub pp_glob
426             {
427 10     10 0 29 my($self, $op, $cx) = @_;
428              
429 10         60 my $opts = {other_ops => [$op->first]};
430 10         53 my $kid = $op->first->sibling; # skip pushmark
431 10 100       185 my $keyword =
432             $op->flags & OPf_SPECIAL ? 'glob' : $self->keyword('glob');
433              
434 10 50 66     79 if ($keyword =~ /^CORE::/ or $kid->name ne 'const') {
435 10         54 my $kid_info = $self->dq($kid, $op);
436 10         25 my $body = [$kid_info];
437 10         39 my $text = $kid_info->{text};
438 10 50 33     99 if ($text =~ /^\$?(\w|::|\`)+$/ # could look like a readline
439             or $text =~ /[<>]/) {
440 10         39 $kid_info = $self->deparse($kid, 0, $op);
441 10         63 $body = [$kid_info];
442 10         33 $text = $kid_info->{text};
443 10         23 $opts->{body} = $body;
444 10 100 66     65 if ($cx >= 5 || $self->{'parens'}) {
445 8         50 return info_from_list($op, $self, [$keyword, '(', $text, ')'], '',
446             'glob_paren', $opts);
447             } else {
448 2         9 return info_from_list($op, $self, [$keyword, $text], ' ',
449             'glob_space', $opts);
450             }
451             } else {
452 0         0 return info_from_list($op, $self, ['<', $text, '>'], '', 'glob_angle', $opts);
453             }
454             }
455 0         0 return info_from_list($op, $self, ['<', '>'], '', 'glob_angle', $opts);
456             }
457              
458 0     0 0 0 sub pp_chomp { maybe_targmy(@_, \&unop, "chomp") }
459 0     0 0 0 sub pp_chop { maybe_targmy(@_, \&unop, "chop") }
460              
461             sub pp_clonecv {
462 0     0 0 0 my $self = shift;
463 0         0 my($op, $cx) = @_;
464 0         0 my $sv = $self->padname_sv($op->targ);
465 0         0 my $name = substr $sv->PVX, 1; # skip &/$/@/%, like $self->padany
466 0         0 return info_from_list($op, $self, ['my', 'sub', $name], ' ', 'clonev', {});
467             }
468              
469             sub pp_delete($$$)
470             {
471 0     0 0 0 my($self, $op, $cx) = @_;
472 0         0 my $arg;
473 0         0 my ($info, $body, $type);
474 0 0       0 if ($op->private & B::OPpSLICE) {
475 0 0       0 if ($op->flags & B::OPf_SPECIAL) {
476             # Deleting from an array, not a hash
477 0         0 $info = $self->pp_aslice($op->first, 16);
478 0         0 $type = 'delete slice';
479             }
480             } else {
481 0 0       0 if ($op->flags & B::OPf_SPECIAL) {
482             # Deleting from an array, not a hash
483 0         0 $info = $self->pp_aelem($op->first, 16);
484 0         0 $type = 'delete array'
485             } else {
486 0         0 $info = $self->pp_helem($op->first, 16);
487 0         0 $type = 'delete hash';
488             }
489             }
490             my @texts = $self->maybe_parens_func("delete",
491 0         0 $info->{text}, $cx, 16);
492 0         0 return info_from_list($op, $self, \@texts, '', $type, {body => [$info]});
493             }
494              
495             sub pp_exists
496             {
497 0     0 0 0 my($self, $op, $cx) = @_;
498 0         0 my ($info, $type);
499 0         0 my $name = $self->keyword("exists");
500 0 0       0 if ($op->private & OPpEXISTS_SUB) {
    0          
501             # Checking for the existence of a subroutine
502 0         0 $info = $self->pp_rv2cv($op->first, 16);
503 0         0 $type = 'exists sub';
504             } elsif ($op->flags & OPf_SPECIAL) {
505             # Array element, not hash helement
506 0         0 $info = $self->pp_aelem($op->first, 16);
507 0         0 $type = 'exists array';
508             } else {
509 0         0 $info = $self->pp_helem($op->first, 16);
510 0         0 $type = 'exists hash';
511             }
512 0         0 my @texts = $self->maybe_parens_func($name, $info->{text}, $cx, 16);
513 0         0 return info_from_list($op, $self, \@texts, '', $type, {});
514             }
515              
516             sub pp_introcv
517             {
518 0     0 0 0 my($self, $op, $cx) = @_;
519             # For now, deparsing doesn't worry about the distinction between introcv
520             # and clonecv, so pretend this op doesn't exist:
521 0         0 return info_from_text($op, $self, '', 'introcv', {});
522             }
523              
524 4     4 0 12 sub pp_leave { scopeop(1, @_); }
525 3     3 0 17 sub pp_leaveloop { shift->loop_common(@_, undef); }
526              
527             sub pp_leavetry {
528 0     0 0 0 my ($self, $op, $cx) = @_;
529 0         0 my $leave_info = $self->pp_leave($op, $cx);
530 0         0 return $self->info_from_template('eval {}', $op, "eval {\n%+%c\n%-}",
531             undef, [$leave_info]);
532             }
533              
534 3     3 0 14 sub pp_lineseq { scopeop(0, @_); }
535              
536             sub pp_list
537             {
538 3270     3270 0 5674 my($self, $op, $cx) = @_;
539 3270         4637 my($expr, @exprs);
540              
541 3270         8238 my $pushmark_op = $op->first;
542 3270         8783 my $kid = $pushmark_op->sibling; # skip a pushmark
543              
544 3270 100       15626 if (class($kid) eq 'NULL') {
545 1         5 return info_from_text($op, $self, '', 'list_null',
546             {other_ops => [$pushmark_op]});
547             }
548 3269         4512 my $lop;
549 3269         4129 my $local = "either"; # could be local(...), my(...), state(...) or our(...)
550 3269         16039 for ($lop = $kid; !B::Deparse::null($lop); $lop = $lop->sibling) {
551             # This assumes that no other private flags equal 128, and that
552             # OPs that store things other than flags in their op_private,
553             # like OP_AELEMFAST, won't be immediate children of a list.
554             #
555             # OP_ENTERSUB and OP_SPLIT can break this logic, so check for them.
556             # I suspect that open and exit can too.
557             # XXX This really needs to be rewritten to accept only those ops
558             # known to take the OPpLVAL_INTRO flag.
559              
560 5821 100 100     34798 if (!($lop->private & (B::Deparse::OPpLVAL_INTRO|B::Deparse::OPpOUR_INTRO)
      66        
561             or $lop->name eq "undef")
562             or $lop->name =~ /^(?:entersub|exit|open|split)\z/)
563             {
564 2602         3794 $local = ""; # or not
565 2602         3653 last;
566             }
567 3219 100 33     12082 if ($lop->name =~ /^pad[ash]v$/) {
    100 66        
    100 100        
      33        
      33        
      66        
568 3196 100       8268 if ($lop->private & B::Deparse::OPpPAD_STATE) { # state()
569 10 50       32 ($local = "", last) if $local =~ /^(?:local|our|my)$/;
570 10         73 $local = "state";
571             } else { # my()
572 3186 50       5377 ($local = "", last) if $local =~ /^(?:local|our|state)$/;
573 3186         19128 $local = "my";
574             }
575             } elsif ($lop->name =~ /^(gv|rv2)[ash]v$/
576             && $lop->private & B::Deparse::OPpOUR_INTRO
577             or $lop->name eq "null" && $lop->first->name eq "gvsv"
578             && $lop->first->private & B::Deparse::OPpOUR_INTRO) { # our()
579 12 50       36 ($local = "", last) if $local =~ /^(?:my|local|state)$/;
580 12         78 $local = "our";
581             } elsif ($lop->name ne "undef"
582             # specifically avoid the "reverse sort" optimisation,
583             # where "reverse" is nullified
584             && !($lop->name eq 'sort' && ($lop->flags & B::Deparse::OPpSORT_REVERSE)))
585             {
586             # local()
587 2 50       9 ($local = "", last) if $local =~ /^(?:my|our|state)$/;
588 2         15 $local = "local";
589             }
590             }
591 3269 100       5999 $local = "" if $local eq "either"; # no point if it's all undefs
592 3269 100 100     22783 if (B::Deparse::null $kid->sibling and not $local) {
593 2582         6162 my $info = $self->deparse($kid, $cx, $op);
594 2582         6971 $info->update_other_ops($pushmark_op);
595 2582         7268 return $info;
596             }
597              
598 687         3663 for (; !B::Deparse::null($kid); $kid = $kid->sibling) {
599 3296 100       6121 if ($local) {
600 3211 100 66     13127 if (class($kid) eq "UNOP" and $kid->first->name eq "gvsv") {
601 14         32 $lop = $kid->first;
602             } else {
603 3197         4463 $lop = $kid;
604             }
605 3211         6673 $self->{'avoid_local'}{$$lop}++;
606 3211         7338 $expr = $self->deparse($kid, 6, $op);
607 3211         6556 delete $self->{'avoid_local'}{$$lop};
608             } else {
609 85         201 $expr = $self->deparse($kid, 6, $op);
610             }
611 3296         29947 push @exprs, $expr;
612             }
613              
614 687 100       1822 if ($local) {
615 659         5869 return $self->info_from_template("$local ()", $op,
616             "$local(%C)", [[0, $#exprs, ', ']],
617             \@exprs,
618             {other_ops => [$pushmark_op]});
619              
620             } else {
621 28         242 return $self->info_from_template("list", $op,
622             "%C", [[0, $#exprs, ', ']],
623             \@exprs,
624             {maybe_parens => [$self, $cx, 6],
625             other_ops => [$pushmark_op]});
626             }
627             }
628              
629             sub pp_padcv {
630 0     0 0 0 my($self, $op, $cx) = @_;
631 0         0 return info_from_text($op, $self, $self->padany($op), 'padcv', {});
632             }
633              
634             sub pp_refgen
635             {
636 0     0 0 0 my($self, $op, $cx) = @_;
637 0         0 my $kid = $op->first;
638 0 0       0 if ($kid->name eq "null") {
639 0         0 my $other_ops = [$kid];
640 0         0 my $anoncode = $kid = $kid->first;
641 0 0       0 if ($anoncode->name eq "anonconst") {
642 0         0 $anoncode = $anoncode->first->first->sibling;
643             }
644 0 0 0     0 if ($anoncode->name eq "anoncode"
    0 0        
645             or !B::Deparse::null($anoncode = $kid->sibling) and
646             $anoncode->name eq "anoncode") {
647 0         0 return $self->e_anoncode({ code => $self->padval($anoncode->targ) });
648             } elsif ($kid->name eq "pushmark") {
649 0         0 my $sib_name = $kid->sibling->name;
650 0 0       0 if ($sib_name =~ /^enter(xs)?sub/) {
651 0         0 my $kid_info = $self->deparse($kid->sibling, 1, $op);
652             # Always show parens for \(&func()), but only with -p otherwise
653 0         0 my @texts = ('\\', $kid_info->{text});
654 0 0 0     0 if ($self->{'parens'} or $kid->sibling->private & OPpENTERSUB_AMPER) {
655 0         0 @texts = ('(', "\\", $kid_info->{text}, ')');
656             }
657 0         0 return info_from_list($op, $self, \@texts, '', 'refgen_entersub',
658             {body => [$kid_info],
659             other_ops => $other_ops});
660             }
661             }
662             }
663 0         0 local $self->{'in_refgen'} = 1;
664 0         0 $self->pfixop($op, $cx, "\\", 20);
665             }
666              
667             sub pp_require
668             {
669 1     1 0 3 my($self, $op, $cx) = @_;
670 1 50       8 my $opname = $op->flags & OPf_SPECIAL ? 'CORE::require' : 'require';
671 1 50 33     39 if (class($op) eq "UNOP" and $op->first->name eq "const"
      33        
672             and $op->first->private & B::OPpCONST_BARE) {
673 0         0 my $name = $self->const_sv($op->first)->PV;
674 0         0 $name =~ s[/][::]g;
675 0         0 $name =~ s/\.pm//g;
676 0         0 return info_from_list($op, $self, [$opname, $name], ' ',
677             'require',
678             {maybe_parens => [$self, $cx, 16]});
679             } else {
680 1 50 33     13 return $self->unop(
681             $op, $cx,
682             $op->first->name eq 'const'
683             && $op->first->private & B::OPpCONST_NOVER
684             ? "no"
685             : $opname,
686             1, # llafr does not apply
687             );
688             }
689 0         0 Carp::confess("unhandled condition in pp_require");
690             }
691              
692              
693 6     6 0 25 sub pp_schomp { maybe_targmy(@_, \&unop, "chomp") }
694 6     6 0 26 sub pp_schop { maybe_targmy(@_, \&unop, "chop") }
695 0     0 0 0 sub pp_scope { scopeop(0, @_); }
696              
697 50     50 0 164 sub pp_and { logop(@_, "and", 3, "&&", 11, "if") }
698              
699             sub pp_cond_expr
700             {
701 0     0 0 0 my $self = shift;
702 0         0 my($op, $cx) = @_;
703 0         0 my $cond = $op->first;
704 0         0 my $true = $cond->sibling;
705 0         0 my $false = $true->sibling;
706 0         0 my $cuddle = $self->{'cuddle'};
707 0         0 my $type = 'if';
708 0 0 0     0 unless ($cx < 1 and (B::Deparse::is_scope($true) and $true->name ne "null") and
      0        
      0        
      0        
      0        
709             (B::Deparse::is_scope($false) || B::Deparse::is_ifelse_cont($false))
710             and $self->{'expand'} < 7) {
711             # FIXME: turn into template
712 0         0 my $cond_info = $self->deparse($cond, 8, $op);
713 0         0 my $true_info = $self->deparse($true, 6, $op);
714 0         0 my $false_info = $self->deparse($false, 8, $op);
715 0         0 return $self->info_from_template('ternary ?', $op, "%c ? %c : %c",
716             [0, 1, 2],
717             [$cond_info, $true_info, $false_info],
718             {maybe_parens => [$self, $cx, 8]});
719             }
720              
721 0         0 my $cond_info = $self->deparse($cond, 1, $op);
722 0         0 my $true_info = $self->deparse($true, 0, $op);
723 0         0 my $fmt = "%|if (%c) {\n%+%c\n%-}";
724 0         0 my @exprs = ($cond_info, $true_info);
725 0         0 my @args_spec = (0, 1);
726              
727 0         0 my $i;
728 0   0     0 for ($i=0; !B::Deparse::null($false) and B::Deparse::is_ifelse_cont($false); $i++) {
729 0         0 my $newop = $false->first;
730 0         0 my $newcond = $newop->first;
731 0         0 my $newtrue = $newcond->sibling;
732 0         0 $false = $newtrue->sibling; # last in chain is OP_AND => no else
733 0 0       0 if ($newcond->name eq "lineseq")
734             {
735             # lineseq to ensure correct line numbers in elsif()
736             # Bug #37302 fixed by change #33710.
737 0         0 $newcond = $newcond->first->sibling;
738             }
739 0         0 my $newcond_info = $self->deparse($newcond, 1, $op);
740 0         0 my $newtrue_info = $self->deparse($newtrue, 0, $op);
741 0         0 push @args_spec, scalar(@args_spec), scalar(@args_spec)+1;
742 0         0 push @exprs, $newcond_info, $newtrue_info;
743 0         0 $fmt .= " elsif ( %c ) {\n%+%c\n\%-}";
744             }
745 0 0       0 $type .= " elsif($i)" if $i;
746 0         0 my $false_info;
747 0 0       0 if (!B::Deparse::null($false)) {
748 0         0 $false_info = $self->deparse($false, 0, $op);
749 0         0 $fmt .= "${cuddle}else {\n%+%c\n%-}";
750 0         0 push @args_spec, scalar(@args_spec);
751 0         0 push @exprs, $false_info;
752 0         0 $type .= ' else';
753             }
754 0         0 return $self->info_from_template($type, $op, $fmt, \@args_spec, \@exprs);
755             }
756              
757             sub pp_const {
758 72     72 0 107 my $self = shift;
759 72         127 my($op, $cx) = @_;
760 72 50       281 if ($op->private & OPpCONST_ARYBASE) {
761 0         0 return info_from_text($op, $self, '$[', 'const_ary', {});
762             }
763             # if ($op->private & OPpCONST_BARE) { # trouble with '=>' autoquoting
764             # return $self->const_sv($op)->PV;
765             # }
766 72         423 my $sv = $self->const_sv($op);
767 72         263 return $self->const($sv, $cx);;
768             }
769              
770             # Handle subroutien calls. These are a bit complicated.
771             # NOTE: this is not right for CPerl, so it needs to be split out.
772             sub pp_entersub
773             {
774 596     596 0 1265 my($self, $op, $cx) = @_;
775 596 100       5724 return $self->e_method($op, $self->_method($op, $cx))
776             unless B::Deparse::null $op->first->sibling;
777 594         1624 my $prefix = "";
778 594         1073 my $amper = "";
779 594         854 my($kid, @exprs);
780 594 50 33     3785 if ($op->flags & OPf_SPECIAL && !($op->flags & OPf_MOD)) {
    50          
781 0         0 $prefix = "do ";
782             } elsif ($op->private & OPpENTERSUB_AMPER) {
783 0         0 $amper = "&";
784             }
785 594         1933 $kid = $op->first;
786              
787 594         2148 my $other_ops = [$kid, $kid->first];
788 594         2466 $kid = $kid->first->sibling; # skip ex-list, pushmark
789              
790 594         4348 for (; not B::Deparse::null $kid->sibling; $kid = $kid->sibling) {
791 766         5660 push @exprs, $kid;
792             }
793 594         1725 my ($simple, $proto, $subname_info) = (0, undef, undef);
794 594 50 0     13965 if (B::Deparse::is_scope($kid)) {
    50          
    0          
795 0         0 $amper = "&";
796 0         0 $subname_info = $self->deparse($kid, 0, $op);
797 0         0 $subname_info->{texts} = ['{', $subname_info->texts, '}'];
798 0         0 $subname_info->{text} = join('', @$subname_info->{texts});
799             } elsif ($kid->first->name eq "gv") {
800 594         3227 my $gv = $self->gv_or_padgv($kid->first);
801 594         1047 my $cv;
802 594 100 66     7009 if (class($gv) eq 'GV' && class($cv = $gv->CV) ne "SPECIAL"
      33        
      66        
803             || $gv->FLAGS & SVf_ROK && class($cv = $gv->RV) eq 'CV') {
804 560 100       2009 $proto = $cv->PV if $cv->FLAGS & SVf_POK;
805             }
806 594         1063 $simple = 1; # only calls of named functions can be prototyped
807 594         1445 $subname_info = $self->deparse($kid, 24, $op);
808 594         846 my $fq;
809             # Fully qualify any sub name that conflicts with a lexical.
810 594 50 33     11392 if ($self->lex_in_scope("&$kid")
    50          
811             || $self->lex_in_scope("&$kid", 1))
812             {
813 0         0 $fq++;
814             } elsif (!$amper) {
815 594 50       1956 if ($subname_info->{text} eq 'main::') {
816 0         0 $subname_info->{text} = '::';
817             } else {
818 594 50 33     2790 if ($kid !~ /::/ && $kid ne 'x') {
819             # Fully qualify any sub name that is also a keyword. While
820             # we could check the import flag, we cannot guarantee that
821             # the code deparsed so far would set that flag, so we qual-
822             # ify the names regardless of importation.
823 0 0       0 if (exists $feature_keywords{$kid}) {
    0          
824 0 0       0 $fq++ if $self->feature_enabled($kid);
825 0         0 } elsif (do { local $@; local $SIG{__DIE__};
  0         0  
826 0         0 eval { () = prototype "CORE::$kid"; 1 } }) {
  0         0  
  0         0  
827 0         0 $fq++
828             }
829             }
830             }
831 594 50       4130 if ($subname_info->{text} !~ /^(?:\w|::)(?:[\w\d]|::(?!\z))*\z/) {
832 0         0 $subname_info->{text} = $self->single_delim($$kid, "q", "'", $kid) . '->';
833             }
834             }
835             } elsif (B::Deparse::is_scalar ($kid->first) && $kid->first->name ne 'rv2cv') {
836 0         0 $amper = "&";
837 0         0 $subname_info = $self->deparse($kid, 24, $op);
838             } else {
839 0         0 $prefix = "";
840 0 0 0     0 my $arrow = is_subscriptable($kid->first) || $kid->first->name eq "padcv" ? "" : "->";
841 0         0 $subname_info = $self->deparse($kid, 24, $op);
842 0         0 $subname_info->{text} .= $arrow;
843             }
844              
845             # Doesn't matter how many prototypes there are, if
846             # they haven't happened yet!
847 594         1210 my $declared;
848 594         1254 my $sub_name = $subname_info->{text};
849             {
850 3     3   24 no strict 'refs';
  3         5  
  3         75  
  594         806  
851 3     3   12 no warnings 'uninitialized';
  3         7  
  3         5298  
852             $declared = exists $self->{'subs_declared'}{$sub_name}
853             || (
854             defined &{ ${$self->{'curstash'}."::"}{$sub_name} }
855             && !exists
856             $self->{'subs_deparsed'}{$self->{'curstash'}."::" . $sub_name}
857 594   66     2226 && defined prototype $self->{'curstash'}."::" . $sub_name
858             );
859 594 50 66     2774 if (!$declared && defined($proto)) {
860             # Avoid "too early to check prototype" warning
861 0         0 ($amper, $proto) = ('&');
862             }
863             }
864              
865 594         1131 my (@texts, @body, $type);
866 594         1101 @body = ();
867 594 100 66     1772 if ($declared and defined $proto and not $amper) {
      66        
868 1         3 my $args;
869 1         15 ($amper, $args) = $self->check_proto($op, $proto, @exprs);
870 1 50       4 if ($amper eq "&") {
871 0         0 @body = map($self->deparse($_, 6, $op), @exprs);
872             } else {
873 1 50       5 @body = @$args if @$args;
874             }
875             } else {
876 593         1931 @body = map($self->deparse($_, 6, $op), @exprs);
877             }
878              
879 594 50 33     2118 if ($prefix or $amper) {
880 0 0       0 if ($sub_name eq '&') {
881             # &{&} cannot be written as &&
882 0         0 $subname_info->{texts} = ["{", @{$subname_info->{texts}}, "}"];
  0         0  
883 0         0 $subname_info->{text} = join('', $subname_info->{texts});
884             }
885 0 0       0 if ($op->flags & OPf_STACKED) {
886 0         0 $type = 'prefix- or &-stacked call()';
887 0         0 @texts = ($prefix, $amper, $subname_info, "(", $self->combine2str(', ', \@body), ")");
888             } else {
889 0         0 $type = 'prefix or &- call';
890 0         0 @texts = ($prefix, $amper, $subname_info);
891             }
892             } else {
893             # It's a syntax error to call CORE::GLOBAL::foo with a prefix,
894             # so it must have been translated from a keyword call. Translate
895             # it back.
896 594         1526 $subname_info->{text} =~ s/^CORE::GLOBAL:://;
897 594 100       1454 my $dproto = defined($proto) ? $proto : "undefined";
898 594 100 33     1251 if (!$declared) {
    50 33        
    50 33        
    50          
899 593         942 $type = 'call (no prior declaration)';
900 593         2395 @texts = dedup_parens_func($self, $subname_info, \@body);
901 593         2545 my $node = B::DeparseTree::Node->new($op, $self, \@texts,
902             '', $type,
903             {other_ops => $other_ops});
904              
905             # Take the subname_info portion of $node and use that as the
906             # part of the parent, null, pushmark ops.
907 593 50 33     2373 if ($subname_info && $other_ops) {
908 593         1152 my $str = $node->{text};
909 593         1625 my $position = [0, length($subname_info->{text})];
910 593         1178 my @new_ops = ();
911 593         1130 foreach my $skipped_op (@$other_ops) {
912 1186         6120 my $new_op = $self->info_from_string($op->name, $skipped_op, $str,
913             {position => $position});
914 1186         2948 push @new_ops, $new_op;
915             }
916 593         1507 $node->{other_ops} = \@new_ops;
917             }
918 593         2325 return $node;
919              
920             } elsif ($dproto =~ /^\s*\z/) {
921 0         0 $type = 'call no protype';
922 0         0 @texts = ($subname_info);
923             } elsif ($dproto eq "\$" and B::Deparse::is_scalar($exprs[0])) {
924 0         0 $type = 'call - $ prototype';
925             # is_scalar is an excessively conservative test here:
926             # really, we should be comparing to the precedence of the
927             # top operator of $exprs[0] (ala unop()), but that would
928             # take some major code restructuring to do right.
929 0         0 @texts = $self->maybe_parens_func($sub_name, $self->combine2str(', ', \@body), $cx, 16);
930             } elsif ($dproto ne '$' and defined($proto) || $simple) { #'
931 1         3 $type = "call $sub_name having prototype";
932 1         5 @texts = $self->maybe_parens_func($sub_name, $self->combine2str(', ', \@body), $cx, 5);
933 1         10 return B::DeparseTree::Node->new($op, $self, \@texts,
934             '', $type,
935             {other_ops => $other_ops});
936             } else {
937 0         0 $type = 'call';
938 0         0 @texts = dedup_parens_func($self, $subname_info, \@body);
939 0         0 return B::DeparseTree::Node->new($op, $self, \@texts,
940             '', $type,
941             {other_ops => $other_ops});
942             }
943             }
944 0         0 my $node = $self->info_from_template($type, $op,
945             '%C', [[0, $#texts, '']], \@texts,
946             {other_ops => $other_ops});
947              
948             # Take the subname_info portion of $node and use that as the
949             # part of the parent, null, pushmark ops.
950 0 0 0     0 if ($subname_info && $other_ops) {
951 0         0 my $str = $node->{text};
952 0         0 my $position = [0, length($subname_info->{text})];
953 0         0 my @new_ops = ();
954 0         0 foreach my $skipped_op (@$other_ops) {
955 0         0 my $new_op = $self->info_from_string($op->name, $skipped_op, $str,
956             {position => $position});
957 0         0 push @new_ops, $new_op;
958             }
959 0         0 $node->{other_ops} = \@new_ops;
960             }
961 0         0 return $node;
962             }
963              
964             sub pp_entereval {
965 12 100   12 0 72 unop(
966             @_,
967             $_[1]->private & OPpEVAL_BYTES ? 'evalbytes' : "eval"
968             )
969             }
970              
971             sub pp_flop
972             {
973 0     0 0 0 my $self = shift;
974 0         0 my($op, $cx) = @_;
975 0         0 my $flip = $op->first;
976 0 0       0 my $type = ($flip->flags & OPf_SPECIAL) ? "..." : "..";
977 0         0 my $node =$self->range($flip->first, $cx, $type);
978 0         0 return $self->info_from_template("pp_flop $type", $op, "%c", undef, [$node], {});
979             }
980              
981             sub pp_gv
982             {
983 674     674 0 1507 my($self, $op, $cx) = @_;
984 674         1792 my $gv = $self->gv_or_padgv($op);
985 674         13865 my $name = $self->gv_name($gv);
986 674         3165 return $self->info_from_string("global variable $name", $op, $name);
987             }
988              
989             # FIXME: adjust use of maybe_local_str
990             sub pp_gvsv
991             {
992 1013     1013 0 1793 my($self, $op, $cx) = @_;
993 1013         2666 my $gv = $self->gv_or_padgv($op);
994 1013         19591 return $self->maybe_local_str($op, $cx,
995             $self->stash_variable("\$",
996             $self->gv_name($gv), $cx));
997             }
998              
999             sub pp_null
1000             {
1001 4392 50   4392 0 12854 $] < 5.022 ? null_older(@_) : null_newer(@_);
1002             }
1003              
1004             sub pp_once
1005             {
1006 1     1 0 4 my ($self, $op, $cx) = @_;
1007 1         21 my $cond = $op->first;
1008 1         10 my $true = $cond->sibling;
1009              
1010 1         7 return $self->deparse($true, $cx);
1011             }
1012              
1013 2     2 0 11 sub pp_print { indirop(@_, "print") }
1014 0     0 0 0 sub pp_prtf { indirop(@_, "printf") }
1015              
1016 4     4 0 22 sub pp_rand { maybe_targmy(@_, \&unop, "rand") }
1017              
1018 49     49 0 216 sub pp_or { logop(@_, "or", 2, "||", 10, "unless") }
1019 0     0 0 0 sub pp_dor { logop(@_, "//", 10) }
1020              
1021 0     0 0 0 sub pp_mapwhile { mapop(@_, "map") }
1022 0     0 0 0 sub pp_grepwhile { mapop(@_, "grep") }
1023              
1024 0     0 0 0 sub pp_complement { maybe_targmy(@_, \&pfixop, "~", 21) }
1025 2     2 0 11 sub pp_getppid { maybe_targmy(@_, \&baseop, "getppid") }
1026 0     0 0 0 sub pp_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }
1027 0     0 0 0 sub pp_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }
1028 2     2 0 12 sub pp_time { maybe_targmy(@_, \&baseop, "time") }
1029              
1030 5     5 0 30 sub pp_preinc { pfixop(@_, "++", 23) }
1031 0     0 0 0 sub pp_predec { pfixop(@_, "--", 23) }
1032 0     0 0 0 sub pp_i_preinc { pfixop(@_, "++", 23) }
1033 0     0 0 0 sub pp_i_predec { pfixop(@_, "--", 23) }
1034              
1035             sub pp_subst {
1036             {
1037 18 50   18 0 26 $] < 5.022 ? subst_older(@_) : subst_newer(@_);
  18         66  
1038             }
1039             }
1040              
1041             sub pp_substr {
1042 6     6 0 15 my ($self,$op,$cx) = @_;
1043 6 50       46 if ($op->private & B::Deparse::OPpSUBSTR_REPL_FIRST) {
1044 0         0 my $left = listop($self, $op, 7, "substr", $op->first->sibling->sibling);
1045 0         0 my $right = $self->deparse($op->first->sibling, 7, $op);
1046 0         0 return info_from_list($op, $self,[$left, '=', $right], ' ',
1047             'substr_repl_first', {});
1048             }
1049 6         29 return maybe_local(@_, listop(@_, "substr"))
1050             }
1051             # FIXME:
1052             # Different between 5.20 and 5.22. We've used 5.22 though.
1053             # Go over and make sure this is okay.
1054             sub pp_stub {
1055 1294     1294 0 2648 my ($self, $op) = @_;
1056 1294         3179 $self->info_from_string('stub ()', $op, '()')
1057             };
1058              
1059 2     2 0 11 sub pp_symlink { maybe_targmy(@_, \&listop, "symlink") }
1060              
1061             sub pp_trans {
1062 6     6 0 10 my $self = shift;
1063 6         15 my($op, $cx) = @_;
1064 6         8 my($from, $to);
1065 6         32 my $class = class($op);
1066 6         21 my $priv_flags = $op->private;
1067 6 50       15 if ($class eq "PVOP") {
    0          
1068 6         788 ($from, $to) = B::Deparse::tr_decode_byte($op->pv, $priv_flags);
1069             } elsif ($class eq "PADOP") {
1070 0         0 ($from, $to)
1071             = tr_decode_utf8($self->padval($op->padix)->RV, $priv_flags);
1072             } else { # class($op) eq "SVOP"
1073 0         0 ($from, $to) = B::Deparse::tr_decode_utf8($op->sv->RV, $priv_flags);
1074             }
1075 6         19 my $flags = "";
1076 6 100       19 $flags .= "c" if $priv_flags & OPpTRANS_COMPLEMENT;
1077 6 100       16 $flags .= "d" if $priv_flags & OPpTRANS_DELETE;
1078 6 100 66     28 $to = "" if $from eq $to and $flags eq "";
1079 6 100       11 $flags .= "s" if $priv_flags & OPpTRANS_SQUASH;
1080 6         53 return info_from_list($op, $self, ['tr', double_delim($from, $to), $flags],
1081             '', 'pp_trans', {});
1082             }
1083              
1084             sub pp_transr {
1085 2     2 0 4 my $self = $_[0];
1086 2         3 my $op = $_[1];
1087 2         7 my $info = pp_trans(@_);
1088 2         26 return info_from_text($op, $self, $info->{text} . 'r', 'pp_transr',
1089             {body => [$info]});
1090             }
1091              
1092             sub pp_unstack {
1093 1     1 0 4 my ($self, $op) = @_;
1094             # see also leaveloop
1095 1         5 return info_from_text($op, $self, '', 'unstack', {});
1096             }
1097              
1098 2     2 0 8 sub pp_wait { maybe_targmy(@_, \&baseop, "wait") }
1099 2     2 0 6 sub pp_wantarray { baseop(@_, "wantarray") }
1100              
1101             # xor is syntactically a logop, but it's really a binop (contrary to
1102             # old versions of opcode.pl). Syntax is what matters here.
1103 8     8 0 29 sub pp_xor { logop(@_, "xor", 2, "", 0, "") }
1104              
1105             1;