Commit | Line | Data |
724aa791 |
1 | #!perl |
2 | |
3 | BEGIN { |
4 | chdir 't'; |
5 | @INC = ('../lib', '../ext/B/t'); |
6 | require './test.pl'; |
7 | } |
8 | |
9 | # import checkOptree(), and %gOpts (containing test state) |
10 | use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!! |
2ce64696 |
11 | use Config; |
724aa791 |
12 | |
cc02ea56 |
13 | plan tests => 23; |
2ce64696 |
14 | SKIP: { |
15 | skip "no perlio in this build", 24 unless $Config::Config{useperlio}; |
724aa791 |
16 | |
17 | $SIG{__WARN__} = sub { |
18 | my $err = shift; |
19 | $err =~ m/Subroutine re::(un)?install redefined/ and return; |
20 | }; |
21 | ################################# |
22 | pass("CANONICAL B::Concise EXAMPLE"); |
23 | |
24 | checkOptree ( name => 'canonical example w -basic', |
25 | bcopts => '-basic', |
26 | code => sub{$a=$b+42}, |
27 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
28 | # 7 <1> leavesub[\d+ refs?] K/REFC,1 ->(end) |
29 | # - <@> lineseq KP ->7 |
30 | # 1 <;> nextstate(foo bar) v ->2 |
31 | # 6 <2> sassign sKS/2 ->7 |
32 | # 4 <2> add[t\d+] sK/2 ->5 |
33 | # - <1> ex-rv2sv sK/1 ->3 |
34 | # 2 <#> gvsv[*b] s ->3 |
35 | # 3 <$> const[IV 42] s ->4 |
36 | # - <1> ex-rv2sv sKRM*/1 ->6 |
37 | # 5 <#> gvsv[*a] s ->6 |
38 | EOT_EOT |
39 | # 7 <1> leavesub[1 ref] K/REFC,1 ->(end) |
40 | # - <@> lineseq KP ->7 |
41 | # 1 <;> nextstate(main 60 optree_concise.t:122) v ->2 |
42 | # 6 <2> sassign sKS/2 ->7 |
43 | # 4 <2> add[t1] sK/2 ->5 |
44 | # - <1> ex-rv2sv sK/1 ->3 |
45 | # 2 <$> gvsv(*b) s ->3 |
46 | # 3 <$> const(IV 42) s ->4 |
47 | # - <1> ex-rv2sv sKRM*/1 ->6 |
48 | # 5 <$> gvsv(*a) s ->6 |
49 | EONT_EONT |
50 | |
51 | checkOptree ( name => 'canonical example w -exec', |
52 | bcopts => '-exec', |
53 | code => sub{$a=$b+42}, |
54 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
724aa791 |
55 | # 1 <;> nextstate(main 61 optree_concise.t:139) v |
56 | # 2 <#> gvsv[*b] s |
57 | # 3 <$> const[IV 42] s |
58 | # 4 <2> add[t3] sK/2 |
59 | # 5 <#> gvsv[*a] s |
60 | # 6 <2> sassign sKS/2 |
61 | # 7 <1> leavesub[1 ref] K/REFC,1 |
62 | EOT_EOT |
724aa791 |
63 | # 1 <;> nextstate(main 61 optree_concise.t:139) v |
64 | # 2 <$> gvsv(*b) s |
65 | # 3 <$> const(IV 42) s |
66 | # 4 <2> add[t1] sK/2 |
67 | # 5 <$> gvsv(*a) s |
68 | # 6 <2> sassign sKS/2 |
69 | # 7 <1> leavesub[1 ref] K/REFC,1 |
70 | EONT_EONT |
71 | |
724aa791 |
72 | ################################# |
73 | pass("B::Concise OPTION TESTS"); |
74 | |
75 | checkOptree ( name => '-base3 sticky-exec', |
76 | bcopts => '-base3', |
77 | code => sub{$a=$b+42}, |
78 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
724aa791 |
79 | 1 <;> dbstate(main 24 optree_concise.t:132) v |
80 | 2 <#> gvsv[*b] s |
81 | 10 <$> const[IV 42] s |
82 | 11 <2> add[t3] sK/2 |
83 | 12 <#> gvsv[*a] s |
84 | 20 <2> sassign sKS/2 |
cc02ea56 |
85 | 21 <1> leavesub[1 ref] K/REFC,1 |
724aa791 |
86 | EOT_EOT |
724aa791 |
87 | # 1 <;> nextstate(main 62 optree_concise.t:161) v |
88 | # 2 <$> gvsv(*b) s |
89 | # 10 <$> const(IV 42) s |
90 | # 11 <2> add[t1] sK/2 |
91 | # 12 <$> gvsv(*a) s |
92 | # 20 <2> sassign sKS/2 |
93 | # 21 <1> leavesub[1 ref] K/REFC,1 |
94 | EONT_EONT |
95 | |
96 | checkOptree ( name => 'sticky-base3, -basic over sticky-exec', |
97 | bcopts => '-basic', |
98 | code => sub{$a=$b+42}, |
99 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
100 | 21 <1> leavesub[1 ref] K/REFC,1 ->(end) |
101 | - <@> lineseq KP ->21 |
102 | 1 <;> nextstate(main 32 optree_concise.t:164) v ->2 |
103 | 20 <2> sassign sKS/2 ->21 |
104 | 11 <2> add[t3] sK/2 ->12 |
105 | - <1> ex-rv2sv sK/1 ->10 |
106 | 2 <#> gvsv[*b] s ->10 |
107 | 10 <$> const[IV 42] s ->11 |
108 | - <1> ex-rv2sv sKRM*/1 ->20 |
109 | 12 <#> gvsv[*a] s ->20 |
110 | EOT_EOT |
111 | # 21 <1> leavesub[1 ref] K/REFC,1 ->(end) |
112 | # - <@> lineseq KP ->21 |
113 | # 1 <;> nextstate(main 63 optree_concise.t:186) v ->2 |
114 | # 20 <2> sassign sKS/2 ->21 |
115 | # 11 <2> add[t1] sK/2 ->12 |
116 | # - <1> ex-rv2sv sK/1 ->10 |
117 | # 2 <$> gvsv(*b) s ->10 |
118 | # 10 <$> const(IV 42) s ->11 |
119 | # - <1> ex-rv2sv sKRM*/1 ->20 |
120 | # 12 <$> gvsv(*a) s ->20 |
121 | EONT_EONT |
122 | |
123 | checkOptree ( name => '-base4', |
124 | bcopts => [qw/ -basic -base4 /], |
125 | code => sub{$a=$b+42}, |
126 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
127 | 13 <1> leavesub[1 ref] K/REFC,1 ->(end) |
128 | - <@> lineseq KP ->13 |
129 | 1 <;> nextstate(main 26 optree_concise.t:145) v ->2 |
130 | 12 <2> sassign sKS/2 ->13 |
131 | 10 <2> add[t3] sK/2 ->11 |
132 | - <1> ex-rv2sv sK/1 ->3 |
133 | 2 <#> gvsv[*b] s ->3 |
134 | 3 <$> const[IV 42] s ->10 |
135 | - <1> ex-rv2sv sKRM*/1 ->12 |
136 | 11 <#> gvsv[*a] s ->12 |
137 | EOT_EOT |
138 | # 13 <1> leavesub[1 ref] K/REFC,1 ->(end) |
139 | # - <@> lineseq KP ->13 |
140 | # 1 <;> nextstate(main 64 optree_concise.t:193) v ->2 |
141 | # 12 <2> sassign sKS/2 ->13 |
142 | # 10 <2> add[t1] sK/2 ->11 |
143 | # - <1> ex-rv2sv sK/1 ->3 |
144 | # 2 <$> gvsv(*b) s ->3 |
145 | # 3 <$> const(IV 42) s ->10 |
146 | # - <1> ex-rv2sv sKRM*/1 ->12 |
147 | # 11 <$> gvsv(*a) s ->12 |
148 | EONT_EONT |
149 | |
150 | checkOptree ( name => "restore -base36 default", |
151 | bcopts => [qw/ -basic -base36 /], |
152 | code => sub{$a}, |
153 | crossfail => 1, |
154 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
155 | 3 <1> leavesub[1 ref] K/REFC,1 ->(end) |
156 | - <@> lineseq KP ->3 |
157 | 1 <;> nextstate(main 27 optree_concise.t:161) v ->2 |
158 | - <1> ex-rv2sv sK/1 ->- |
159 | 2 <#> gvsv[*a] s ->3 |
160 | EOT_EOT |
161 | # 3 <1> leavesub[1 ref] K/REFC,1 ->(end) |
162 | # - <@> lineseq KP ->3 |
163 | # 1 <;> nextstate(main 65 optree_concise.t:210) v ->2 |
164 | # - <1> ex-rv2sv sK/1 ->- |
165 | # 2 <$> gvsv(*a) s ->3 |
166 | EONT_EONT |
167 | |
168 | checkOptree ( name => "terse basic", |
169 | bcopts => [qw/ -basic -terse /], |
170 | code => sub{$a}, |
171 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
172 | UNOP (0x82b0918) leavesub [1] |
173 | LISTOP (0x82b08d8) lineseq |
174 | COP (0x82b0880) nextstate |
175 | UNOP (0x82b0860) null [15] |
176 | PADOP (0x82b0840) gvsv GV (0x82a818c) *a |
177 | EOT_EOT |
178 | # UNOP (0x8282310) leavesub [1] |
179 | # LISTOP (0x82822f0) lineseq |
180 | # COP (0x82822b8) nextstate |
181 | # UNOP (0x812fc20) null [15] |
182 | # SVOP (0x812fc00) gvsv GV (0x814692c) *a |
183 | EONT_EONT |
184 | |
185 | checkOptree ( name => "sticky-terse exec", |
186 | bcopts => [qw/ -exec /], |
187 | code => sub{$a}, |
188 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
724aa791 |
189 | COP (0x82b0d70) nextstate |
190 | PADOP (0x82b0d30) gvsv GV (0x82a818c) *a |
191 | UNOP (0x82b0e08) leavesub [1] |
192 | EOT_EOT |
724aa791 |
193 | # COP (0x82828e0) nextstate |
194 | # SVOP (0x82828a0) gvsv GV (0x814692c) *a |
195 | # UNOP (0x8282938) leavesub [1] |
196 | EONT_EONT |
197 | |
198 | pass("OPTIONS IN CMDLINE MODE"); |
199 | |
200 | checkOptree ( name => 'cmdline invoke -basic works', |
201 | prog => 'sort @a', |
202 | #bcopts => '-basic', # default |
203 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
204 | # 7 <@> leave[1 ref] vKP/REFC ->(end) |
205 | # 1 <0> enter ->2 |
206 | # 2 <;> nextstate(main 1 -e:1) v ->3 |
207 | # 6 <@> sort vK ->7 |
208 | # 3 <0> pushmark s ->4 |
209 | # 5 <1> rv2av[t2] lK/1 ->6 |
210 | # 4 <#> gv[*a] s ->5 |
211 | EOT_EOT |
212 | # 7 <@> leave[1 ref] vKP/REFC ->(end) |
213 | # 1 <0> enter ->2 |
214 | # 2 <;> nextstate(main 1 -e:1) v ->3 |
215 | # 6 <@> sort vK ->7 |
216 | # 3 <0> pushmark s ->4 |
217 | # 5 <1> rv2av[t1] lK/1 ->6 |
218 | # 4 <$> gv(*a) s ->5 |
219 | EONT_EONT |
220 | |
221 | checkOptree ( name => 'cmdline invoke -exec works', |
222 | prog => 'sort @a', |
223 | bcopts => '-exec', |
224 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
225 | 1 <0> enter |
226 | 2 <;> nextstate(main 1 -e:1) v |
227 | 3 <0> pushmark s |
228 | 4 <#> gv[*a] s |
229 | 5 <1> rv2av[t2] lK/1 |
230 | 6 <@> sort vK |
231 | 7 <@> leave[1 ref] vKP/REFC |
232 | EOT_EOT |
233 | # 1 <0> enter |
234 | # 2 <;> nextstate(main 1 -e:1) v |
235 | # 3 <0> pushmark s |
236 | # 4 <$> gv(*a) s |
237 | # 5 <1> rv2av[t1] lK/1 |
238 | # 6 <@> sort vK |
239 | # 7 <@> leave[1 ref] vKP/REFC |
240 | EONT_EONT |
241 | |
242 | checkOptree ( name => 'cmdline self-strict compile err', |
243 | prog => 'use strict; sort @a', |
244 | bcopts => [qw/ -basic -concise -exec /], |
cc02ea56 |
245 | noanchors => 1, |
724aa791 |
246 | expect => 'compilation errors', |
247 | expect_nt => 'compilation errors'); |
248 | |
249 | checkOptree ( name => 'error at -e line 1', |
250 | prog => 'our @a; sort @a', |
251 | bcopts => [qw/ -basic -concise -exec /], |
cc02ea56 |
252 | noanchors => 1, |
724aa791 |
253 | expect => 'at -e line 1', |
254 | expect_nt => 'at -e line 1'); |
255 | |
256 | checkOptree ( name => 'cmdline -basic -concise -exec works', |
257 | prog => 'our @a; sort @a', |
258 | bcopts => [qw/ -basic -concise -exec /], |
259 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
260 | # 1 <0> enter |
261 | # 2 <;> nextstate(main 1 -e:1) v |
262 | # 3 <#> gv[*a] s |
263 | # 4 <1> rv2av[t3] vK/OURINTR,1 |
264 | # 5 <;> nextstate(main 2 -e:1) v |
265 | # 6 <0> pushmark s |
266 | # 7 <#> gv[*a] s |
267 | # 8 <1> rv2av[t5] lK/1 |
268 | # 9 <@> sort vK |
269 | # a <@> leave[1 ref] vKP/REFC |
270 | EOT_EOT |
271 | # 1 <0> enter |
272 | # 2 <;> nextstate(main 1 -e:1) v |
273 | # 3 <$> gv(*a) s |
274 | # 4 <1> rv2av[t2] vK/OURINTR,1 |
275 | # 5 <;> nextstate(main 2 -e:1) v |
276 | # 6 <0> pushmark s |
277 | # 7 <$> gv(*a) s |
278 | # 8 <1> rv2av[t3] lK/1 |
279 | # 9 <@> sort vK |
280 | # a <@> leave[1 ref] vKP/REFC |
281 | EONT_EONT |
282 | |
283 | |
284 | ################################# |
285 | pass("B::Concise STYLE/CALLBACK TESTS"); |
286 | |
287 | use B::Concise qw( walk_output add_style set_style_standard add_callback ); |
288 | |
289 | # new relative style, added by set_up_relative_test() |
290 | @stylespec = |
291 | ( "#hyphseq2 (*( (x( ;)x))*)<#classsym> " |
292 | . "#exname#arg(?([#targarglife])?)~#flags(?(/#privateb)?)(x(;~->#next)x) " |
293 | . "(x(;~=> #extra)x)\n" # new 'variable' used here |
294 | |
295 | , " (*( )*) goto #seq\n" |
cc02ea56 |
296 | , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)" |
724aa791 |
297 | #. "(x(;~=> #extra)x)\n" # new 'variable' used here |
298 | ); |
299 | |
300 | sub set_up_relative_test { |
301 | # add a new style, and a callback which adds an 'extra' property |
302 | |
303 | add_style ( "relative" => @stylespec ); |
304 | #set_style_standard ( "relative" ); |
305 | |
306 | add_callback |
307 | ( sub { |
308 | my ($h, $op, $format, $level, $style) = @_; |
309 | |
310 | # callback marks up const ops |
311 | $h->{arg} .= ' CALLBACK' if $h->{name} eq 'const'; |
312 | $h->{extra} = ''; |
313 | |
cc02ea56 |
314 | if ($lastnext and $$lastnext != $$op) { |
315 | $h->{goto} = ($h->{seq} eq '-') |
316 | ? 'unresolved' : $h->{seq}; |
317 | } |
318 | |
724aa791 |
319 | # 2 style specific behaviors |
320 | if ($style eq 'relative') { |
321 | $h->{extra} = 'RELATIVE'; |
322 | $h->{arg} .= ' RELATIVE' if $h->{name} eq 'leavesub'; |
323 | } |
324 | elsif ($style eq 'scope') { |
325 | # supress printout entirely |
326 | $$format="" unless grep { $h->{name} eq $_ } @scopeops; |
327 | } |
328 | }); |
329 | } |
330 | |
331 | ################################# |
332 | set_up_relative_test(); |
333 | pass("set_up_relative_test, new callback installed"); |
334 | |
335 | checkOptree ( name => 'callback used, independent of style', |
336 | bcopts => [qw/ -concise -exec /], |
337 | code => sub{$a=$b+42}, |
338 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
724aa791 |
339 | 1 <;> nextstate(main 76 optree_concise.t:337) v |
340 | 2 <#> gvsv[*b] s |
341 | 3 <$> const[IV 42] CALLBACK s |
342 | 4 <2> add[t3] sK/2 |
343 | 5 <#> gvsv[*a] s |
344 | 6 <2> sassign sKS/2 |
345 | 7 <1> leavesub[1 ref] K/REFC,1 |
346 | EOT_EOT |
347 | # 1 <;> nextstate(main 455 optree_concise.t:328) v |
348 | # 2 <$> gvsv(*b) s |
349 | # 3 <$> const(IV 42) CALLBACK s |
350 | # 4 <2> add[t1] sK/2 |
351 | # 5 <$> gvsv(*a) s |
352 | # 6 <2> sassign sKS/2 |
353 | # 7 <1> leavesub[1 ref] K/REFC,1 |
354 | EONT_EONT |
355 | |
356 | checkOptree ( name => "new 'relative' style, -exec mode", |
357 | bcopts => [qw/ -basic -relative /], |
358 | code => sub{$a=$b+42}, |
359 | crossfail => 1, |
360 | #retry => 1, |
361 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
cc02ea56 |
362 | 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE |
363 | - <@> lineseq KP ->7 => RELATIVE |
364 | 1 <;> nextstate(main 49 optree_concise.t:309) v ->2 => RELATIVE |
365 | 6 <2> sassign sKS ->7 => RELATIVE |
366 | 4 <2> add[t3] sK ->5 => RELATIVE |
367 | - <1> ex-rv2sv sK ->3 => RELATIVE |
368 | 2 <#> gvsv[*b] s ->3 => RELATIVE |
369 | 3 <$> const[IV 42] CALLBACK s ->4 => RELATIVE |
370 | - <1> ex-rv2sv sKRM* ->6 => RELATIVE |
371 | 5 <#> gvsv[*a] s ->6 => RELATIVE |
724aa791 |
372 | EOT_EOT |
cc02ea56 |
373 | # 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE |
374 | # - <@> lineseq KP ->7 => RELATIVE |
375 | # 1 <;> nextstate(main 77 optree_concise.t:353) v ->2 => RELATIVE |
376 | # 6 <2> sassign sKS ->7 => RELATIVE |
377 | # 4 <2> add[t1] sK ->5 => RELATIVE |
378 | # - <1> ex-rv2sv sK ->3 => RELATIVE |
379 | # 2 <$> gvsv(*b) s ->3 => RELATIVE |
380 | # 3 <$> const(IV 42) CALLBACK s ->4 => RELATIVE |
381 | # - <1> ex-rv2sv sKRM* ->6 => RELATIVE |
382 | # 5 <$> gvsv(*a) s ->6 => RELATIVE |
724aa791 |
383 | EONT_EONT |
384 | |
385 | checkOptree ( name => "both -exec -relative", |
386 | bcopts => [qw/ -exec -relative /], |
387 | code => sub{$a=$b+42}, |
388 | crossfail => 1, |
389 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
724aa791 |
390 | 1 <;> nextstate(main 50 optree_concise.t:326) v |
391 | 2 <#> gvsv[*b] s |
392 | 3 <$> const[IV 42] CALLBACK s |
393 | 4 <2> add[t3] sK |
394 | 5 <#> gvsv[*a] s |
395 | 6 <2> sassign sKS |
396 | 7 <1> leavesub RELATIVE[1 ref] K |
397 | EOT_EOT |
398 | # 1 <;> nextstate(main 78 optree_concise.t:371) v |
399 | # 2 <$> gvsv(*b) s |
400 | # 3 <$> const(IV 42) CALLBACK s |
401 | # 4 <2> add[t1] sK |
402 | # 5 <$> gvsv(*a) s |
403 | # 6 <2> sassign sKS |
404 | # 7 <1> leavesub RELATIVE[1 ref] K |
405 | EONT_EONT |
406 | |
407 | ################################# |
408 | |
409 | @scopeops = qw( leavesub enter leave nextstate ); |
410 | add_style |
411 | ( 'scope' # concise copy |
412 | , "#hyphseq2 (*( (x( ;)x))*)<#classsym> " |
413 | . "#exname#arg(?([#targarglife])?)~#flags(?(/#private)?)(x(;~->#next)x) " |
414 | , " (*( )*) goto #seq\n" |
415 | , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)" |
416 | ); |
417 | |
418 | checkOptree ( name => "both -exec -scope", |
419 | bcopts => [qw/ -exec -scope /], |
420 | code => sub{$a=$b+42}, |
421 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
724aa791 |
422 | 1 <;> nextstate(main 50 optree_concise.t:337) v |
423 | 7 <1> leavesub[1 ref] K/REFC,1 |
424 | EOT_EOT |
724aa791 |
425 | 1 <;> nextstate(main 75 optree_concise.t:396) v |
426 | 7 <1> leavesub[1 ref] K/REFC,1 |
427 | EONT_EONT |
428 | |
429 | |
430 | checkOptree ( name => "both -basic -scope", |
431 | bcopts => [qw/ -basic -scope /], |
432 | code => sub{$a=$b+42}, |
433 | expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); |
434 | 7 <1> leavesub[1 ref] K/REFC,1 ->(end) |
435 | 1 <;> nextstate(main 51 optree_concise.t:347) v ->2 |
436 | EOT_EOT |
437 | 7 <1> leavesub[1 ref] K/REFC,1 ->(end) |
438 | 1 <;> nextstate(main 76 optree_concise.t:407) v ->2 |
439 | EONT_EONT |
440 | |
2ce64696 |
441 | } #skip |
724aa791 |
442 | |