Commit | Line | Data |
---|---|---|
a798dbf2 | 1 | package B::Terse; |
ad4997d3 JH |
2 | use strict; |
3 | use B qw(peekop class walkoptree walkoptree_exec walkoptree_slow | |
d9963e60 | 4 | main_start main_root cstring svref_2object SVf_IVisUV); |
ad4997d3 JH |
5 | use B::Asmdata qw(@specialsv_name); |
6 | ||
7 | sub terse { | |
8 | my ($order, $cvref) = @_; | |
9 | my $cv = svref_2object($cvref); | |
10 | if ($order eq "exec") { | |
11 | walkoptree_exec($cv->START, "terse"); | |
12 | } else { | |
13 | walkoptree_slow($cv->ROOT, "terse"); | |
14 | } | |
15 | } | |
a798dbf2 MB |
16 | |
17 | sub compile { | |
244826eb | 18 | my $order = @_ ? shift : ""; |
ad4997d3 JH |
19 | my @options = @_; |
20 | B::clearsym(); | |
21 | if (@options) { | |
22 | return sub { | |
23 | my $objname; | |
24 | foreach $objname (@options) { | |
25 | $objname = "main::$objname" unless $objname =~ /::/; | |
26 | eval "terse(\$order, \\&$objname)"; | |
27 | die "terse($order, \\&$objname) failed: $@" if $@; | |
28 | } | |
29 | } | |
30 | } else { | |
31 | if ($order eq "exec") { | |
32 | return sub { walkoptree_exec(main_start, "terse") } | |
33 | } else { | |
34 | return sub { walkoptree_slow(main_root, "terse") } | |
35 | } | |
36 | } | |
37 | } | |
38 | ||
39 | sub indent { | |
244826eb | 40 | my $level = @_ ? shift : 0; |
ad4997d3 JH |
41 | return " " x $level; |
42 | } | |
43 | ||
44 | sub B::OP::terse { | |
45 | my ($op, $level) = @_; | |
46 | my $targ = $op->targ; | |
47 | $targ = ($targ > 0) ? " [$targ]" : ""; | |
48 | print indent($level), peekop($op), $targ, "\n"; | |
49 | } | |
50 | ||
51 | sub B::SVOP::terse { | |
52 | my ($op, $level) = @_; | |
53 | print indent($level), peekop($op), " "; | |
54 | $op->sv->terse(0); | |
55 | } | |
56 | ||
57 | sub B::PADOP::terse { | |
58 | my ($op, $level) = @_; | |
59 | print indent($level), peekop($op), " ", $op->padix, "\n"; | |
60 | } | |
61 | ||
62 | sub B::PMOP::terse { | |
63 | my ($op, $level) = @_; | |
64 | my $precomp = $op->precomp; | |
65 | print indent($level), peekop($op), | |
66 | defined($precomp) ? " /$precomp/\n" : " (regexp not compiled)\n"; | |
67 | ||
68 | } | |
69 | ||
70 | sub B::PVOP::terse { | |
71 | my ($op, $level) = @_; | |
72 | print indent($level), peekop($op), " ", cstring($op->pv), "\n"; | |
73 | } | |
74 | ||
75 | sub B::COP::terse { | |
76 | my ($op, $level) = @_; | |
77 | my $label = $op->label; | |
78 | if ($label) { | |
79 | $label = " label ".cstring($label); | |
80 | } | |
81 | print indent($level), peekop($op), $label || "", "\n"; | |
82 | } | |
83 | ||
84 | sub B::PV::terse { | |
85 | my ($sv, $level) = @_; | |
86 | print indent($level); | |
87 | printf "%s (0x%lx) %s\n", class($sv), $$sv, cstring($sv->PV); | |
88 | } | |
89 | ||
90 | sub B::AV::terse { | |
91 | my ($sv, $level) = @_; | |
92 | print indent($level); | |
93 | printf "%s (0x%lx) FILL %d\n", class($sv), $$sv, $sv->FILL; | |
94 | } | |
95 | ||
96 | sub B::GV::terse { | |
97 | my ($gv, $level) = @_; | |
98 | my $stash = $gv->STASH->NAME; | |
99 | if ($stash eq "main") { | |
100 | $stash = ""; | |
101 | } else { | |
102 | $stash = $stash . "::"; | |
103 | } | |
104 | print indent($level); | |
002b978b | 105 | printf "%s (0x%lx) *%s%s\n", class($gv), $$gv, $stash, $gv->SAFENAME; |
ad4997d3 JH |
106 | } |
107 | ||
108 | sub B::IV::terse { | |
109 | my ($sv, $level) = @_; | |
110 | print indent($level); | |
d9963e60 RH |
111 | my $v = $sv->FLAGS & SVf_IVisUV ? "%u" : "%d"; |
112 | printf "%s (0x%lx) $v\n", class($sv), $$sv, $sv->int_value; | |
ad4997d3 JH |
113 | } |
114 | ||
115 | sub B::NV::terse { | |
116 | my ($sv, $level) = @_; | |
117 | print indent($level); | |
118 | printf "%s (0x%lx) %s\n", class($sv), $$sv, $sv->NV; | |
119 | } | |
120 | ||
d333a217 RGS |
121 | sub B::RV::terse { |
122 | my ($rv, $level) = @_; | |
123 | print indent($level); | |
124 | printf "%s (0x%lx) %s\n", class($rv), $$rv, printref($rv); | |
125 | } | |
126 | ||
127 | sub printref { | |
128 | my $rv = shift; | |
129 | my $rcl = class($rv->RV); | |
130 | if ($rcl eq 'PV') { | |
131 | return "\\" . cstring($rv->RV->$rcl); | |
132 | } elsif ($rcl eq 'NV') { | |
133 | return "\\" . $rv->RV->$rcl; | |
134 | } elsif ($rcl eq 'IV') { | |
135 | return sprintf "\\%" . ($rv->RV->FLAGS & SVf_IVisUV ? "u" : "d"), | |
136 | $rv->RV->int_value; | |
137 | } elsif ($rcl eq 'RV') { | |
138 | return "\\" . printref($rv->RV); | |
139 | } | |
140 | } | |
141 | ||
ad4997d3 JH |
142 | sub B::NULL::terse { |
143 | my ($sv, $level) = @_; | |
144 | print indent($level); | |
145 | printf "%s (0x%lx)\n", class($sv), $$sv; | |
146 | } | |
147 | ||
148 | sub B::SPECIAL::terse { | |
149 | my ($sv, $level) = @_; | |
150 | print indent($level); | |
151 | printf "%s #%d %s\n", class($sv), $$sv, $specialsv_name[$$sv]; | |
a798dbf2 MB |
152 | } |
153 | ||
154 | 1; | |
7f20e9dd GS |
155 | |
156 | __END__ | |
157 | ||
158 | =head1 NAME | |
159 | ||
160 | B::Terse - Walk Perl syntax tree, printing terse info about ops | |
161 | ||
162 | =head1 SYNOPSIS | |
163 | ||
ad4997d3 | 164 | perl -MO=Terse[,OPTIONS] foo.pl |
7f20e9dd GS |
165 | |
166 | =head1 DESCRIPTION | |
167 | ||
ad4997d3 | 168 | See F<ext/B/README>. |
7f20e9dd GS |
169 | |
170 | =head1 AUTHOR | |
171 | ||
ad4997d3 | 172 | Malcolm Beattie, C<mbeattie@sable.ox.ac.uk> |
7f20e9dd GS |
173 | |
174 | =cut |