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