El siguiente programa Btree3.pl
implanta una subrutina
treetrav
que muestra el árbol
generado por el compilador para una subrutina dada.
pp2@nereida:~/src/perl/B$ cat -n Btree3.pl 1 #!/usr/local/bin/perl -w 2 use strict; 3 use B::Utils; 4 5 my $s = sub { 6 my $a = shift; 7 print $a+1; 8 }; 9 10 sub treetrav { .. ........... 22 } 23 24 my $b = B::svref_2object($s); # Objeto B::CV 25 print "*** Tree ***\n"; 26 my $op = $b->ROOT; 27 treetrav($op, 0);La llamada a B::svref_2object sobre la subrutina referenciada por
$s
nos produce un objeto
B::CV que representa el árbol de codigo resultante.
Cuando treetrav
es llamada con el objeto y un sangrado inicial igual a 0
nos produce la siguiente
salida:
pp2@nereida:~/src/perl/B$ Btree3.pl *** Tree *** leavesub( #subroutine exit lineseq( #line sequence sassign( #scalar assignment shift( #shift rv2av( #array dereference gv( #glob value ) # end gv ) # end rv2av ) # end shift padsv( #private variable ) # end padsv ) # end sassign nextstate( #next statement ) # end nextstate print( #print add( #addition (+) padsv( #private variable ) # end padsv const( #constant item ) # end const ) # end add ) # end print ) # end lineseq ) # end leavesubLa función
treetrav
usa los métodos name
y desc
de la subclase B::OP
para obtener el nombre y la descripción de la operación actual.
El método kids
en B::Utils
devuelve la lista de hijos:
10 sub treetrav { 11 my $op = shift; 12 my $indent = shift; 13 14 my $spaces = " "x$indent; 15 print $spaces.$op->name."(\t\t#".$op->desc; 16 print "\n"; 17 for ($op->kids()) { 18 treetrav($_, $indent+2); 19 } 20 print "$spaces) # end ".$op->name; 21 print "\n"; 22 }
Hay varias subrutinas de recorrido del árbol de
códigos. Una de las mas sencillas es walkoptree_simple
(en B::Utils
):
walkoptree_simple($op, \&callback, [$data])
Casiano Rodríguez León