token.bend
yaml-for-bend@0.1.0.0 · 94 lines · 0 definitions
1# The pieces the scanner hands the parser, and the errors both report.
2
3import Base
4
5# A place in the text: the line and column (each from 0, a column counted in
6# characters) and the character's index from the start.
7type Mark is Data:
8 Mark{line: Nat, col: Nat, idx: Nat}
9
10# How a scalar was written.
11type Style is Data:
12 Plain{}
13 Single{}
14 Double{}
15 Literal{}
16 Folded{}
17
18# A token, as libyaml names them. A scanner error ends the tokens with Broken.
19type Tok is Data:
20 StreamStart{}
21 StreamEnd{}
22 VersionDir{major: Nat, minor: Nat}
23 TagDir{handle: String, prefix: String}
24 DocStart{}
25 DocEnd{}
26 BSeqStart{}
27 BMapStart{}
28 BEnd{}
29 FSeqStart{}
30 FSeqEnd{}
31 FMapStart{}
32 FMapEnd{}
33 BEntry{}
34 FEntry{}
35 KeyTok{}
36 ValueTok{}
37 AliasTok{name: String}
38 AnchorTok{name: String}
39 TagTok{handle: String, suffix: String}
40 ScalarTok{text: String, style: Style}
41 Broken{error: Error}
42
43type Token is Data:
44 Token{tok: Tok, start: Mark, end: Mark}
45
46# Why a text didn't load: it isn't YAML, or it is but the schema can't
47# load it (a bad !!int, an unknown alias, a repeated key).
48type Cause is Data:
49 Syntax{}
50 Content{}
51
52# What went wrong, where, and why. A syntax error reads as a problem and
53# what was being read: "did not find expected key while parsing a block
54# mapping".
55type Error is Data:
56 Error{why: String, at: Mark, cause: Cause}
57
58def mark.line(m: Mark) -> Nat:
59 match m:
60 case Mark{line, col, idx}:
61 line
62
63def mark.col(m: Mark) -> Nat:
64 match m:
65 case Mark{line, col, idx}:
66 col
67
68def mark.idx(m: Mark) -> Nat:
69 match m:
70 case Mark{line, col, idx}:
71 idx
72
73# "at line 2 column 5", counting from 1.
74def mark.show(m: Mark) -> String:
75 match m:
76 case Mark{line, col, idx}:
77 "line " ++ Nat.show(1n+line) ++ " column " ++ Nat.show(1n+col)
78
79# The error as one line: "mapping values are not allowed in this context at
80# line 1 column 5".
81def error.show(e: Error) -> String:
82 match e:
83 case Error{why, at, cause}:
84 why ++ " at " ++ mark.show(at)
85
86def error.why(e: Error) -> String:
87 match e:
88 case Error{why, at, cause}:
89 why
90
91def error.at(e: Error) -> Mark:
92 match e:
93 case Error{why, at, cause}:
94 at