| 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; |