parse.bend

bend-scanner@0.1.0.0 · 180 lines · 25 definitions

1import Base
2
3type Parse.Cur is Data:
4  Cur{rest: String, off: Nat}
5
6type Parse.Error is Data:
7  Unexpected{offset: Nat, char: Char}
8  Eof{offset: Nat}
9  Overflow{offset: Nat}
10  Extra{offset: Nat, char: Char}
11
12type Parse.St is Data:
13  StOk{}
14  StBad{c: Char}
15  StOv{}
16
17type Parse.Dec is Data:
18  Dec{value: U32, cur: Parse.Cur}
19
20def Parse.start(text: String) -> Parse.Cur:
21  Cur{text, 0n}
22
23def Parse.peek.s(s: String) -> Maybe<&2, Char>:
24  match s:
25    case SNil{}:
26      None{}
27    case SCon{+h, _}:
28      Some{h}
29
30def Parse.peek(cur: Parse.Cur) -> Maybe<&2, Char>:
31  match cur:
32    case Cur{rest, _}:
33      Parse.peek.s(rest)
34
35def Parse.expect_char.eq(
36  t: String, off: Nat, h: Char, eq: Bool
37) -> Result<&2, &2, Parse.Error, Parse.Cur>:
38  match eq:
39    case True{}:
40      Done{Cur{t, 1n+off}}
41    case False{}:
42      Fail{Unexpected{off, h}}
43
44def Parse.expect_char.s(
45  s: String, off: Nat, +want: Char
46) -> Result<&2, &2, Parse.Error, Parse.Cur>:
47  match s:
48    case SNil{}:
49      Fail{Eof{off}}
50    case SCon{+h, t}:
51      Parse.expect_char.eq(t, off, h, Char.is_eq(h, want))
52
53def Parse.expect_char(
54  cur: Parse.Cur, +want: Char
55) -> Result<&2, &2, Parse.Error, Parse.Cur>:
56  match cur:
57    case Cur{rest, off}:
58      Parse.expect_char.s(rest, off, want)
59
60def Parse.expect_literal.go(
61  s: String, p: String, eq: Bool, h: Char, off: Nat
62) -> Result<&2, &2, Parse.Error, Parse.Cur>:
63  match s p eq:
64    case _ _ False{}:
65      Fail{Unexpected{off, h}}
66    case _ SNil{} True{}:
67      Done{Cur{s, 1n+off}}
68    case SNil{} SCon{_, _} True{}:
69      Fail{Eof{1n+off}}
70    case SCon{+h2, t} SCon{ph, pt} True{}:
71      Parse.expect_literal.go(t, pt, Char.is_eq(h2, ph), h2, 1n+off)
72
73def Parse.expect_literal.start(
74  s: String, p: String, off: Nat
75) -> Result<&2, &2, Parse.Error, Parse.Cur>:
76  match s p:
77    case _ SNil{}:
78      Done{Cur{s, off}}
79    case SNil{} SCon{_, _}:
80      Fail{Eof{off}}
81    case SCon{+h, t} SCon{ph, pt}:
82      Parse.expect_literal.go(t, pt, Char.is_eq(h, ph), h, off)
83
84def Parse.expect_literal(
85  cur: Parse.Cur, pat: String
86) -> Result<&2, &2, Parse.Error, Parse.Cur>:
87  match cur:
88    case Cur{rest, off}:
89      Parse.expect_literal.start(rest, pat, off)
90
91def Parse.ascii_digit.val(
92  +h: Char, t: String, off: Nat, dig: Bool
93) -> Result<&2, &2, Parse.Error, Parse.Dec>:
94  match dig:
95    case False{}:
96      Fail{Unexpected{off, h}}
97    case True{}:
98      Done{Dec{(Char.to_u32(h) - Char.to_u32('0') : U32), Cur{t, 1n+off}}}
99
100def Parse.ascii_digit.s(
101  s: String, off: Nat
102) -> Result<&2, &2, Parse.Error, Parse.Dec>:
103  match s:
104    case SNil{}:
105      Fail{Eof{off}}
106    case SCon{+h, t}:
107      Parse.ascii_digit.val(h, t, off, Char.is_digit(h))
108
109def Parse.ascii_digit(
110  cur: Parse.Cur
111) -> Result<&2, &2, Parse.Error, Parse.Dec>:
112  match cur:
113    case Cur{rest, off}:
114      Parse.ascii_digit.s(rest, off)
115
116def Parse.acc.ok(+acc: U32, +d: U32, +max: U32) -> Bool:
117  Nat.is_le(Nat.add(Nat.mul(U32.to_nat(acc), 10n), U32.to_nat(d)), U32.to_nat(max))
118
119def Parse.nacc(+acc: U32, +h: Char) -> U32:
120  U32.add(U32.mul(acc, 10), (Char.to_u32(h) - Char.to_u32('0') : U32))
121
122def Parse.st.ov(+acc: U32, +d: U32, +max: U32, ok: Bool) -> Parse.St:
123  match ok:
124    case False{}:
125      StOv{}
126    case True{}:
127      StOk{}
128
129def Parse.st.of2(+acc: U32, +h: Char, +max: U32, dig: Bool) -> Parse.St:
130  match dig:
131    case False{}:
132      StBad{h}
133    case True{}:
134      Parse.st.ov(
135        acc, (Char.to_u32(h) - Char.to_u32('0') : U32), max,
136        Parse.acc.ok(acc, (Char.to_u32(h) - Char.to_u32('0') : U32), max)
137      )
138
139def Parse.st.of(+acc: U32, +h: Char, +max: U32) -> Parse.St:
140  Parse.st.of2(acc, h, max, Char.is_digit(h))
141
142def Parse.read_fixed.go(
143  s: String, n: Nat, +acc: U32, off: Nat, st: Parse.St, +max: U32
144) -> Result<&2, &2, Parse.Error, Parse.Dec>:
145  match s n st:
146    case _ _ StBad{c}:
147      Fail{Unexpected{off, c}}
148    case _ _ StOv{}:
149      Fail{Overflow{off}}
150    case _ 0n StOk{}:
151      Done{Dec{acc, Cur{s, off}}}
152    case SNil{} 1n++p StOk{}:
153      Fail{Eof{off}}
154    case SCon{+h, t} 1n++p StOk{}:
155      Parse.read_fixed.go(
156        t, p, Parse.nacc(acc, h), 1n+off, Parse.st.of(acc, h, max), max
157      )
158
159def Parse.read_fixed_decimal(
160  cur: Parse.Cur, count: Nat, max: U32
161) -> Result<&2, &2, Parse.Error, Parse.Dec>:
162  match cur:
163    case Cur{rest, off}:
164      Parse.read_fixed.go(rest, count, 0, off, StOk{}, max)
165
166def Parse.finish.s(
167  s: String, off: Nat
168) -> Result<&2, &2, Parse.Error, Unit>:
169  match s:
170    case SNil{}:
171      Done{Unit{}}
172    case SCon{h, _}:
173      Fail{Extra{off, h}}
174
175def Parse.finish(
176  cur: Parse.Cur
177) -> Result<&2, &2, Parse.Error, Unit>:
178  match cur:
179    case Cur{rest, off}:
180      Parse.finish.s(rest, off)