File Coverage

blib/lib/Language/P/Toy/Value/SymbolTable.pm
Criterion Covered Total %
statement 35 51 68.6
branch 8 18 44.4
condition 5 14 35.7
subroutine 7 11 63.6
pod 1 6 16.6
total 56 100 56.0


line stmt bran cond sub pod time code
1             package Language::P::Toy::Value::SymbolTable;
2              
3 100     100   615 use strict;
  100         213  
  100         3890  
4 100     100   585 use warnings;
  100         232  
  100         2765  
5 100     100   521 use base qw(Language::P::Toy::Value::Any);
  100         199  
  100         68299  
6              
7             __PACKAGE__->mk_ro_accessors( qw(symbols) );
8              
9 100     100   67309 use Language::P::Toy::Value::Typeglob;
  100         346  
  100         1121  
10              
11 0     0 0 0 sub type { 7 }
12 0     0 0 0 sub is_main { 0 }
13              
14             sub new {
15 74     74 1 203 my( $class, $args ) = @_;
16 74         913 my $self = $class->SUPER::new( $args );
17              
18 74   50     2756 $self->{symbols} ||= {};
19              
20 74         338 return $self;
21             }
22              
23             sub get_package {
24 0     0 0 0 my( $self, $package ) = @_;
25              
26 0 0 0     0 return $self if $self->is_main && $package eq 'main';
27              
28 0         0 die 'Implement me';
29             }
30              
31             our %sigils =
32             ( '$' => [ 'scalar', 'Language::P::Toy::Value::Scalar' ],
33             '@' => [ 'array', 'Language::P::Toy::Value::Array' ],
34             '%' => [ 'hash', 'Language::P::Toy::Value::Hash' ],
35             '&' => [ 'subroutine', 'Language::P::Toy::Value::Subroutine' ],
36             '*' => [ undef, 'Language::P::Toy::Value::Typeglob' ],
37             'I' => [ 'io', 'Language::P::Toy::Value::Handle' ],
38             'F' => [ 'format', 'Language::P::Toy::Value::Format' ],
39             '::' => [ undef, 'language::P::Value::SymbolTable' ],
40             );
41              
42             sub get_symbol {
43 0     0 0 0 my( $self, $name, $sigil, $create ) = @_;
44 0         0 my( $symbol, $created ) = $self->_get_symbol( $name, $sigil, $create );
45              
46 0         0 return $symbol;
47             }
48              
49             sub _get_symbol {
50 3233     3233   5664 my( $self, $name, $sigil, $create ) = @_;
51 3233         9279 my( @packages ) = split /::/, $name;
52 3233 50 33     9493 if( $self->is_main && ( $packages[0] eq '' || $packages[0] eq 'main' ) ) {
      33        
53 0         0 shift @packages;
54             }
55              
56 3233         4526 my $index = 0;
57 3233         3916 my $current = $self;
58 3233         4865 foreach my $package ( @packages ) {
59 3233 50       6386 if( $index == $#packages ) {
60 3233 50       6141 return $current if $sigil eq '::';
61 3233         11981 my $glob = $current->{symbols}{$package};
62 3233         3976 my $created = 0;
63 3233 100 66     7220 return ( undef, $created ) if !$glob && !$create;
64 3223 100       6454 if( !$glob ) {
65 121         219 $created = 1;
66 121         1059 $glob = $current->{symbols}{$package} =
67             Language::P::Toy::Value::Typeglob->new;
68             }
69 3223 50       15255 return ( $glob, $created ) if $sigil eq '*';
70 0         0 return ( $glob->get_slot( $sigils{$sigil}[0] ), $created );
71             } else {
72 0         0 my $subpackage = $package . '::';
73 0 0       0 if( !exists $current->{symbols}{$subpackage} ) {
74 0 0       0 return ( undef, 0 ) unless $create;
75              
76 0         0 $current = $current->{symbols}{$subpackage} =
77             Language::P::Toy::Value::SymbolTable->new;
78             } else {
79 0         0 $current = $current->{symbols}{$subpackage};
80             }
81             }
82              
83 0         0 ++$index;
84             }
85             }
86              
87             sub set_symbol {
88 104     104 0 730 my( $self, $name, $sigil, $value ) = @_;
89 104         594 my $glob = $self->get_symbol( $name, '*', 1 );
90              
91 104         720 $glob->set_slot( $sigils{$sigil}[0], $value );
92              
93 104         5287 return;
94             }
95              
96             1;