File Coverage

blib/lib/Pugs/Runtime/Match.pm
Criterion Covered Total %
statement 50 112 44.6
branch 3 22 13.6
condition 1 3 33.3
subroutine 19 33 57.5
pod 0 24 0.0
total 73 194 37.6


line stmt bran cond sub pod time code
1             package Pugs::Runtime::Match;
2             # Documentation in the __END__
3              
4 22     22   39981 use 5.006;
  22         88  
  22         904  
5 22     22   120 use strict;
  22         47  
  22         679  
6 22     22   143 use warnings;
  22         41  
  22         584  
7 22     22   7942 use Data::Dumper;
  22         75431  
  22         1743  
8             #use Class::InsideOut qw( public register id );
9 22     22   186 use Scalar::Util qw( refaddr blessed );
  22         85  
  22         2525  
10 22     22   13642 use Pugs::Runtime::StrPos;
  22         80  
  22         2012  
11              
12             use overload (
13 22         286 '@{}' => \&array,
14             '%{}' => \&hash,
15             'bool' => \&bool,
16             '&{}' => \&code,
17             '${}' => \&scalar,
18             '""' => \&flat,
19             '0+' => \&flat,
20             fallback => 1,
21 22     22   169 );
  22         49  
22              
23             # class method
24             # ::fail can be called from inside closures
25             # sub ::fail { $::_V6_SUCCEED = 0 }
26              
27             my %_data;
28              
29             sub new {
30 213     213 0 606 my $obj = bless \$_[1], $_[0];
31 213         824 $_data{ refaddr $obj } = $_[1];
32 213         902 return $obj;
33             }
34              
35             sub DESTROY {
36 213     213   4434 delete $_data{ refaddr $_[0] };
37             }
38              
39 646     646 0 4310 sub data { $_data{refaddr $_[0]} }
40 747     747 0 1003 sub bool { ${$_data{refaddr $_[0]}->{bool}} }
  747         4270  
41 84     84 0 437 sub array { $_data{refaddr $_[0]}->{match} }
42              
43             sub from {
44              
45 213     213 0 234 return ${$_data{refaddr $_[0]}->{from}};
  213         1078  
46              
47 0         0 my $obj = $_data{refaddr $_[0]};
48             #return ${$obj->{from}} if blessed ${$obj->{from}};
49 0         0 Pugs::Runtime::StrPos->from_str_codes( ${$obj->{str}}, ${$obj->{from}} );
  0         0  
  0         0  
50             }
51 0     0 0 0 sub pos { $_[0]->to } # pugs pos.t - lvalue ???
52             sub to {
53              
54 395     395 0 664 return ${$_data{refaddr $_[0]}->{to}};
  395         4989  
55              
56 0         0 my $obj = $_data{refaddr $_[0]};
57             #return ${$obj->{to}} if blessed ${$obj->{to}};
58             #print "TO: ",${$obj->{to}},"\n";
59 0         0 Pugs::Runtime::StrPos->from_str_codes( ${$obj->{str}}, ${$obj->{to}} );
  0         0  
  0         0  
60             }
61             # "low-level" position defaults to perl5-utf8
62 0     0 0 0 sub from_as_codes { ${$_data{refaddr $_[0]}->{from}} }
  0         0  
63 0     0 0 0 sub to_as_codes { ${$_data{refaddr $_[0]}->{to}} }
  0         0  
64              
65             sub hash {
66 77     77 0 215 my $array = $_data{refaddr $_[0]}->{match};
67 77         181 my $hash = $_data{refaddr $_[0]}->{named};
68 77         167 $hash->{$_} = $array->[$_] for 0 .. $#$array;
69 77         322 return $hash;
70              
71             #my $array = $_data{refaddr $_[0]}->{match};
72             #return {
73             # %{ $_data{refaddr $_[0]}->{named} },
74             # (
75             # map { ( $_, $array->[$_] ) }
76             # 0 .. $#$array
77             # ),
78             #}
79             }
80             sub keys {
81 0         0 CORE::keys %{$_data{refaddr $_[0]}->{named}},
  0         0  
82 0     0 0 0 0 .. $#{ $_[0]->array }
83             }
84             sub values {
85 0         0 CORE::values %{$_data{refaddr $_[0]}->{named}},
  0         0  
86 0     0 0 0 @{ $_[0]->array }
87             }
88             sub kv {
89 0     0 0 0 map { ( $_, $_[0]->{$_} ) }
  0         0  
90             $_[0]->keys
91             }
92             sub elems {
93 0     0 0 0 scalar $_[0]->keys
94             }
95              
96 0     0 0 0 sub chars { CORE::length $_[0]->str }
97              
98             sub flat {
99 41     41 0 205 my $obj = $_data{refaddr $_[0]};
100 41         61 my $cap = $obj->{capture};
101             #print ref $cap;
102 41 50 33     217 return $$cap
103             if ref $cap eq 'REF' ||
104             ref $cap eq 'SCALAR';
105 41 50       717 return '' unless ${$obj->{bool}};
  41         112  
106            
107 41 50       117 return '' if $_[0]->from > length( ${$obj->{str}} );
  41         130  
108            
109 41         56 return substr( ${$obj->{str}}, $_[0]->from, $_[0]->to - $_[0]->from );
  41         114  
110             }
111              
112             sub str {
113 19     19 0 84 "" . $_[0]->flat;
114             }
115              
116             sub perl {
117 0     0 0 0 local $Data::Dumper::Terse = 1;
118 0         0 local $Data::Dumper::Sortkeys = 1;
119 0         0 local $Data::Dumper::Pad = ' ';
120 0         0 return __PACKAGE__ . "->new( " . Dumper( $_[0]->data ) . ")\n";
121             }
122              
123             sub yaml {
124 0     0 0 0 require YAML::Syck;
125             # interoperability with other YAML/Syck bindings:
126 0         0 $YAML::Syck::ImplicitTyping = 1;
127 0         0 YAML::Syck::Dump( $_[0] );
128             }
129              
130             # for Pugs interoperability
131             sub dump_hs {
132 0     0 0 0 my $obj;
133 0 0       0 if (ref($_[0]) eq 'SCALAR') {
134 0         0 $obj = ${$_[0]};
  0         0  
135             }
136             else {
137 0         0 $obj = $_data{refaddr $_[0]};
138             }
139              
140 0 0       0 if ($obj) {
    0          
    0          
141             # Ok, this is a genuine Match object.
142 0 0       0 return "PGE_Fail" unless ${$obj->{bool}};
  0         0  
143              
144             # Now we matched; dump the rest of data
145 0         0 join(' ', 'PGE_Match', ${$obj->{from}}, ${$obj->{to}},
  0         0  
  0         0  
146 0 0       0 ('['.join(', ', map { dump_hs($_) } @{$obj->{match}||[]} ).']'),
  0         0  
147             ('['.join(', ', map {
148 0 0       0 my $str = $_;
149 0 0       0 if ( my $dump = dump_hs($obj->{named}{$_}) ) {
150 0         0 $str =~ s/([^ \!\#\$\%\&\x28-\x5B\x5D-\x7E])/'\\'.ord($1)/eg;
  0         0  
151 0         0 qq[("$str", $dump)];
152             }
153             else {
154 0         0 ();
155             }
156 0         0 } sort(CORE::keys(%{$obj->{named}||{}})) ).']'),
157             )
158             }
159             elsif (ref($_[0]) eq 'ARRAY') {
160 0         0 return "PGE_Array [" . join(', ', map { dump_hs($_) } @$obj) . "]"
  0         0  
161             }
162             elsif (!ref($_[0])) {
163 0         0 my $str = shift;
164 0         0 $str =~ s/([^ \!\#\$\%\&\x28-\x5B\x5D-\x7E])/'\\'.ord($1)/eg;
  0         0  
165 0         0 return "PGE_String \"$str\"";
166             }
167             else {
168 0         0 warn "Unrecognized blessed match object: $_[0]";
169 0         0 return '';
170             }
171             }
172              
173             # tail() for backwards compatibility
174             # - doesn't work on failed matches
175             sub tail {
176 6     6 0 13 return substr( ${$_data{refaddr $_[0]}->{str}}, $_[0]->to );
  6         35  
177             }
178              
179             # state() is used for multiple matches and backtracking control
180             sub state {
181 321     321 0 1275 return $_data{refaddr $_[0]}->{state};
182             }
183              
184             # return the capture
185             sub code {
186 0     0 0   my $c = $_[0];
187 0     0     return sub { $c->flat };
  0            
188             }
189              
190             # return the capture
191             sub scalar {
192 0     0 0   return \( $_[0]->flat );
193             }
194              
195             1;
196              
197             __END__