File Coverage

blib/lib/assign/Array.pm
Criterion Covered Total %
statement 77 78 98.7
branch 26 32 81.2
condition 5 8 62.5
subroutine 8 8 100.0
pod 0 2 0.0
total 116 128 90.6


line stmt bran cond sub pod time code
1 5     5   33 use strict; use warnings;
  5     5   10  
  5         134  
  5         22  
  5         11  
  5         161  
2             package assign::Array;
3              
4 5     5   1924 use assign::Struct;
  5         13  
  5         144  
5 5     5   32 use base 'assign::Struct';
  5         8  
  5         483  
6              
7 5     5   1882 use assign::Types;
  5         13  
  5         162  
8              
9 5     5   32 use XXX;
  5         9  
  5         23  
10              
11             sub parse_elem {
12 66     66 0 121 my ($self) = @_;
13 66         108 my $in = $self->{in};
14 66         93 my $elems = $self->{elems};
15 66         130 while (@$in) {
16 110         139 my $tok = shift(@$in);
17 110         168 my $type = ref($tok);
18 110 100       229 next if $type eq 'PPI::Token::Whitespace';
19              
20 64 100       122 if ($type eq 'PPI::Token::Symbol') {
21 58         119 my $str = $tok->content;
22 58 50       351 if ($str =~ /^[\$\@]\w+$/) {
23 58         140 my $elem = $self->get_var($str);
24 58         124 push @$elems, $elem;
25 58         160 return 1;
26             }
27             }
28              
29             # Parse @$a in the following if-statement.
30 6 100       12 if ($type eq 'PPI::Token::Cast') {
31 1 50       4 $tok->content eq '@' or
32             XXX $tok, "unexpected token";
33 1         9 $tok = shift(@$in);
34 1         3 $type = ref($tok);
35 1         6 my $str = $tok->content;
36 1 50 33     15 $type eq 'PPI::Token::Symbol' and $str =~ /^\$\w+$/ or
37             XXX $tok, "unexpected token";
38 1         7 my $elem = $self->get_var($str);
39 1         7 $elem->{cast} = 1;
40 1         2 push @$elems, $elem;
41 1         3 return 1;
42             }
43              
44 5 100       46 if ($type eq 'PPI::Token::Number') {
45 2         6 my $str = $tok->content;
46 2 50       14 if ($str =~ /^[1-9][0-9]*$/) {
47 2         9 push @$elems, assign::skip_num->new($str);
48 2         7 return 1;
49             }
50             }
51 3 50       9 if ($type eq 'PPI::Token::Magic') {
52 3         8 my $str = $tok->content;
53 3 100       14 if ($str eq '_') {
54 2         8 push @$elems, assign::skip->new;
55 2         7 return 1;
56             }
57 1 50       8 if ($str eq '$_') {
58 1         4 push @$elems, assign::var->new($str);
59 1         6 return 1;
60             }
61             }
62 0         0 XXX $tok, "unexpected token";
63             }
64 2         7 return 0;
65             }
66              
67             sub gen_code {
68 21     21 0 55 my ($self, $decl, $oper, $from, $init) = @_;
69              
70 21         41 my $code = [ @$init ];
71 21         36 my $elems = $self->{elems};
72              
73 21 100       57 if ($decl) {
74             push @$code,
75             "$decl(" .
76             join(', ',
77             map $_->val,
78 53         109 grep {$_->val ne '$_'}
79 19         70 grep {$_->val =~ /^[\$\@]/}
  57         116  
80             @$elems
81             ) .
82             ');';
83             }
84              
85 21         47 my $i = 0;
86 21         45 for my $elem (@$elems) {
87 64         88 my $type = ref $elem;
88 64 100       141 if ($type eq 'assign::skip') {
89 2         3 $i++;
90 2         3 next;
91             }
92 62 100       106 if ($type eq 'assign::skip_num') {
93 2         5 $i += $elem->val;
94 2         3 next;
95             }
96              
97 60         114 my $var = $elem->val;
98 60   100     166 my $def = $elem->{def} // '';
99 60   66     113 $def &&= " // $def";
100              
101             push @$code,
102             ($elem->sigil eq '@')
103             ? "$var $oper \@$from\[$i..\@$from-1\]$def;" :
104             ($elem->{cast})
105 60 100       122 ? "$var $oper \[\@$from\[$i..\@$from-1\]\]$def;" :
    100          
106             "$var $oper $from\->[$i]$def;";
107              
108 60         144 $i++;
109             }
110              
111 21         101 return join "\n", @$code;
112             }
113              
114             1;