src/rep.bend
bend-toon-codec@0.1.0.0 · 113 lines · 14 definitions
1import Base
2
3
4
5
6
7
8
9type Ln is Data:
10 Ln{d: U32, t: String}
11
12type Rep is Data:
13
14 RPrim{t: String}
15
16 RLines{ls: List<&2, Ln>}
17
18
19 RArr{h: String, ks: List<&2, Ln>}
20
21 REmpty{}
22
23def shift(+ls: List<&2, Ln>) -> List<&2, Ln>:
24 match ls:
25 case Nil{}:
26 Nil{}
27 case Con{Ln{d, t}, rest}:
28 Con{Ln{(d + 1 : U32), t}, shift(rest)}
29
30def lines.of(+r: Rep) -> List<&2, Ln>:
31 match r:
32 case RLines{ls}:
33 ls
34 case _:
35 Nil{}
36
37def cat(+a: List<&2, Ln>, +b: List<&2, Ln>) -> List<&2, Ln>:
38 match a:
39 case Nil{}:
40 b
41 case Con{h, t}:
42 Con{h, cat(t, b)}
43
44def one(+d: U32, +t: String) -> List<&2, Ln>:
45 Con{Ln{d, t}, Nil{}}
46
47
48def field(+k: String, +r: Rep) -> List<&2, Ln>:
49 match r:
50 case RPrim{t}:
51 one(0, k ++ ": " ++ t)
52 case RLines{ls}:
53 Con{Ln{0, k ++ ":"}, shift(ls)}
54 case RArr{h, ks}:
55 Con{Ln{0, k ++ h}, ks}
56 case REmpty{}:
57 one(0, k ++ ": []")
58
59
60
61def item.obj(+ls: List<&2, Ln>) -> List<&2, Ln>:
62 match ls:
63 case Nil{}:
64 one(0, "-")
65 case Con{Ln{d, t}, rest}:
66 Con{Ln{0, "- " ++ t}, shift(rest)}
67
68
69def item(+r: Rep) -> List<&2, Ln>:
70 match r:
71 case RPrim{t}:
72 one(0, "- " ++ t)
73 case RLines{ls}:
74 item.obj(ls)
75 case RArr{h, ks}:
76 Con{Ln{0, "- " ++ h}, ks}
77 case REmpty{}:
78 one(0, "- [0]:")
79
80
81def root(+r: Rep) -> List<&2, Ln>:
82 match r:
83 case RPrim{t}:
84 one(0, t)
85 case RLines{ls}:
86 ls
87 case RArr{h, ks}:
88 Con{Ln{0, h}, ks}
89 case REmpty{}:
90 one(0, "[]")
91
92def indent.of(+size: U32, +d: U32) -> String:
93 String.repeat(" ", U32.to_nat((size * d : U32)))
94
95def render.line(+size: U32, +l: Ln) -> String:
96 match l:
97 case Ln{d, t}:
98 indent.of(size, d) ++ t
99
100def render.tail(+size: U32, +ls: List<&2, Ln>) -> String:
101 match ls:
102 case Nil{}:
103 ""
104 case Con{l, rest}:
105 "\n" ++ render.line(size, l) ++ render.tail(size, rest)
106
107
108def render(+size: U32, +ls: List<&2, Ln>) -> String:
109 match ls:
110 case Nil{}:
111 ""
112 case Con{l, rest}:
113 render.line(size, l) ++ render.tail(size, rest)