Add new dUNDERBAR and UNDERBAR macros, to help XS writers to
[p5sagit/p5-mst-13.2.git] / ext / B / t / optree_concise.t
CommitLineData
724aa791 1#!perl
2
3BEGIN {
4 chdir 't';
5 @INC = ('../lib', '../ext/B/t');
6 require './test.pl';
7}
8
9# import checkOptree(), and %gOpts (containing test state)
10use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!!
2ce64696 11use Config;
724aa791 12
2ce64696 13plan tests => 24;
14SKIP: {
15skip "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#################################
22pass("CANONICAL B::Concise EXAMPLE");
23
24checkOptree ( 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
38EOT_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
49EONT_EONT
50
51checkOptree ( name => 'canonical example w -exec',
52 bcopts => '-exec',
53 code => sub{$a=$b+42},
54 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
55# goto -
56# 1 <;> nextstate(main 61 optree_concise.t:139) v
57# 2 <#> gvsv[*b] s
58# 3 <$> const[IV 42] s
59# 4 <2> add[t3] sK/2
60# 5 <#> gvsv[*a] s
61# 6 <2> sassign sKS/2
62# 7 <1> leavesub[1 ref] K/REFC,1
63EOT_EOT
64# goto -
65# 1 <;> nextstate(main 61 optree_concise.t:139) v
66# 2 <$> gvsv(*b) s
67# 3 <$> const(IV 42) s
68# 4 <2> add[t1] sK/2
69# 5 <$> gvsv(*a) s
70# 6 <2> sassign sKS/2
71# 7 <1> leavesub[1 ref] K/REFC,1
72EONT_EONT
73
74checkOptree ( name => 'tree reftext is messy cut-paste',
75 skip => 1);
76
77
78#################################
79pass("B::Concise OPTION TESTS");
80
81checkOptree ( name => '-base3 sticky-exec',
82 bcopts => '-base3',
83 code => sub{$a=$b+42},
84 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
85 goto -
861 <;> dbstate(main 24 optree_concise.t:132) v
872 <#> gvsv[*b] s
8810 <$> const[IV 42] s
8911 <2> add[t3] sK/2
9012 <#> gvsv[*a] s
9120 <2> sassign sKS/2
9221 <1> leavesub[2 refs] K/REFC,1
93EOT_EOT
94# goto -
95# 1 <;> nextstate(main 62 optree_concise.t:161) v
96# 2 <$> gvsv(*b) s
97# 10 <$> const(IV 42) s
98# 11 <2> add[t1] sK/2
99# 12 <$> gvsv(*a) s
100# 20 <2> sassign sKS/2
101# 21 <1> leavesub[1 ref] K/REFC,1
102EONT_EONT
103
104checkOptree ( name => 'sticky-base3, -basic over sticky-exec',
105 bcopts => '-basic',
106 code => sub{$a=$b+42},
107 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
10821 <1> leavesub[1 ref] K/REFC,1 ->(end)
109- <@> lineseq KP ->21
1101 <;> nextstate(main 32 optree_concise.t:164) v ->2
11120 <2> sassign sKS/2 ->21
11211 <2> add[t3] sK/2 ->12
113- <1> ex-rv2sv sK/1 ->10
1142 <#> gvsv[*b] s ->10
11510 <$> const[IV 42] s ->11
116- <1> ex-rv2sv sKRM*/1 ->20
11712 <#> gvsv[*a] s ->20
118EOT_EOT
119# 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
120# - <@> lineseq KP ->21
121# 1 <;> nextstate(main 63 optree_concise.t:186) v ->2
122# 20 <2> sassign sKS/2 ->21
123# 11 <2> add[t1] sK/2 ->12
124# - <1> ex-rv2sv sK/1 ->10
125# 2 <$> gvsv(*b) s ->10
126# 10 <$> const(IV 42) s ->11
127# - <1> ex-rv2sv sKRM*/1 ->20
128# 12 <$> gvsv(*a) s ->20
129EONT_EONT
130
131checkOptree ( name => '-base4',
132 bcopts => [qw/ -basic -base4 /],
133 code => sub{$a=$b+42},
134 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
13513 <1> leavesub[1 ref] K/REFC,1 ->(end)
136- <@> lineseq KP ->13
1371 <;> nextstate(main 26 optree_concise.t:145) v ->2
13812 <2> sassign sKS/2 ->13
13910 <2> add[t3] sK/2 ->11
140- <1> ex-rv2sv sK/1 ->3
1412 <#> gvsv[*b] s ->3
1423 <$> const[IV 42] s ->10
143- <1> ex-rv2sv sKRM*/1 ->12
14411 <#> gvsv[*a] s ->12
145EOT_EOT
146# 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
147# - <@> lineseq KP ->13
148# 1 <;> nextstate(main 64 optree_concise.t:193) v ->2
149# 12 <2> sassign sKS/2 ->13
150# 10 <2> add[t1] sK/2 ->11
151# - <1> ex-rv2sv sK/1 ->3
152# 2 <$> gvsv(*b) s ->3
153# 3 <$> const(IV 42) s ->10
154# - <1> ex-rv2sv sKRM*/1 ->12
155# 11 <$> gvsv(*a) s ->12
156EONT_EONT
157
158checkOptree ( name => "restore -base36 default",
159 bcopts => [qw/ -basic -base36 /],
160 code => sub{$a},
161 crossfail => 1,
162 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
1633 <1> leavesub[1 ref] K/REFC,1 ->(end)
164- <@> lineseq KP ->3
1651 <;> nextstate(main 27 optree_concise.t:161) v ->2
166- <1> ex-rv2sv sK/1 ->-
1672 <#> gvsv[*a] s ->3
168EOT_EOT
169# 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
170# - <@> lineseq KP ->3
171# 1 <;> nextstate(main 65 optree_concise.t:210) v ->2
172# - <1> ex-rv2sv sK/1 ->-
173# 2 <$> gvsv(*a) s ->3
174EONT_EONT
175
176checkOptree ( name => "terse basic",
177 bcopts => [qw/ -basic -terse /],
178 code => sub{$a},
179 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
180UNOP (0x82b0918) leavesub [1]
181 LISTOP (0x82b08d8) lineseq
182 COP (0x82b0880) nextstate
183 UNOP (0x82b0860) null [15]
184 PADOP (0x82b0840) gvsv GV (0x82a818c) *a
185EOT_EOT
186# UNOP (0x8282310) leavesub [1]
187# LISTOP (0x82822f0) lineseq
188# COP (0x82822b8) nextstate
189# UNOP (0x812fc20) null [15]
190# SVOP (0x812fc00) gvsv GV (0x814692c) *a
191EONT_EONT
192
193checkOptree ( name => "sticky-terse exec",
194 bcopts => [qw/ -exec /],
195 code => sub{$a},
196 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
197 goto UNOP (0x82b0918)
198COP (0x82b0d70) nextstate
199PADOP (0x82b0d30) gvsv GV (0x82a818c) *a
200UNOP (0x82b0e08) leavesub [1]
201EOT_EOT
202# goto UNOP (0x8282310)
203# COP (0x82828e0) nextstate
204# SVOP (0x82828a0) gvsv GV (0x814692c) *a
205# UNOP (0x8282938) leavesub [1]
206EONT_EONT
207
208pass("OPTIONS IN CMDLINE MODE");
209
210checkOptree ( name => 'cmdline invoke -basic works',
211 prog => 'sort @a',
212 #bcopts => '-basic', # default
213 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
214# 7 <@> leave[1 ref] vKP/REFC ->(end)
215# 1 <0> enter ->2
216# 2 <;> nextstate(main 1 -e:1) v ->3
217# 6 <@> sort vK ->7
218# 3 <0> pushmark s ->4
219# 5 <1> rv2av[t2] lK/1 ->6
220# 4 <#> gv[*a] s ->5
221EOT_EOT
222# 7 <@> leave[1 ref] vKP/REFC ->(end)
223# 1 <0> enter ->2
224# 2 <;> nextstate(main 1 -e:1) v ->3
225# 6 <@> sort vK ->7
226# 3 <0> pushmark s ->4
227# 5 <1> rv2av[t1] lK/1 ->6
228# 4 <$> gv(*a) s ->5
229EONT_EONT
230
231checkOptree ( name => 'cmdline invoke -exec works',
232 prog => 'sort @a',
233 bcopts => '-exec',
234 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
2351 <0> enter
2362 <;> nextstate(main 1 -e:1) v
2373 <0> pushmark s
2384 <#> gv[*a] s
2395 <1> rv2av[t2] lK/1
2406 <@> sort vK
2417 <@> leave[1 ref] vKP/REFC
242EOT_EOT
243# 1 <0> enter
244# 2 <;> nextstate(main 1 -e:1) v
245# 3 <0> pushmark s
246# 4 <$> gv(*a) s
247# 5 <1> rv2av[t1] lK/1
248# 6 <@> sort vK
249# 7 <@> leave[1 ref] vKP/REFC
250EONT_EONT
251
252checkOptree ( name => 'cmdline self-strict compile err',
253 prog => 'use strict; sort @a',
254 bcopts => [qw/ -basic -concise -exec /],
255 expect => 'compilation errors',
256 expect_nt => 'compilation errors');
257
258checkOptree ( name => 'error at -e line 1',
259 prog => 'our @a; sort @a',
260 bcopts => [qw/ -basic -concise -exec /],
261 expect => 'at -e line 1',
262 expect_nt => 'at -e line 1');
263
264checkOptree ( name => 'cmdline -basic -concise -exec works',
265 prog => 'our @a; sort @a',
266 bcopts => [qw/ -basic -concise -exec /],
267 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
268# 1 <0> enter
269# 2 <;> nextstate(main 1 -e:1) v
270# 3 <#> gv[*a] s
271# 4 <1> rv2av[t3] vK/OURINTR,1
272# 5 <;> nextstate(main 2 -e:1) v
273# 6 <0> pushmark s
274# 7 <#> gv[*a] s
275# 8 <1> rv2av[t5] lK/1
276# 9 <@> sort vK
277# a <@> leave[1 ref] vKP/REFC
278EOT_EOT
279# 1 <0> enter
280# 2 <;> nextstate(main 1 -e:1) v
281# 3 <$> gv(*a) s
282# 4 <1> rv2av[t2] vK/OURINTR,1
283# 5 <;> nextstate(main 2 -e:1) v
284# 6 <0> pushmark s
285# 7 <$> gv(*a) s
286# 8 <1> rv2av[t3] lK/1
287# 9 <@> sort vK
288# a <@> leave[1 ref] vKP/REFC
289EONT_EONT
290
291
292#################################
293pass("B::Concise STYLE/CALLBACK TESTS");
294
295use B::Concise qw( walk_output add_style set_style_standard add_callback );
296
297# new relative style, added by set_up_relative_test()
298@stylespec =
299 ( "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
300 . "#exname#arg(?([#targarglife])?)~#flags(?(/#privateb)?)(x(;~->#next)x) "
301 . "(x(;~=> #extra)x)\n" # new 'variable' used here
302
303 , " (*( )*) goto #seq\n"
304 , "(?(<#speq>)?)#exname#arg(?([#targarglife])?)"
305 #. "(x(;~=> #extra)x)\n" # new 'variable' used here
306 );
307
308sub set_up_relative_test {
309 # add a new style, and a callback which adds an 'extra' property
310
311 add_style ( "relative" => @stylespec );
312 #set_style_standard ( "relative" );
313
314 add_callback
315 ( sub {
316 my ($h, $op, $format, $level, $style) = @_;
317
318 # callback marks up const ops
319 $h->{arg} .= ' CALLBACK' if $h->{name} eq 'const';
320 $h->{extra} = '';
321
322 # 2 style specific behaviors
323 if ($style eq 'relative') {
324 $h->{extra} = 'RELATIVE';
325 $h->{arg} .= ' RELATIVE' if $h->{name} eq 'leavesub';
326 }
327 elsif ($style eq 'scope') {
328 # supress printout entirely
329 $$format="" unless grep { $h->{name} eq $_ } @scopeops;
330 }
331 });
332}
333
334#################################
335set_up_relative_test();
336pass("set_up_relative_test, new callback installed");
337
338checkOptree ( name => 'callback used, independent of style',
339 bcopts => [qw/ -concise -exec /],
340 code => sub{$a=$b+42},
341 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
342 goto -
3431 <;> nextstate(main 76 optree_concise.t:337) v
3442 <#> gvsv[*b] s
3453 <$> const[IV 42] CALLBACK s
3464 <2> add[t3] sK/2
3475 <#> gvsv[*a] s
3486 <2> sassign sKS/2
3497 <1> leavesub[1 ref] K/REFC,1
350EOT_EOT
351# 1 <;> nextstate(main 455 optree_concise.t:328) v
352# 2 <$> gvsv(*b) s
353# 3 <$> const(IV 42) CALLBACK s
354# 4 <2> add[t1] sK/2
355# 5 <$> gvsv(*a) s
356# 6 <2> sassign sKS/2
357# 7 <1> leavesub[1 ref] K/REFC,1
358EONT_EONT
359
360checkOptree ( name => "new 'relative' style, -exec mode",
361 bcopts => [qw/ -basic -relative /],
362 code => sub{$a=$b+42},
363 crossfail => 1,
364 #retry => 1,
365 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
3667 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
367- <@> lineseq KP ->7 => RELATIVE
3681 <;> nextstate(main 49 optree_concise.t:309) v ->2 => RELATIVE
3696 <2> sassign sKS ->7 => RELATIVE
3704 <2> add[t3] sK ->5 => RELATIVE
371- <1> ex-rv2sv sK ->3 => RELATIVE
3722 <#> gvsv[*b] s ->3 => RELATIVE
3733 <$> const[IV 42] CALLBACK s ->4 => RELATIVE
374- <1> ex-rv2sv sKRM* ->6 => RELATIVE
3755 <#> gvsv[*a] s ->6 => RELATIVE
376EOT_EOT
377# 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
378# - <@> lineseq KP ->7 => RELATIVE
379# 1 <;> nextstate(main 77 optree_concise.t:353) v ->2 => RELATIVE
380# 6 <2> sassign sKS ->7 => RELATIVE
381# 4 <2> add[t1] sK ->5 => RELATIVE
382# - <1> ex-rv2sv sK ->3 => RELATIVE
383# 2 <$> gvsv(*b) s ->3 => RELATIVE
384# 3 <$> const(IV 42) CALLBACK s ->4 => RELATIVE
385# - <1> ex-rv2sv sKRM* ->6 => RELATIVE
386# 5 <$> gvsv(*a) s ->6 => RELATIVE
387EONT_EONT
388
389checkOptree ( name => "both -exec -relative",
390 bcopts => [qw/ -exec -relative /],
391 code => sub{$a=$b+42},
392 crossfail => 1,
393 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
394 goto -
3951 <;> nextstate(main 50 optree_concise.t:326) v
3962 <#> gvsv[*b] s
3973 <$> const[IV 42] CALLBACK s
3984 <2> add[t3] sK
3995 <#> gvsv[*a] s
4006 <2> sassign sKS
4017 <1> leavesub RELATIVE[1 ref] K
402EOT_EOT
403# 1 <;> nextstate(main 78 optree_concise.t:371) v
404# 2 <$> gvsv(*b) s
405# 3 <$> const(IV 42) CALLBACK s
406# 4 <2> add[t1] sK
407# 5 <$> gvsv(*a) s
408# 6 <2> sassign sKS
409# 7 <1> leavesub RELATIVE[1 ref] K
410EONT_EONT
411
412#################################
413
414@scopeops = qw( leavesub enter leave nextstate );
415add_style
416 ( 'scope' # concise copy
417 , "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
418 . "#exname#arg(?([#targarglife])?)~#flags(?(/#private)?)(x(;~->#next)x) "
419 , " (*( )*) goto #seq\n"
420 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
421 );
422
423checkOptree ( name => "both -exec -scope",
424 bcopts => [qw/ -exec -scope /],
425 code => sub{$a=$b+42},
426 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
427 goto -
4281 <;> nextstate(main 50 optree_concise.t:337) v
4297 <1> leavesub[1 ref] K/REFC,1
430EOT_EOT
431 goto -
4321 <;> nextstate(main 75 optree_concise.t:396) v
4337 <1> leavesub[1 ref] K/REFC,1
434EONT_EONT
435
436
437checkOptree ( name => "both -basic -scope",
438 bcopts => [qw/ -basic -scope /],
439 code => sub{$a=$b+42},
440 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
4417 <1> leavesub[1 ref] K/REFC,1 ->(end)
4421 <;> nextstate(main 51 optree_concise.t:347) v ->2
443EOT_EOT
4447 <1> leavesub[1 ref] K/REFC,1 ->(end)
4451 <;> nextstate(main 76 optree_concise.t:407) v ->2
446EONT_EONT
447
2ce64696 448} #skip
724aa791 449
450__END__
451