Re: [PATCH] Copy on write for $& and $1...
[p5sagit/p5-mst-13.2.git] / ext / B / B / Concise.pm
CommitLineData
c99ca59a 1package B::Concise;
c27ea44e 2# Copyright (C) 2000-2003 Stephen McCamant. All rights reserved.
c99ca59a 3# This program is free software; you can redistribute and/or modify it
4# under the same terms as Perl itself.
5
c99ca59a 6use strict;
78ad9108 7use warnings;
8
9use Exporter ();
10
40b5b14f 11our $VERSION = "0.54";
78ad9108 12our @ISA = qw(Exporter);
13our @EXPORT_OK = qw(set_style add_callback);
14
c99ca59a 15use B qw(class ppname main_start main_root main_cv cstring svref_2object
16 SVf_IOK SVf_NOK SVf_POK OPf_KIDS);
17
18my %style =
19 ("terse" =>
c3caa09d 20 ["(?(#label =>\n)?)(*( )*)#class (#addr) #name (?([#targ])?) "
21 . "#svclass~(?((#svaddr))?)~#svval~(?(label \"#coplabel\")?)\n",
c99ca59a 22 "(*( )*)goto #class (#addr)\n",
23 "#class pp_#name"],
24 "concise" =>
25 ["#hyphseq2 (*( (x( ;)x))*)<#classsym> "
26 . "#exname#arg(?([#targarglife])?)~#flags(?(/#private)?)(x(;~->#next)x)\n",
27 " (*( )*) goto #seq\n",
28 "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"],
29 "linenoise" =>
30 ["(x(;(*( )*))x)#noise#arg(?([#targarg])?)(x( ;\n)x)",
31 "gt_#seq ",
32 "(?(#seq)?)#noise#arg(?([#targarg])?)"],
33 "debug" =>
34 ["#class (#addr)\n\top_next\t\t#nextaddr\n\top_sibling\t#sibaddr\n\t"
35 . "op_ppaddr\tPL_ppaddr[OP_#NAME]\n\top_type\t\t#typenum\n\top_seq\t\t"
36 . "#seqnum\n\top_flags\t#flagval\n\top_private\t#privval\n"
37 . "(?(\top_first\t#firstaddr\n)?)(?(\top_last\t\t#lastaddr\n)?)"
38 . "(?(\top_sv\t\t#svaddr\n)?)",
39 " GOTO #addr\n",
40 "#addr"],
41 "env" => [$ENV{B_CONCISE_FORMAT}, $ENV{B_CONCISE_GOTO_FORMAT},
42 $ENV{B_CONCISE_TREE_FORMAT}],
43 );
44
45my($format, $gotofmt, $treefmt);
46my $curcv;
c27ea44e 47my $cop_seq_base;
78ad9108 48my @callbacks;
49
50sub set_style {
51 ($format, $gotofmt, $treefmt) = @_;
52}
53
54sub add_callback {
55 push @callbacks, @_;
56}
c99ca59a 57
58sub concise_cv {
59 my ($order, $cvref) = @_;
60 my $cv = svref_2object($cvref);
61 $curcv = $cv;
c27ea44e 62 sequence($cv->START);
c99ca59a 63 if ($order eq "exec") {
64 walk_exec($cv->START);
65 } elsif ($order eq "basic") {
66 walk_topdown($cv->ROOT, sub { $_[0]->concise($_[1]) }, 0);
67 } else {
68 print tree($cv->ROOT, 0)
69 }
70}
71
72my $start_sym = "\e(0"; # "\cN" sometimes also works
73my $end_sym = "\e(B"; # "\cO" respectively
74
75my @tree_decorations =
76 ([" ", "--", "+-", "|-", "| ", "`-", "-", 1],
77 [" ", "-", "+", "+", "|", "`", "", 0],
78 [" ", map("$start_sym$_$end_sym", "qq", "wq", "tq", "x ", "mq", "q"), 1],
79 [" ", map("$start_sym$_$end_sym", "q", "w", "t", "x", "m"), "", 0],
80 );
81my $tree_style = 0;
82
83my $base = 36;
84my $big_endian = 1;
85
86my $order = "basic";
87
78ad9108 88set_style(@{$style{concise}});
89
c99ca59a 90sub compile {
91 my @options = grep(/^-/, @_);
92 my @args = grep(!/^-/, @_);
93 my $do_main = 0;
c99ca59a 94 for my $o (@options) {
95 if ($o eq "-basic") {
96 $order = "basic";
97 } elsif ($o eq "-exec") {
98 $order = "exec";
99 } elsif ($o eq "-tree") {
100 $order = "tree";
101 } elsif ($o eq "-compact") {
102 $tree_style |= 1;
103 } elsif ($o eq "-loose") {
104 $tree_style &= ~1;
105 } elsif ($o eq "-vt") {
106 $tree_style |= 2;
107 } elsif ($o eq "-ascii") {
108 $tree_style &= ~2;
109 } elsif ($o eq "-main") {
110 $do_main = 1;
111 } elsif ($o =~ /^-base(\d+)$/) {
112 $base = $1;
113 } elsif ($o eq "-bigendian") {
114 $big_endian = 1;
115 } elsif ($o eq "-littleendian") {
116 $big_endian = 0;
117 } elsif (exists $style{substr($o, 1)}) {
78ad9108 118 set_style(@{$style{substr($o, 1)}});
c99ca59a 119 } else {
120 warn "Option $o unrecognized";
121 }
122 }
c27ea44e 123 return sub {
124 if (@args) {
c99ca59a 125 for my $objname (@args) {
126 $objname = "main::" . $objname unless $objname =~ /::/;
c27ea44e 127 print "$objname:\n";
c99ca59a 128 eval "concise_cv(\$order, \\&$objname)";
129 die "concise_cv($order, \\&$objname) failed: $@" if $@;
130 }
131 }
c27ea44e 132 if (!@args or $do_main) {
133 print "main program:\n" if $do_main;
134 sequence(main_start);
40b5b14f 135 $curcv = main_cv;
c27ea44e 136 if ($order eq "exec") {
137 return if class(main_start) eq "NULL";
c27ea44e 138 walk_exec(main_start);
139 } elsif ($order eq "tree") {
140 return if class(main_root) eq "NULL";
c27ea44e 141 print tree(main_root, 0);
142 } elsif ($order eq "basic") {
143 return if class(main_root) eq "NULL";
c27ea44e 144 walk_topdown(main_root,
145 sub { $_[0]->concise($_[1]) }, 0);
146 }
c99ca59a 147 }
148 }
149}
150
151my %labels;
152my $lastnext;
153
154my %opclass = ('OP' => "0", 'UNOP' => "1", 'BINOP' => "2", 'LOGOP' => "|",
155 'LISTOP' => "@", 'PMOP' => "/", 'SVOP' => "\$", 'GVOP' => "*",
051f02e9 156 'PVOP' => '"', 'LOOP' => "{", 'COP' => ";", 'PADOP' => "#");
c99ca59a 157
35fc55f1 158no warnings 'qw'; # "Possible attempt to put comments..."
159my @linenoise =
160 qw'# () sc ( @? 1 $* gv *{ m$ m@ m% m? p/ *$ $ $# & a& pt \\ s\\ rf bl
c99ca59a 161 ` *? <> ?? ?/ r/ c/ // qr s/ /c y/ = @= C sC Cp sp df un BM po +1 +I
162 -1 -I 1+ I+ 1- I- ** * i* / i/ %$ i% x + i+ - i- . " << >> < i<
163 > i> <= i, >= i. == i= != i! <? i? s< s> s, s. s= s! s? b& b^ b| -0 -i
164 ! ~ a2 si cs rd sr e^ lg sq in %x %o ab le ss ve ix ri sf FL od ch cy
165 uf lf uc lc qm @ [f [ @[ eh vl ky dl ex % ${ @{ uk pk st jn ) )[ a@
166 a% sl +] -] [- [+ so rv GS GW MS MW .. f. .f && || ^^ ?: &= |= -> s{ s}
167 v} ca wa di rs ;; ; ;d }{ { } {} f{ it {l l} rt }l }n }r dm }g }e ^o
168 ^c ^| ^# um bm t~ u~ ~d DB db ^s se ^g ^r {w }w pf pr ^O ^K ^R ^W ^d ^v
169 ^e ^t ^k t. fc ic fl .s .p .b .c .l .a .h g1 s1 g2 s2 ?. l? -R -W -X -r
170 -w -x -e -o -O -z -s -M -A -C -S -c -b -f -d -p -l -u -g -k -t -T -B cd
171 co cr u. cm ut r. l@ s@ r@ mD uD oD rD tD sD wD cD f$ w$ p$ sh e$ k$ g3
172 g4 s4 g5 s5 T@ C@ L@ G@ A@ S@ Hg Hc Hr Hw Mg Mc Ms Mr Sg Sc So rq do {e
173 e} {t t} g6 G6 6e g7 G7 7e g8 G8 8e g9 G9 9e 6s 7s 8s 9s 6E 7E 8E 9E Pn
c27ea44e 174 Pu GP SP EP Gn Gg GG SG EG g0 c$ lk t$ ;s n> // /= CO';
c99ca59a 175
176my $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
177
178sub op_flags {
179 my($x) = @_;
180 my(@v);
181 push @v, "v" if ($x & 3) == 1;
182 push @v, "s" if ($x & 3) == 2;
183 push @v, "l" if ($x & 3) == 3;
184 push @v, "K" if $x & 4;
185 push @v, "P" if $x & 8;
186 push @v, "R" if $x & 16;
187 push @v, "M" if $x & 32;
188 push @v, "S" if $x & 64;
189 push @v, "*" if $x & 128;
190 return join("", @v);
191}
192
193sub base_n {
194 my $x = shift;
195 return "-" . base_n(-$x) if $x < 0;
196 my $str = "";
197 do { $str .= substr($chars, $x % $base, 1) } while $x = int($x / $base);
198 $str = reverse $str if $big_endian;
199 return $str;
200}
201
c27ea44e 202my %sequence_num;
203my $seq_max = 1;
204
205sub seq {
206 my($op) = @_;
207 return "-" if not exists $sequence_num{$$op};
208 return base_n($sequence_num{$$op});
209}
c99ca59a 210
211sub walk_topdown {
212 my($op, $sub, $level) = @_;
213 $sub->($op, $level);
214 if ($op->flags & OPf_KIDS) {
215 for (my $kid = $op->first; $$kid; $kid = $kid->sibling) {
216 walk_topdown($kid, $sub, $level + 1);
217 }
218 }
b2a3cfdd 219 if (class($op) eq "PMOP" and $ {$op->pmreplroot}
220 and $op->pmreplroot->isa("B::OP")) {
c99ca59a 221 walk_topdown($op->pmreplroot, $sub, $level + 1);
222 }
223}
224
225sub walklines {
226 my($ar, $level) = @_;
227 for my $l (@$ar) {
228 if (ref($l) eq "ARRAY") {
229 walklines($l, $level + 1);
230 } else {
231 $l->concise($level);
232 }
233 }
234}
235
236sub walk_exec {
237 my($top, $level) = @_;
238 my %opsseen;
239 my @lines;
240 my @todo = ([$top, \@lines]);
241 while (@todo and my($op, $targ) = @{shift @todo}) {
242 for (; $$op; $op = $op->next) {
243 last if $opsseen{$$op}++;
244 push @$targ, $op;
245 my $name = $op->name;
62e36f8a 246 if (class($op) eq "LOGOP") {
c99ca59a 247 my $ar = [];
248 push @$targ, $ar;
249 push @todo, [$op->other, $ar];
250 } elsif ($name eq "subst" and $ {$op->pmreplstart}) {
251 my $ar = [];
252 push @$targ, $ar;
253 push @todo, [$op->pmreplstart, $ar];
254 } elsif ($name =~ /^enter(loop|iter)$/) {
255 $labels{$op->nextop->seq} = "NEXT";
256 $labels{$op->lastop->seq} = "LAST";
257 $labels{$op->redoop->seq} = "REDO";
258 }
259 }
260 }
261 walklines(\@lines, 0);
262}
263
c27ea44e 264# The structure of this routine is purposely modeled after op.c's peep()
265sub sequence {
266 my($op) = @_;
267 my $oldop = 0;
268 return if class($op) eq "NULL" or exists $sequence_num{$$op};
269 for (; $$op; $op = $op->next) {
270 last if exists $sequence_num{$$op};
271 my $name = $op->name;
272 if ($name =~ /^(null|scalar|lineseq|scope)$/) {
273 next if $oldop and $ {$op->next};
274 } else {
275 $sequence_num{$$op} = $seq_max++;
276 if (class($op) eq "LOGOP") {
277 my $other = $op->other;
278 $other = $other->next while $other->name eq "null";
279 sequence($other);
280 } elsif (class($op) eq "LOOP") {
281 my $redoop = $op->redoop;
282 $redoop = $redoop->next while $redoop->name eq "null";
283 sequence($redoop);
284 my $nextop = $op->nextop;
285 $nextop = $nextop->next while $nextop->name eq "null";
286 sequence($nextop);
287 my $lastop = $op->lastop;
288 $lastop = $lastop->next while $lastop->name eq "null";
289 sequence($lastop);
290 } elsif ($name eq "subst" and $ {$op->pmreplstart}) {
291 my $replstart = $op->pmreplstart;
292 $replstart = $replstart->next while $replstart->name eq "null";
293 sequence($replstart);
294 }
295 }
296 $oldop = $op;
297 }
298}
299
c99ca59a 300sub fmt_line {
301 my($hr, $fmt, $level) = @_;
302 my $text = $fmt;
303 $text =~ s/\(\?\(([^\#]*?)\#(\w+)([^\#]*?)\)\?\)/
304 $hr->{$2} ? $1.$hr->{$2}.$3 : ""/eg;
305 $text =~ s/\(x\((.*?);(.*?)\)x\)/$order eq "exec" ? $1 : $2/egs;
306 $text =~ s/\(\*\(([^;]*?)\)\*\)/$1 x $level/egs;
307 $text =~ s/\(\*\((.*?);(.*?)\)\*\)/$1 x ($level - 1) . $2 x ($level>0)/egs;
308 $text =~ s/#([a-zA-Z]+)(\d+)/sprintf("%-$2s", $hr->{$1})/eg;
309 $text =~ s/#([a-zA-Z]+)/$hr->{$1}/eg;
310 $text =~ s/[ \t]*~+[ \t]*/ /g;
311 return $text;
312}
313
314my %priv;
315$priv{$_}{128} = "LVINTRO"
316 for ("pos", "substr", "vec", "threadsv", "gvsv", "rv2sv", "rv2hv", "rv2gv",
317 "rv2av", "rv2arylen", "aelem", "helem", "aslice", "hslice", "padsv",
318 "padav", "padhv");
319$priv{$_}{64} = "REFC" for ("leave", "leavesub", "leavesublv", "leavewrite");
320$priv{"aassign"}{64} = "COMMON";
c99ca59a 321$priv{"sassign"}{64} = "BKWARD";
322$priv{$_}{64} = "RTIME" for ("match", "subst", "substcont");
323@{$priv{"trans"}}{1,2,4,8,16,64} = ("<UTF", ">UTF", "IDENT", "SQUASH", "DEL",
324 "COMPL", "GROWS");
325$priv{"repeat"}{64} = "DOLIST";
326$priv{"leaveloop"}{64} = "CONT";
327@{$priv{$_}}{32,64,96} = ("DREFAV", "DREFHV", "DREFSV")
328 for ("entersub", map("rv2${_}v", "a", "s", "h", "g"), "aelem", "helem");
329$priv{"entersub"}{16} = "DBG";
330$priv{"entersub"}{32} = "TARG";
331@{$priv{$_}}{4,8,128} = ("INARGS","AMPER","NO()") for ("entersub", "rv2cv");
332$priv{"gv"}{32} = "EARLYCV";
333$priv{"aelem"}{16} = $priv{"helem"}{16} = "LVDEFER";
334$priv{$_}{16} = "OURINTR" for ("gvsv", "rv2sv", "rv2av", "rv2hv", "r2gv");
335$priv{$_}{16} = "TARGMY"
336 for (map(($_,"s$_"),"chop", "chomp"),
337 map(($_,"i_$_"), "postinc", "postdec", "multiply", "divide", "modulo",
338 "add", "subtract", "negate"), "pow", "concat", "stringify",
339 "left_shift", "right_shift", "bit_and", "bit_xor", "bit_or",
340 "complement", "atan2", "sin", "cos", "rand", "exp", "log", "sqrt",
341 "int", "hex", "oct", "abs", "length", "index", "rindex", "sprintf",
342 "ord", "chr", "crypt", "quotemeta", "join", "push", "unshift", "flock",
343 "chdir", "chown", "chroot", "unlink", "chmod", "utime", "rename",
344 "link", "symlink", "mkdir", "rmdir", "wait", "waitpid", "system",
345 "exec", "kill", "getppid", "getpgrp", "setpgrp", "getpriority",
346 "setpriority", "time", "sleep");
7a9b44b9 347@{$priv{"const"}}{8,16,32,64,128} = ("STRICT","ENTERED", '$[', "BARE", "WARN");
c99ca59a 348$priv{"flip"}{64} = $priv{"flop"}{64} = "LINENUM";
349$priv{"list"}{64} = "GUESSED";
350$priv{"delete"}{64} = "SLICE";
351$priv{"exists"}{64} = "SUB";
352$priv{$_}{64} = "LOCALE"
353 for ("sort", "prtf", "sprintf", "slt", "sle", "seq", "sne", "sgt", "sge",
354 "scmp", "lc", "uc", "lcfirst", "ucfirst");
355@{$priv{"sort"}}{1,2,4} = ("NUM", "INT", "REV");
356$priv{"threadsv"}{64} = "SVREFd";
c27ea44e 357@{$priv{$_}}{16,32,64,128} = ("INBIN","INCR","OUTBIN","OUTCR")
358 for ("open", "backtick");
c99ca59a 359$priv{"exit"}{128} = "VMS";
360
361sub private_flags {
362 my($name, $x) = @_;
363 my @s;
364 for my $flag (128, 96, 64, 32, 16, 8, 4, 2, 1) {
365 if ($priv{$name}{$flag} and $x & $flag and $x >= $flag) {
366 $x -= $flag;
367 push @s, $priv{$name}{$flag};
368 }
369 }
370 push @s, $x if $x;
371 return join(",", @s);
372}
373
c27ea44e 374sub concise_sv {
375 my($sv, $hr) = @_;
376 $hr->{svclass} = class($sv);
377 $hr->{svaddr} = sprintf("%#x", $$sv);
378 if ($hr->{svclass} eq "GV") {
379 my $gv = $sv;
380 my $stash = $gv->STASH->NAME;
381 if ($stash eq "main") {
382 $stash = "";
383 } else {
384 $stash = $stash . "::";
385 }
386 $hr->{svval} = "*$stash" . $gv->SAFENAME;
387 return "*$stash" . $gv->SAFENAME;
388 } else {
389 while (class($sv) eq "RV") {
390 $hr->{svval} .= "\\";
391 $sv = $sv->RV;
392 }
393 if (class($sv) eq "SPECIAL") {
40b5b14f 394 $hr->{svval} .= ["Null", "sv_undef", "sv_yes", "sv_no"]->[$$sv];
c27ea44e 395 } elsif ($sv->FLAGS & SVf_NOK) {
40b5b14f 396 $hr->{svval} .= $sv->NV;
c27ea44e 397 } elsif ($sv->FLAGS & SVf_IOK) {
40b5b14f 398 $hr->{svval} .= $sv->IV;
c27ea44e 399 } elsif ($sv->FLAGS & SVf_POK) {
40b5b14f 400 $hr->{svval} .= cstring($sv->PV);
c27ea44e 401 }
402 return $hr->{svclass} . " " . $hr->{svval};
403 }
404}
405
c99ca59a 406sub concise_op {
407 my ($op, $level, $format) = @_;
408 my %h;
409 $h{exname} = $h{name} = $op->name;
410 $h{NAME} = uc $h{name};
411 $h{class} = class($op);
412 $h{extarg} = $h{targ} = $op->targ;
413 $h{extarg} = "" unless $h{extarg};
414 if ($h{name} eq "null" and $h{targ}) {
415 $h{exname} = "ex-" . substr(ppname($h{targ}), 3);
416 $h{extarg} = "";
417 } elsif ($h{targ}) {
418 my $padname = (($curcv->PADLIST->ARRAY)[0]->ARRAY)[$h{targ}];
419 if (defined $padname and class($padname) ne "SPECIAL") {
0b40bd6d 420 $h{targarg} = $padname->PVX;
c99ca59a 421 my $intro = $padname->NVX - $cop_seq_base;
422 my $finish = int($padname->IVX) - $cop_seq_base;
423 $finish = "end" if $finish == 999999999 - $cop_seq_base;
424 $h{targarglife} = "$h{targarg}:$intro,$finish";
425 } else {
426 $h{targarglife} = $h{targarg} = "t" . $h{targ};
427 }
428 }
429 $h{arg} = "";
430 $h{svclass} = $h{svaddr} = $h{svval} = "";
431 if ($h{class} eq "PMOP") {
432 my $precomp = $op->precomp;
7a9b44b9 433 if (defined $precomp) {
c27ea44e 434 $precomp = cstring($precomp); # Escape literal control sequences
435 $precomp = "/$precomp/";
436 } else {
437 $precomp = "";
7a9b44b9 438 }
b2a3cfdd 439 my $pmreplroot = $op->pmreplroot;
34a48b4b 440 my $pmreplstart;
441 if ($$pmreplroot && $pmreplroot->isa("B::GV")) {
b2a3cfdd 442 # with C<@stash_array = split(/pat/, str);>,
443 # *stash_array is stored in pmreplroot.
444 $h{arg} = "($precomp => \@" . $pmreplroot->NAME . ")";
445 } elsif ($ {$op->pmreplstart}) {
c99ca59a 446 undef $lastnext;
447 $pmreplstart = "replstart->" . seq($op->pmreplstart);
448 $h{arg} = "(" . join(" ", $precomp, $pmreplstart) . ")";
449 } else {
450 $h{arg} = "($precomp)";
451 }
452 } elsif ($h{class} eq "PVOP" and $h{name} ne "trans") {
453 $h{arg} = '("' . $op->pv . '")';
454 $h{svval} = '"' . $op->pv . '"';
455 } elsif ($h{class} eq "COP") {
456 my $label = $op->label;
c3caa09d 457 $h{coplabel} = $label;
c99ca59a 458 $label = $label ? "$label: " : "";
459 my $loc = $op->file;
460 $loc =~ s[.*/][];
461 $loc .= ":" . $op->line;
462 my($stash, $cseq) = ($op->stash->NAME, $op->cop_seq - $cop_seq_base);
463 my $arybase = $op->arybase;
464 $arybase = $arybase ? ' $[=' . $arybase : "";
465 $h{arg} = "($label$stash $cseq $loc$arybase)";
466 } elsif ($h{class} eq "LOOP") {
467 $h{arg} = "(next->" . seq($op->nextop) . " last->" . seq($op->lastop)
468 . " redo->" . seq($op->redoop) . ")";
469 } elsif ($h{class} eq "LOGOP") {
470 undef $lastnext;
471 $h{arg} = "(other->" . seq($op->other) . ")";
472 } elsif ($h{class} eq "SVOP") {
c27ea44e 473 if (! ${$op->sv}) {
474 my $sv = (($curcv->PADLIST->ARRAY)[1]->ARRAY)[$op->targ];
475 $h{arg} = "[" . concise_sv($sv, \%h) . "]";
476 $h{targarglife} = $h{targarg} = "";
c99ca59a 477 } else {
c27ea44e 478 $h{arg} = "(" . concise_sv($op->sv, \%h) . ")";
c99ca59a 479 }
480 }
481 $h{seq} = $h{hyphseq} = seq($op);
482 $h{seq} = "" if $h{seq} eq "-";
483 $h{seqnum} = $op->seq;
484 $h{next} = $op->next;
485 $h{next} = (class($h{next}) eq "NULL") ? "(end)" : seq($h{next});
486 $h{nextaddr} = sprintf("%#x", $ {$op->next});
487 $h{sibaddr} = sprintf("%#x", $ {$op->sibling});
488 $h{firstaddr} = sprintf("%#x", $ {$op->first}) if $op->can("first");
489 $h{lastaddr} = sprintf("%#x", $ {$op->last}) if $op->can("last");
490
491 $h{classsym} = $opclass{$h{class}};
492 $h{flagval} = $op->flags;
493 $h{flags} = op_flags($op->flags);
494 $h{privval} = $op->private;
495 $h{private} = private_flags($h{name}, $op->private);
496 $h{addr} = sprintf("%#x", $$op);
497 $h{label} = $labels{$op->seq};
498 $h{typenum} = $op->type;
499 $h{noise} = $linenoise[$op->type];
78ad9108 500 $_->(\%h, $op, \$format, \$level) for @callbacks;
c99ca59a 501 return fmt_line(\%h, $format, $level);
502}
503
504sub B::OP::concise {
505 my($op, $level) = @_;
506 if ($order eq "exec" and $lastnext and $$lastnext != $$op) {
507 my $h = {"seq" => seq($lastnext), "class" => class($lastnext),
508 "addr" => sprintf("%#x", $$lastnext)};
509 print fmt_line($h, $gotofmt, $level+1);
510 }
511 $lastnext = $op->next;
512 print concise_op($op, $level, $format);
513}
514
515sub tree {
516 my $op = shift;
517 my $level = shift;
518 my $style = $tree_decorations[$tree_style];
519 my($space, $single, $kids, $kid, $nokid, $last, $lead, $size) = @$style;
520 my $name = concise_op($op, $level, $treefmt);
521 if (not $op->flags & OPf_KIDS) {
522 return $name . "\n";
523 }
524 my @lines;
525 for (my $kid = $op->first; $$kid; $kid = $kid->sibling) {
526 push @lines, tree($kid, $level+1);
527 }
528 my $i;
529 for ($i = $#lines; substr($lines[$i], 0, 1) eq " "; $i--) {
530 $lines[$i] = $space . $lines[$i];
531 }
532 if ($i > 0) {
533 $lines[$i] = $last . $lines[$i];
534 while ($i-- > 1) {
535 if (substr($lines[$i], 0, 1) eq " ") {
536 $lines[$i] = $nokid . $lines[$i];
537 } else {
538 $lines[$i] = $kid . $lines[$i];
539 }
540 }
541 $lines[$i] = $kids . $lines[$i];
542 } else {
543 $lines[0] = $single . $lines[0];
544 }
545 return("$name$lead" . shift @lines,
546 map(" " x (length($name)+$size) . $_, @lines));
547}
548
213a1a26 549# *** Warning: fragile kludge ahead ***
550# Because the B::* modules run in the same interpreter as the code
551# they're compiling, their presence tends to distort the view we have
552# of the code we're looking at. In particular, perl gives sequence
553# numbers to both OPs in general and COPs in particular. If the
554# program we're looking at were run on its own, these numbers would
555# start at 1. Because all of B::Concise and all the modules it uses
556# are compiled first, though, by the time we get to the user's program
557# the sequence numbers are alreay at pretty high numbers, which would
558# be distracting if you're trying to tell OPs apart. Therefore we'd
559# like to subtract an offset from all the sequence numbers we display,
560# to restore the simpler view of the world. The trick is to know what
561# that offset will be, when we're still compiling B::Concise! If we
562# hardcoded a value, it would have to change every time B::Concise or
563# other modules we use do. To help a little, what we do here is
564# compile a little code at the end of the module, and compute the base
565# sequence number for the user's program as being a small offset
566# later, so all we have to worry about are changes in the offset.
c27ea44e 567# (Note that we now only play this game with COP sequence numbers. OP
568# sequence numbers aren't used to refer to OPs from a distance, and
569# they don't have much significance, so we just generate our own
570# sequence numbers which are easier to control. This way we also don't
571# stand in the way of a possible future removal of OP sequence
572# numbers).
213a1a26 573
574# When you say "perl -MO=Concise -e '$a'", the output should look like:
575
576# 4 <@> leave[t1] vKP/REFC ->(end)
577# 1 <0> enter ->2
578 #^ smallest OP sequence number should be 1
579# 2 <;> nextstate(main 1 -e:1) v ->3
580 # ^ smallest COP sequence number should be 1
581# - <1> ex-rv2sv vK/1 ->4
582# 3 <$> gvsv(*a) s ->4
583
c27ea44e 584# If the second of the marked numbers there isn't 1, it means you need
585# to update the corresponding magic number in the next line.
586# Remember, this needs to stay the last things in the module.
e69a2255 587
c27ea44e 588# Why is this different for MacOS? Does it matter?
589my $cop_seq_mnum = $^O eq 'MacOS' ? 10 : 9;
e69a2255 590$cop_seq_base = svref_2object(eval 'sub{0;}')->START->cop_seq + $cop_seq_mnum;
c99ca59a 591
5921;
593
594__END__
595
596=head1 NAME
597
598B::Concise - Walk Perl syntax tree, printing concise info about ops
599
600=head1 SYNOPSIS
601
602 perl -MO=Concise[,OPTIONS] foo.pl
603
78ad9108 604 use B::Concise qw(set_style add_callback);
605
c99ca59a 606=head1 DESCRIPTION
607
608This compiler backend prints the internal OPs of a Perl program's syntax
609tree in one of several space-efficient text formats suitable for debugging
610the inner workings of perl or other compiler backends. It can print OPs in
611the order they appear in the OP tree, in the order they will execute, or
612in a text approximation to their tree structure, and the format of the
613information displyed is customizable. Its function is similar to that of
614perl's B<-Dx> debugging flag or the B<B::Terse> module, but it is more
615sophisticated and flexible.
616
f8a679e6 617=head1 EXAMPLE
618
619Here's is a short example of output, using the default formatting
620conventions :
621
622 % perl -MO=Concise -e '$a = $b + 42'
623 8 <@> leave[t1] vKP/REFC ->(end)
624 1 <0> enter ->2
625 2 <;> nextstate(main 1 -e:1) v ->3
626 7 <2> sassign vKS/2 ->8
627 5 <2> add[t1] sK/2 ->6
628 - <1> ex-rv2sv sK/1 ->4
629 3 <$> gvsv(*b) s ->4
630 4 <$> const(IV 42) s ->5
631 - <1> ex-rv2sv sKRM*/1 ->7
632 6 <$> gvsv(*a) s ->7
633
634Each line corresponds to an operator. Null ops appear as C<ex-opname>,
635where I<opname> is the op that has been optimized away by perl.
636
637The number on the first row indicates the op's sequence number. It's
638given in base 36 by default.
639
640The symbol between angle brackets indicates the op's type : for example,
641<2> is a BINOP, <@> a LISTOP, etc. (see L</"OP class abbreviations">).
642
643The opname may be followed by op-specific information in parentheses
644(e.g. C<gvsv(*b)>), and by targ information in brackets (e.g.
645C<leave[t1]>).
646
647Next come the op flags. The common flags are listed below
648(L</"OP flags abbreviations">). The private flags follow, separated
649by a slash. For example, C<vKP/REFC> means that the leave op has
650public flags OPf_WANT_VOID, OPf_KIDS, and OPf_PARENS, and the private
651flag OPpREFCOUNTED.
652
653Finally an arrow points to the sequence number of the next op.
654
c99ca59a 655=head1 OPTIONS
656
657Arguments that don't start with a hyphen are taken to be the names of
658subroutines to print the OPs of; if no such functions are specified, the
659main body of the program (outside any subroutines, and not including use'd
660or require'd files) is printed.
661
662=over 4
663
664=item B<-basic>
665
666Print OPs in the order they appear in the OP tree (a preorder
667traversal, starting at the root). The indentation of each OP shows its
668level in the tree. This mode is the default, so the flag is included
669simply for completeness.
670
671=item B<-exec>
672
673Print OPs in the order they would normally execute (for the majority
674of constructs this is a postorder traversal of the tree, ending at the
675root). In most cases the OP that usually follows a given OP will
676appear directly below it; alternate paths are shown by indentation. In
677cases like loops when control jumps out of a linear path, a 'goto'
678line is generated.
679
680=item B<-tree>
681
682Print OPs in a text approximation of a tree, with the root of the tree
683at the left and 'left-to-right' order of children transformed into
684'top-to-bottom'. Because this mode grows both to the right and down,
685it isn't suitable for large programs (unless you have a very wide
686terminal).
687
688=item B<-compact>
689
690Use a tree format in which the minimum amount of space is used for the
691lines connecting nodes (one character in most cases). This squeezes out
692a few precious columns of screen real estate.
693
694=item B<-loose>
695
696Use a tree format that uses longer edges to separate OP nodes. This format
697tends to look better than the compact one, especially in ASCII, and is
698the default.
699
700=item B<-vt>
701
702Use tree connecting characters drawn from the VT100 line-drawing set.
703This looks better if your terminal supports it.
704
705=item B<-ascii>
706
707Draw the tree with standard ASCII characters like C<+> and C<|>. These don't
708look as clean as the VT100 characters, but they'll work with almost any
709terminal (or the horizontal scrolling mode of less(1)) and are suitable
710for text documentation or email. This is the default.
711
712=item B<-main>
713
714Include the main program in the output, even if subroutines were also
715specified.
716
717=item B<-base>I<n>
718
719Print OP sequence numbers in base I<n>. If I<n> is greater than 10, the
720digit for 11 will be 'a', and so on. If I<n> is greater than 36, the digit
721for 37 will be 'A', and so on until 62. Values greater than 62 are not
722currently supported. The default is 36.
723
724=item B<-bigendian>
725
726Print sequence numbers with the most significant digit first. This is the
727usual convention for Arabic numerals, and the default.
728
729=item B<-littleendian>
730
731Print seqence numbers with the least significant digit first.
732
733=item B<-concise>
734
735Use the author's favorite set of formatting conventions. This is the
736default, of course.
737
738=item B<-terse>
739
740Use formatting conventions that emulate the ouput of B<B::Terse>. The
741basic mode is almost indistinguishable from the real B<B::Terse>, and the
742exec mode looks very similar, but is in a more logical order and lacks
743curly brackets. B<B::Terse> doesn't have a tree mode, so the tree mode
744is only vaguely reminiscient of B<B::Terse>.
745
746=item B<-linenoise>
747
748Use formatting conventions in which the name of each OP, rather than being
749written out in full, is represented by a one- or two-character abbreviation.
750This is mainly a joke.
751
752=item B<-debug>
753
754Use formatting conventions reminiscient of B<B::Debug>; these aren't
755very concise at all.
756
757=item B<-env>
758
759Use formatting conventions read from the environment variables
760C<B_CONCISE_FORMAT>, C<B_CONCISE_GOTO_FORMAT>, and C<B_CONCISE_TREE_FORMAT>.
761
762=back
763
764=head1 FORMATTING SPECIFICATIONS
765
766For each general style ('concise', 'terse', 'linenoise', etc.) there are
767three specifications: one of how OPs should appear in the basic or exec
768modes, one of how 'goto' lines should appear (these occur in the exec
769mode only), and one of how nodes should appear in tree mode. Each has the
770same format, described below. Any text that doesn't match a special
771pattern is copied verbatim.
772
773=over 4
774
775=item B<(x(>I<exec_text>B<;>I<basic_text>B<)x)>
776
777Generates I<exec_text> in exec mode, or I<basic_text> in basic mode.
778
779=item B<(*(>I<text>B<)*)>
780
781Generates one copy of I<text> for each indentation level.
782
783=item B<(*(>I<text1>B<;>I<text2>B<)*)>
784
785Generates one fewer copies of I<text1> than the indentation level, followed
786by one copy of I<text2> if the indentation level is more than 0.
787
788=item B<(?(>I<text1>B<#>I<var>I<Text2>B<)?)>
789
790If the value of I<var> is true (not empty or zero), generates the
791value of I<var> surrounded by I<text1> and I<Text2>, otherwise
792nothing.
793
794=item B<#>I<var>
795
796Generates the value of the variable I<var>.
797
798=item B<#>I<var>I<N>
799
800Generates the value of I<var>, left jutified to fill I<N> spaces.
801
802=item B<~>
803
804Any number of tildes and surrounding whitespace will be collapsed to
805a single space.
806
807=back
808
809The following variables are recognized:
810
811=over 4
812
813=item B<#addr>
814
815The address of the OP, in hexidecimal.
816
817=item B<#arg>
818
819The OP-specific information of the OP (such as the SV for an SVOP, the
820non-local exit pointers for a LOOP, etc.) enclosed in paretheses.
821
822=item B<#class>
823
824The B-determined class of the OP, in all caps.
825
f8a679e6 826=item B<#classsym>
c99ca59a 827
828A single symbol abbreviating the class of the OP.
829
c3caa09d 830=item B<#coplabel>
831
832The label of the statement or block the OP is the start of, if any.
833
c99ca59a 834=item B<#exname>
835
836The name of the OP, or 'ex-foo' if the OP is a null that used to be a foo.
837
838=item B<#extarg>
839
840The target of the OP, or nothing for a nulled OP.
841
842=item B<#firstaddr>
843
844The address of the OP's first child, in hexidecimal.
845
846=item B<#flags>
847
848The OP's flags, abbreviated as a series of symbols.
849
850=item B<#flagval>
851
852The numeric value of the OP's flags.
853
f8a679e6 854=item B<#hyphseq>
c99ca59a 855
856The sequence number of the OP, or a hyphen if it doesn't have one.
857
858=item B<#label>
859
860'NEXT', 'LAST', or 'REDO' if the OP is a target of one of those in exec
861mode, or empty otherwise.
862
863=item B<#lastaddr>
864
865The address of the OP's last child, in hexidecimal.
866
867=item B<#name>
868
869The OP's name.
870
871=item B<#NAME>
872
873The OP's name, in all caps.
874
875=item B<#next>
876
877The sequence number of the OP's next OP.
878
879=item B<#nextaddr>
880
881The address of the OP's next OP, in hexidecimal.
882
883=item B<#noise>
884
c27ea44e 885A one- or two-character abbreviation for the OP's name.
c99ca59a 886
887=item B<#private>
888
889The OP's private flags, rendered with abbreviated names if possible.
890
891=item B<#privval>
892
893The numeric value of the OP's private flags.
894
895=item B<#seq>
896
c27ea44e 897The sequence number of the OP. Note that this is now a sequence number
898generated by B::Concise, rather than the real op_seq value (for which
899see B<#seqnum>).
c99ca59a 900
901=item B<#seqnum>
902
903The real sequence number of the OP, as a regular number and not adjusted
904to be relative to the start of the real program. (This will generally be
905a fairly large number because all of B<B::Concise> is compiled before
906your program is).
907
908=item B<#sibaddr>
909
910The address of the OP's next youngest sibling, in hexidecimal.
911
912=item B<#svaddr>
913
914The address of the OP's SV, if it has an SV, in hexidecimal.
915
916=item B<#svclass>
917
918The class of the OP's SV, if it has one, in all caps (e.g., 'IV').
919
920=item B<#svval>
921
922The value of the OP's SV, if it has one, in a short human-readable format.
923
924=item B<#targ>
925
926The numeric value of the OP's targ.
927
928=item B<#targarg>
929
930The name of the variable the OP's targ refers to, if any, otherwise the
931letter t followed by the OP's targ in decimal.
932
933=item B<#targarglife>
934
935Same as B<#targarg>, but followed by the COP sequence numbers that delimit
936the variable's lifetime (or 'end' for a variable in an open scope) for a
937variable.
938
939=item B<#typenum>
940
941The numeric value of the OP's type, in decimal.
942
943=back
944
945=head1 ABBREVIATIONS
946
947=head2 OP flags abbreviations
948
949 v OPf_WANT_VOID Want nothing (void context)
950 s OPf_WANT_SCALAR Want single value (scalar context)
951 l OPf_WANT_LIST Want list of any length (list context)
952 K OPf_KIDS There is a firstborn child.
953 P OPf_PARENS This operator was parenthesized.
954 (Or block needs explicit scope entry.)
955 R OPf_REF Certified reference.
956 (Return container, not containee).
957 M OPf_MOD Will modify (lvalue).
958 S OPf_STACKED Some arg is arriving on the stack.
959 * OPf_SPECIAL Do something weird for this op (see op.h)
960
961=head2 OP class abbreviations
962
963 0 OP (aka BASEOP) An OP with no children
964 1 UNOP An OP with one child
965 2 BINOP An OP with two children
966 | LOGOP A control branch OP
967 @ LISTOP An OP that could have lots of children
968 / PMOP An OP with a regular expression
969 $ SVOP An OP with an SV
970 " PVOP An OP with a string
971 { LOOP An OP that holds pointers for a loop
972 ; COP An OP that marks the start of a statement
051f02e9 973 # PADOP An OP with a GV on the pad
c99ca59a 974
78ad9108 975=head1 Using B::Concise outside of the O framework
976
977It is possible to extend B<B::Concise> by using it outside of the B<O>
978framework and providing new styles and new variables.
979
980 use B::Concise qw(set_style add_callback);
981 set_style($format, $gotofmt, $treefmt);
982 add_callback
983 (
984 sub
985 {
986 my ($h, $op, $level, $format) = @_;
987 $h->{variable} = some_func($op);
988 }
989 );
990 B::Concise::compile(@options)->();
991
992You can specify a style by calling the B<set_style> subroutine. If you
993have a new variable in your style, or you want to change the value of an
994existing variable, you will need to add a callback to specify the value
995for that variable.
996
997This is done by calling B<add_callback> passing references to any
998callback subroutines. The subroutines are called in the same order as
999they are added. Each subroutine is passed four parameters. These are a
1000reference to a hash, the keys of which are the names of the variables
1001and the values of which are their values, the op, the level and the
1002format.
1003
1004To define your own variables, simply add them to the hash, or change
1005existing values if you need to. The level and format are passed in as
1006references to scalars, but it is unlikely that they will need to be
1007changed or even used.
1008
1009To see the output, call the subroutine returned by B<compile> in the
1010same way that B<O> does.
1011
c99ca59a 1012=head1 AUTHOR
1013
1014Stephen McCamant, C<smcc@CSUA.Berkeley.EDU>
1015
1016=cut