-
Notifications
You must be signed in to change notification settings - Fork 20
/
Actions.pm
70 lines (59 loc) · 1.66 KB
/
Actions.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
unit class JSON::Tiny::Actions;
method TOP($/) {
make $<value>.made;
};
method object($/) {
make $<pairlist>.made.hash.item;
}
method pairlist($/) {
make $<pair>>>.made.flat;
}
method pair($/) {
make $<string>.made => $<value>.made;
}
method array($/) {
make $<arraylist>.made.item;
}
method arraylist($/) {
make [$<value>.map(*.made)];
}
method string($/) {
my $str = +@$<str> == 1
?? $<str>[0].made
!! $<str>>>.made.join;
# see https://github.com/moritz/json/issues/25
# when a combining character comes after an opening quote,
# it doesn't become part of the quoted string, because
# it's stuffed into the same grapheme as the quote.
# so we need to extract those combining character(s)
# from the match of the opening quote, and stuff it into the string.
if $0.Str ne '"' {
my @chars := $0.Str.NFC;
$str = @chars[1..*].chrs ~ $str;
}
make $str
}
method value:sym<number>($/) { make +$/.Str }
method value:sym<string>($/) { make $<string>.made }
method value:sym<true>($/) { make Bool::True }
method value:sym<false>($/) { make Bool::False }
method value:sym<null>($/) { make Any }
method value:sym<object>($/) { make $<object>.made }
method value:sym<array>($/) { make $<array>.made }
method str($/) { make ~$/ }
my %h = '\\' => "\\",
'/' => "/",
'b' => "\b",
'n' => "\n",
't' => "\t",
'f' => "\f",
'r' => "\r",
'"' => "\"";
method str_escape($/) {
if $<utf16_codepoint> {
make utf16.new( $<utf16_codepoint>.map({:16(~$_)}) ).decode();
} else {
make %h{~$/};
}
}
# vim: ft=perl6