-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.kk
118 lines (97 loc) · 2.12 KB
/
json.kk
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
module json
import std/text/parse
import std/num/float64
import util
pub type json
JSONFalse
JSONTrue
JSONNull
JSONNumber(value: float64)
JSONString(value: string)
JSONArray(value: list<json>)
JSONObject(value: list<(string, json)>)
// First let's define some punctuation parsers
fun json-comma()
pstring(",")
fun json-colon()
pstring(":")
fun json-left-bracket()
pstring("[")
fun json-right-bracket()
pstring("]")
fun json-left-brace()
pstring("{")
fun json-right-brace()
pstring("}")
fun json-quote()
pstring("\"")
// Now for the good parts
fun json-null()
pstring("null")
JSONNull
fun json-true()
pstring("true")
JSONTrue
fun json-false()
pstring("false")
JSONFalse
fun json-number()
val s = digits() ++ (optional("") { pstring(".") ++ digits() })
JSONNumber(s.parse-float64.default(0.0))
// TODO: Support escaping
fun json-string()
json-quote()
val s = chars-are("", fn(c) c != '"')
json-quote()
JSONString(s.string)
fun json-key-value()
val key = match json-string()
JSONString(value) -> value
_ -> fail("key must be a string")
whitespace0()
json-colon()
whitespace0()
val value = parse-json()
(key, value)
fun json-object()
json-left-brace()
whitespace0()
val kvs = sep-by(json-comma, {
whitespace0()
val kv = json-key-value()
whitespace0()
kv
})
whitespace0()
json-right-brace()
JSONObject(kvs)
fun json-array()
json-left-bracket()
val values = sep-by(json-comma, {
whitespace0()
val value = parse-json()
whitespace0()
value
})
json-right-bracket()
JSONArray(values)
pub fun parse-json()
choose([
json-null,
json-true,
json-false,
json-number,
json-string,
json-object,
json-array
])
pub fun show-json(json: json) : pure string
match json
JSONFalse -> "false"
JSONTrue -> "true"
JSONNull -> "null"
JSONString(value) -> "\"" ++ value ++ "\""
JSONNumber(value) -> value.show-fixed
JSONArray(value) -> value.show-list(show-json)
JSONObject(kvs) -> "{" ++ kvs.map(fn((k, v)) "\"" ++ k ++ "\":" ++ show-json(v)).join(",") ++ "}"
pub val stringify = show-json