/
Match.pm
102 lines (90 loc) · 2.62 KB
/
Match.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
my class Match is Capture is Cool {
has $.orig;
has int $.from;
has int $.to;
has $.CURSOR;
has $.made;
# new/BUILD here only for performance reasons
method new(:$orig,:$from,:$to,:$CURSOR,:$made) {
nqp::create(self).BUILD(:$orig,:$from,:$to,:$CURSOR,:$made);
}
method BUILD(:$!orig,:$from,:$to,:$!CURSOR,:$!made) {
$!from = $from // 0; # cannot assign to int in sig
$!to = $to // 0; # cannot assign to int in sig
self;
}
method ast(Match:D:) { $!made }
multi method Str(Match:D:) {
$!to > $!from ?? substr($!orig,$!from,$!to-$!from) !! ''
}
multi method Numeric(Match:D:) {
self.Str.Numeric
}
multi method Bool(Match:D:) {
$!to >= $!from
}
multi method ACCEPTS(Match:D: Any $) { self }
method prematch(Match:D:) {
substr($!orig,0,$!from);
}
method postmatch(Match:D:) {
substr($!orig,$!to)
}
method caps(Match:D:) {
my @caps;
for self.pairs -> $p {
if nqp::istype($p.value,Array) {
@caps.push: $p.key => $_ for $p.value.list
} else {
@caps.push: $p;
}
}
@caps.sort: -> $p { $p.value.from }
}
method chunks(Match:D:) {
my $prev = $!from;
gather {
for self.caps {
if .value.from > $prev {
take '~' => substr($!orig,$prev, .value.from - $prev)
}
take $_;
$prev = .value.to;
}
take '~' => substr($!orig,$prev, $!to - $prev) if $prev < $!to;
}
}
multi method perl(Match:D:) {
my %attrs;
for <orig from to ast list hash> {
%attrs{$_} = self."$_"().perl;
}
'Match.new('
~ %attrs.fmt('%s => %s', ', ')
~ ')'
}
multi method gist (Match:D: $d = 0) {
return "#<failed match>" unless self;
my $s = ' ' x ($d + 1);
my $r = ("=> " if $d) ~ "\x[FF62]{self}\x[FF63]\n";
for @.caps {
$r ~= $s ~ (.key // '?') ~ ' ' ~ .value.gist($d + 1)
}
$d == 0 ?? $r.chomp !! $r;
}
method make(Match:D: Mu \made) {
$!made = made;
nqp::bindattr(
nqp::decont(self.CURSOR),
Cursor,
'$!made',
made
);
}
}
sub make(Mu \made) {
my $slash := nqp::getlexcaller('$/');
nqp::bindattr( nqp::decont($slash), Match, '$!made', made );
nqp::bindattr( nqp::decont($slash.CURSOR), Cursor, '$!made', made );
}
# vim: ft=perl6 expandtab sw=4