json/scan.bend

cswap-bend-cli@0.1.0.0 · 59 lines · 8 definitions

1import Base
2import cswap-bend-cli@0.1.0.0/json/lex.bend as Lex
3
4def tk.kind(t: Lex.Tok) -> U32:
5  match t:
6    case Lex.TLBrace{}:
7      11
8    case Lex.TLBrack{}:
9      12
10    case Lex.TRBrace{}:
11      21
12    case Lex.TRBrack{}:
13      22
14    case Lex.TComma{}:
15      3
16    case _:
17      0
18
19def depth.next(+k: U32, +d: U32) -> U32:
20  Lex.sel(U32.is_eq(k, 11) || U32.is_eq(k, 12), (d + 1 : U32),
21    Lex.sel(U32.is_eq(k, 21) || U32.is_eq(k, 22), Lex.sel(U32.is_eq(d, 0), 0, (d - 1 : U32)), d))
22
23def stopper(+k: U32, +d: U32) -> Bool:
24  U32.is_eq(d, 0) && (U32.is_eq(k, 3) || U32.is_eq(k, 21) || U32.is_eq(k, 22))
25
26def scan.pick(stop: Bool, rest: Nat) -> Nat:
27  match stop:
28    case True{}:
29      0n
30    case False{}:
31      rest
32
33# Tokens before the first comma or closer at depth 0.
34def scan(toks: List<&2, Lex.Tok>, +d: U32) -> Nat:
35  match toks:
36    case Nil{}:
37      0n
38    case Con{+h, t}:
39      scan.pick(stopper(tk.kind(h), d), 1n+scan(t, depth.next(tk.kind(h), d)))
40
41def last.kind(m: Maybe<&2, Lex.Tok>) -> U32:
42  match m:
43    case None{}:
44      0
45    case Some{t}:
46      tk.kind(t)
47
48# Is the last token of t the closer `k`?
49def closed_by(+t: List<&2, Lex.Tok>, k: U32) -> Bool:
50  U32.is_eq(last.kind(List.last(&2, Lex.Tok, t)), k)
51
52def err.of(toks: List<&2, Lex.Tok>) -> String:
53  match toks:
54    case Nil{}:
55      ""
56    case Con{Lex.TErr{m}, t}:
57      m
58    case Con{h, t}:
59      err.of(t)