5 @INC = ('../lib', '../ext/B/t');
7 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
8 print "1..0 # Skip -- Perl configured without B module\n";
11 if ($Config{'extensions'} !~ /\bData\/Dumper\b/) {
13 "1..0 # Skip: Data::Dumper was not built, needed by OptreeCheck\n";
20 # import checkOptree(), and %gOpts (containing test state)
21 use OptreeCheck; # ALSO DOES @ARGV HANDLING !!!!!!
26 skip "no perlio in this build", 23 unless $Config::Config{useperlio};
28 $SIG{__WARN__} = sub {
30 $err =~ m/Subroutine re::(un)?install redefined/ and return;
32 #################################
33 pass("CANONICAL B::Concise EXAMPLE");
35 checkOptree ( name => 'canonical example w -basic',
37 code => sub{$a=$b+42},
38 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
39 # 7 <1> leavesub[\d+ refs?] K/REFC,1 ->(end)
40 # - <@> lineseq KP ->7
41 # 1 <;> nextstate(foo bar) v ->2
42 # 6 <2> sassign sKS/2 ->7
43 # 4 <2> add[t\d+] 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
50 # 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
51 # - <@> lineseq KP ->7
52 # 1 <;> nextstate(main 60 optree_concise.t:122) v ->2
53 # 6 <2> sassign sKS/2 ->7
54 # 4 <2> add[t1] sK/2 ->5
55 # - <1> ex-rv2sv sK/1 ->3
56 # 2 <$> gvsv(*b) s ->3
57 # 3 <$> const(IV 42) s ->4
58 # - <1> ex-rv2sv sKRM*/1 ->6
59 # 5 <$> gvsv(*a) s ->6
62 checkOptree ( name => 'canonical example w -exec',
64 code => sub{$a=$b+42},
65 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
66 # 1 <;> nextstate(main 61 optree_concise.t:139) v
68 # 3 <$> const[IV 42] s
72 # 7 <1> leavesub[1 ref] K/REFC,1
74 # 1 <;> nextstate(main 61 optree_concise.t:139) v
76 # 3 <$> const(IV 42) s
80 # 7 <1> leavesub[1 ref] K/REFC,1
83 #################################
84 pass("B::Concise OPTION TESTS");
86 checkOptree ( name => '-base3 sticky-exec',
88 code => sub{$a=$b+42},
89 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
90 1 <;> dbstate(main 24 optree_concise.t:132) v
96 21 <1> leavesub[1 ref] K/REFC,1
98 # 1 <;> nextstate(main 62 optree_concise.t:161) v
100 # 10 <$> const(IV 42) s
101 # 11 <2> add[t1] sK/2
103 # 20 <2> sassign sKS/2
104 # 21 <1> leavesub[1 ref] K/REFC,1
107 checkOptree ( name => 'sticky-base3, -basic over sticky-exec',
109 code => sub{$a=$b+42},
110 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
111 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
112 - <@> lineseq KP ->21
113 1 <;> nextstate(main 32 optree_concise.t:164) v ->2
114 20 <2> sassign sKS/2 ->21
115 11 <2> add[t3] 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
122 # 21 <1> leavesub[1 ref] K/REFC,1 ->(end)
123 # - <@> lineseq KP ->21
124 # 1 <;> nextstate(main 63 optree_concise.t:186) v ->2
125 # 20 <2> sassign sKS/2 ->21
126 # 11 <2> add[t1] sK/2 ->12
127 # - <1> ex-rv2sv sK/1 ->10
128 # 2 <$> gvsv(*b) s ->10
129 # 10 <$> const(IV 42) s ->11
130 # - <1> ex-rv2sv sKRM*/1 ->20
131 # 12 <$> gvsv(*a) s ->20
134 checkOptree ( name => '-base4',
135 bcopts => [qw/ -basic -base4 /],
136 code => sub{$a=$b+42},
137 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
138 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
139 - <@> lineseq KP ->13
140 1 <;> nextstate(main 26 optree_concise.t:145) v ->2
141 12 <2> sassign sKS/2 ->13
142 10 <2> add[t3] sK/2 ->11
143 - <1> ex-rv2sv sK/1 ->3
145 3 <$> const[IV 42] s ->10
146 - <1> ex-rv2sv sKRM*/1 ->12
147 11 <#> gvsv[*a] s ->12
149 # 13 <1> leavesub[1 ref] K/REFC,1 ->(end)
150 # - <@> lineseq KP ->13
151 # 1 <;> nextstate(main 64 optree_concise.t:193) v ->2
152 # 12 <2> sassign sKS/2 ->13
153 # 10 <2> add[t1] sK/2 ->11
154 # - <1> ex-rv2sv sK/1 ->3
155 # 2 <$> gvsv(*b) s ->3
156 # 3 <$> const(IV 42) s ->10
157 # - <1> ex-rv2sv sKRM*/1 ->12
158 # 11 <$> gvsv(*a) s ->12
161 checkOptree ( name => "restore -base36 default",
162 bcopts => [qw/ -basic -base36 /],
165 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
166 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
168 1 <;> nextstate(main 27 optree_concise.t:161) v ->2
169 - <1> ex-rv2sv sK/1 ->-
172 # 3 <1> leavesub[1 ref] K/REFC,1 ->(end)
173 # - <@> lineseq KP ->3
174 # 1 <;> nextstate(main 65 optree_concise.t:210) v ->2
175 # - <1> ex-rv2sv sK/1 ->-
176 # 2 <$> gvsv(*a) s ->3
179 checkOptree ( name => "terse basic",
180 bcopts => [qw/ -basic -terse /],
182 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
183 UNOP (0x82b0918) leavesub [1]
184 LISTOP (0x82b08d8) lineseq
185 COP (0x82b0880) nextstate
186 UNOP (0x82b0860) null [15]
187 PADOP (0x82b0840) gvsv GV (0x82a818c) *a
189 # UNOP (0x8282310) leavesub [1]
190 # LISTOP (0x82822f0) lineseq
191 # COP (0x82822b8) nextstate
192 # UNOP (0x812fc20) null [15]
193 # SVOP (0x812fc00) gvsv GV (0x814692c) *a
196 checkOptree ( name => "sticky-terse exec",
197 bcopts => [qw/ -exec /],
199 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
200 COP (0x82b0d70) nextstate
201 PADOP (0x82b0d30) gvsv GV (0x82a818c) *a
202 UNOP (0x82b0e08) leavesub [1]
204 # COP (0x82828e0) nextstate
205 # SVOP (0x82828a0) gvsv GV (0x814692c) *a
206 # UNOP (0x8282938) leavesub [1]
209 pass("OPTIONS IN CMDLINE MODE");
211 checkOptree ( name => 'cmdline invoke -basic works',
213 #bcopts => '-basic', # default
214 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
215 # 7 <@> leave[1 ref] vKP/REFC ->(end)
217 # 2 <;> nextstate(main 1 -e:1) v ->3
219 # 3 <0> pushmark s ->4
220 # 5 <1> rv2av[t2] lK/1 ->6
223 # 7 <@> leave[1 ref] vKP/REFC ->(end)
225 # 2 <;> nextstate(main 1 -e:1) v ->3
227 # 3 <0> pushmark s ->4
228 # 5 <1> rv2av[t1] lK/1 ->6
232 checkOptree ( name => 'cmdline invoke -exec works',
235 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
237 2 <;> nextstate(main 1 -e:1) v
242 7 <@> leave[1 ref] vKP/REFC
245 # 2 <;> nextstate(main 1 -e:1) v
248 # 5 <1> rv2av[t1] lK/1
250 # 7 <@> leave[1 ref] vKP/REFC
253 checkOptree ( name => 'cmdline self-strict compile err',
254 prog => 'use strict; sort @a',
255 bcopts => [qw/ -basic -concise -exec /],
257 expect => 'compilation errors',
258 expect_nt => 'compilation errors');
260 checkOptree ( name => 'error at -e line 1',
261 prog => 'our @a; sort @a',
262 bcopts => [qw/ -basic -concise -exec /],
264 expect => 'at -e line 1',
265 expect_nt => 'at -e line 1');
267 checkOptree ( name => 'cmdline -basic -concise -exec works',
268 prog => 'our @a; sort @a',
269 bcopts => [qw/ -basic -concise -exec /],
270 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
272 # 2 <;> nextstate(main 1 -e:1) v
274 # 4 <1> rv2av[t3] vK/OURINTR,1
275 # 5 <;> nextstate(main 2 -e:1) v
278 # 8 <1> rv2av[t5] lK/1
280 # a <@> leave[1 ref] vKP/REFC
283 # 2 <;> nextstate(main 1 -e:1) v
285 # 4 <1> rv2av[t2] vK/OURINTR,1
286 # 5 <;> nextstate(main 2 -e:1) v
289 # 8 <1> rv2av[t3] lK/1
291 # a <@> leave[1 ref] vKP/REFC
295 #################################
296 pass("B::Concise STYLE/CALLBACK TESTS");
298 use B::Concise qw( walk_output add_style set_style_standard add_callback );
300 # new relative style, added by set_up_relative_test()
302 ( "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
303 . "#exname#arg(?([#targarglife])?)~#flags(?(/#privateb)?)(x(;~->#next)x) "
304 . "(x(;~=> #extra)x)\n" # new 'variable' used here
306 , " (*( )*) goto #seq\n"
307 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
308 #. "(x(;~=> #extra)x)\n" # new 'variable' used here
311 sub set_up_relative_test {
312 # add a new style, and a callback which adds an 'extra' property
314 add_style ( "relative" => @stylespec );
315 #set_style_standard ( "relative" );
319 my ($h, $op, $format, $level, $style) = @_;
321 # callback marks up const ops
322 $h->{arg} .= ' CALLBACK' if $h->{name} eq 'const';
325 if ($lastnext and $$lastnext != $$op) {
326 $h->{goto} = ($h->{seq} eq '-')
327 ? 'unresolved' : $h->{seq};
330 # 2 style specific behaviors
331 if ($style eq 'relative') {
332 $h->{extra} = 'RELATIVE';
333 $h->{arg} .= ' RELATIVE' if $h->{name} eq 'leavesub';
335 elsif ($style eq 'scope') {
336 # supress printout entirely
337 $$format="" unless grep { $h->{name} eq $_ } @scopeops;
342 #################################
343 set_up_relative_test();
344 pass("set_up_relative_test, new callback installed");
346 checkOptree ( name => 'callback used, independent of style',
347 bcopts => [qw/ -concise -exec /],
348 code => sub{$a=$b+42},
349 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
350 1 <;> nextstate(main 76 optree_concise.t:337) v
352 3 <$> const[IV 42] CALLBACK s
356 7 <1> leavesub[1 ref] K/REFC,1
358 # 1 <;> nextstate(main 455 optree_concise.t:328) v
360 # 3 <$> const(IV 42) CALLBACK s
363 # 6 <2> sassign sKS/2
364 # 7 <1> leavesub[1 ref] K/REFC,1
367 checkOptree ( name => "new 'relative' style, -exec mode",
368 bcopts => [qw/ -basic -relative /],
369 code => sub{$a=$b+42},
372 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
373 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
374 - <@> lineseq KP ->7 => RELATIVE
375 1 <;> nextstate(main 49 optree_concise.t:309) v ->2 => RELATIVE
376 6 <2> sassign sKS ->7 => RELATIVE
377 4 <2> add[t3] 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
384 # 7 <1> leavesub RELATIVE[1 ref] K ->(end) => RELATIVE
385 # - <@> lineseq KP ->7 => RELATIVE
386 # 1 <;> nextstate(main 77 optree_concise.t:353) v ->2 => RELATIVE
387 # 6 <2> sassign sKS ->7 => RELATIVE
388 # 4 <2> add[t1] sK ->5 => RELATIVE
389 # - <1> ex-rv2sv sK ->3 => RELATIVE
390 # 2 <$> gvsv(*b) s ->3 => RELATIVE
391 # 3 <$> const(IV 42) CALLBACK s ->4 => RELATIVE
392 # - <1> ex-rv2sv sKRM* ->6 => RELATIVE
393 # 5 <$> gvsv(*a) s ->6 => RELATIVE
396 checkOptree ( name => "both -exec -relative",
397 bcopts => [qw/ -exec -relative /],
398 code => sub{$a=$b+42},
400 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
401 1 <;> nextstate(main 50 optree_concise.t:326) v
403 3 <$> const[IV 42] CALLBACK s
407 7 <1> leavesub RELATIVE[1 ref] K
409 # 1 <;> nextstate(main 78 optree_concise.t:371) v
411 # 3 <$> const(IV 42) CALLBACK s
415 # 7 <1> leavesub RELATIVE[1 ref] K
418 #################################
420 @scopeops = qw( leavesub enter leave nextstate );
422 ( 'scope' # concise copy
423 , "#hyphseq2 (*( (x( ;)x))*)<#classsym> "
424 . "#exname#arg(?([#targarglife])?)~#flags(?(/#private)?)(x(;~->#next)x) "
425 , " (*( )*) goto #seq\n"
426 , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
429 checkOptree ( name => "both -exec -scope",
430 bcopts => [qw/ -exec -scope /],
431 code => sub{$a=$b+42},
432 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
433 1 <;> nextstate(main 50 optree_concise.t:337) v
434 7 <1> leavesub[1 ref] K/REFC,1
436 1 <;> nextstate(main 75 optree_concise.t:396) v
437 7 <1> leavesub[1 ref] K/REFC,1
441 checkOptree ( name => "both -basic -scope",
442 bcopts => [qw/ -basic -scope /],
443 code => sub{$a=$b+42},
444 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
445 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
446 1 <;> nextstate(main 51 optree_concise.t:347) v ->2
448 7 <1> leavesub[1 ref] K/REFC,1 ->(end)
449 1 <;> nextstate(main 76 optree_concise.t:407) v ->2