1 import Base 2 import ./lex.bend as Lex 3 4 def 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 19 def 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 23 def 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 26 def 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. 34 def 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 41 def 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`? 49 def closed_by(+t: List<&2, Lex.Tok>, k: U32) -> Bool: 50 U32.is_eq(last.kind(List.last(&2, Lex.Tok, t)), k) 51 52 def 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)