line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Spp::Cursor; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
26
|
use 5.012; |
|
2
|
|
|
|
|
5
|
|
4
|
2
|
|
|
2
|
|
8
|
no warnings 'experimental'; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
47
|
|
5
|
|
|
|
|
|
|
|
6
|
2
|
|
|
2
|
|
8
|
use Exporter; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
105
|
|
7
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
8
|
|
|
|
|
|
|
our @EXPORT = |
9
|
|
|
|
|
|
|
qw(new_cursor load_text to_next cache reset_cache get_char pre_char fail_report); |
10
|
|
|
|
|
|
|
|
11
|
2
|
|
|
2
|
|
10
|
use Spp::Builtin; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
976
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new_cursor { |
14
|
3
|
|
|
3
|
0
|
10
|
my ($str, $ns) = @_; |
15
|
3
|
|
|
|
|
14
|
my $text = add($str, End); |
16
|
3
|
|
|
|
|
11
|
my $length = len($text); |
17
|
|
|
|
|
|
|
return { |
18
|
3
|
|
|
|
|
40
|
'text' => $text, |
19
|
|
|
|
|
|
|
'ns' => $ns, |
20
|
|
|
|
|
|
|
'length' => $length, |
21
|
|
|
|
|
|
|
'off' => 0, |
22
|
|
|
|
|
|
|
'line' => 1, |
23
|
|
|
|
|
|
|
'depth' => 0, |
24
|
|
|
|
|
|
|
'maxoff' => 0, |
25
|
|
|
|
|
|
|
'maxline' => 1 |
26
|
|
|
|
|
|
|
}; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub load_text { |
30
|
0
|
|
|
0
|
0
|
0
|
my ($cursor, $text) = @_; |
31
|
0
|
|
|
|
|
0
|
$cursor->{'text'} = $text; |
32
|
0
|
|
|
|
|
0
|
$cursor->{'off'} = 0; |
33
|
0
|
|
|
|
|
0
|
return True; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub to_next { |
37
|
39
|
|
|
39
|
0
|
54
|
my $cursor = shift; |
38
|
39
|
50
|
|
|
|
54
|
if (get_char($cursor) eq "\n") { $cursor->{'line'}++ } |
|
0
|
|
|
|
|
0
|
|
39
|
39
|
|
|
|
|
74
|
$cursor->{'off'}++; |
40
|
39
|
100
|
|
|
|
76
|
if ($cursor->{'off'} > $cursor->{'maxoff'}) { |
41
|
36
|
|
|
|
|
68
|
$cursor->{'maxoff'} = $cursor->{'off'}; |
42
|
36
|
|
|
|
|
47
|
$cursor->{'maxline'} = $cursor->{'line'}; |
43
|
|
|
|
|
|
|
} |
44
|
39
|
|
|
|
|
50
|
return True; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub cache { |
48
|
325
|
|
|
325
|
0
|
387
|
my $cursor = shift; |
49
|
325
|
|
|
|
|
387
|
my $off = $cursor->{'off'}; |
50
|
325
|
|
|
|
|
367
|
my $line = $cursor->{'line'}; |
51
|
325
|
|
|
|
|
654
|
return [$off, $line]; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub reset_cache { |
55
|
224
|
|
|
224
|
0
|
327
|
my ($cursor, $cache) = @_; |
56
|
224
|
|
|
|
|
325
|
$cursor->{'off'} = $cache->[0]; |
57
|
224
|
|
|
|
|
277
|
$cursor->{'line'} = $cache->[1]; |
58
|
224
|
|
|
|
|
368
|
return True; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub get_char { |
62
|
273
|
|
|
273
|
0
|
333
|
my $cursor = shift; |
63
|
273
|
|
|
|
|
1041
|
return substr($cursor->{'text'}, $cursor->{'off'}, 1); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub pre_char { |
67
|
0
|
|
|
0
|
0
|
|
my $cursor = shift; |
68
|
0
|
|
|
|
|
|
return substr($cursor->{'text'}, $cursor->{'off'} - 1, 1); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub fail_report { |
72
|
0
|
|
|
0
|
0
|
|
my $cursor = shift; |
73
|
0
|
|
|
|
|
|
my $text = $cursor->{'text'}; |
74
|
0
|
|
|
|
|
|
my $off = $cursor->{'maxoff'}; |
75
|
0
|
|
|
|
|
|
my $line = $cursor->{'maxline'}; |
76
|
0
|
|
|
|
|
|
my $line_str = to_end(substr($text, $off)); |
77
|
0
|
|
|
|
|
|
return "line: $line Stop match:\n$line_str\n^"; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
1; |