json/quote.bend
cswap-bend-cli@0.1.0.0 · 61 lines · 12 definitions
1import Base
2import cswap-bend-cli@0.1.0.0/json/lex.bend as Lex
3
4def hexd(+n: U32) -> Char:
5 Chr{Lex.sel(U32.is_lt(n, 10), (n + 48 : U32), (n + 87 : U32))}
6
7
8def uesc(+n: U32) -> String:
9 "\\u" ++ SCon{hexd(((n >> 12n) .&. 15 : U32)), SCon{hexd(((n >> 8n) .&. 15 : U32)), SCon{hexd(((n >> 4n) .&. 15 : U32)), SCon{hexd((n .&. 15 : U32)), SNil{}}}}}
10
11def uesc.pair(+c: U32) -> String:
12 uesc((55296 + ((c - 65536) >> 10n) : U32)) ++ uesc((56320 + ((c - 65536) .&. 1023) : U32))
13
14def esc.high(ascii: Bool, +c: U32) -> String:
15 match ascii:
16 case False{}:
17 SCon{Chr{c}, SNil{}}
18 case True{}:
19 Lex.sel.s(U32.is_lt(c, 65536), uesc(c), uesc.pair(c))
20
21def esc.rest(ascii: Bool, +c: U32) -> String:
22 Lex.sel.s(U32.is_lt(c, 32), uesc(c),
23 Lex.sel.s(U32.is_lt(c, 127), SCon{Chr{c}, SNil{}}, esc.high(ascii, c)))
24
25
26
27def esc.char(+ascii: Bool, +c: U32) -> String:
28 Lex.sel.s(U32.is_eq(c, 34), "\\\"",
29 Lex.sel.s(U32.is_eq(c, 92), "\\\\",
30 Lex.sel.s(U32.is_eq(c, 10), "\\n",
31 Lex.sel.s(U32.is_eq(c, 13), "\\r",
32 Lex.sel.s(U32.is_eq(c, 9), "\\t",
33 Lex.sel.s(U32.is_eq(c, 8), "\\b",
34 Lex.sel.s(U32.is_eq(c, 12), "\\f",
35 Lex.sel.s(U32.is_eq(c, 127), Lex.sel.s(ascii, uesc(127), SCon{Chr{127}, SNil{}}), esc.rest(ascii, c)))))))))
36
37def quote.body(s: String, +ascii: Bool) -> String:
38 match s:
39 case SNil{}:
40 SNil{}
41 case SCon{Chr{c}, t}:
42 esc.char(ascii, c) ++ quote.body(t, ascii)
43
44
45def quote(s: String, ascii: Bool) -> String:
46 "\"" ++ quote.body(s, ascii) ++ "\""
47
48
49def indent(d: Nat) -> String:
50 String.repeat(" ", d)
51
52def nl(style: U32, d: Nat) -> String:
53 Lex.sel.s(U32.is_eq(style, 2), "\n" ++ indent(d), "")
54
55def sep(+style: U32, d: Nat) -> String:
56 Lex.sel.s(U32.is_eq(style, 0), ",", Lex.sel.s(U32.is_eq(style, 1), ", ", ",\n" ++ indent(d)))
57
58def colon(+style: U32) -> String:
59 Lex.sel.s(U32.is_eq(style, 0), ":", ": ")
60
61