0 | module Text.YAML.Types
3 | import Derive.Prelude
4 | import public Text.ParseError
7 | %language ElabReflection
21 | data Style : Type where
37 | %runElab derive "Style" [Show,Eq]
41 | data Tag : Type where
50 | Verbatim : String -> Tag
52 | %runElab derive "Tag" [Show,Eq]
66 | data Event : Type where
69 | DocStart : (explicit : Bool) -> Event
70 | DocEnd : (explicit : Bool) -> Event
71 | SeqStart : (flow : Bool) -> Maybe Anchor -> Tag -> Event
73 | MapStart : (flow : Bool) -> Maybe Anchor -> Tag -> Event
75 | Scalar : Maybe Anchor -> Tag -> Style -> String -> Event
76 | Alias : Anchor -> Event
78 | %runElab derive "Event" [Show,Eq]
84 | escape : SnocList Char -> Char -> SnocList Char
85 | escape sc '\\' = sc :< '\\' :< '\\'
86 | escape sc '\0' = sc :< '\\' :< '0'
87 | escape sc '\b' = sc :< '\\' :< 'b'
88 | escape sc '\n' = sc :< '\\' :< 'n'
89 | escape sc '\r' = sc :< '\\' :< 'r'
90 | escape sc '\t' = sc :< '\\' :< 't'
91 | escape sc c = sc :< c
93 | value : String -> String
94 | value s = pack (foldl escape [<] (unpack s) <>> [])
96 | flow : String -> Bool -> String
97 | flow s True = " " ++ s
100 | anchor : Maybe Anchor -> String
101 | anchor Nothing = ""
102 | anchor (Just a) = " &" ++ a
104 | tag : Tag -> String
106 | tag NonSpec = " <!>"
107 | tag (Verbatim t) = " <" ++ t ++ ">"
109 | sigil : Style -> Char
111 | sigil SingleQ = '\''
112 | sigil DoubleQ = '"'
113 | sigil Literal = '|'
119 | printEvent : Event -> String
120 | printEvent StreamStart = "+STR"
121 | printEvent StreamEnd = "-STR"
122 | printEvent (DocStart True) = "+DOC ---"
123 | printEvent (DocStart False) = "+DOC"
124 | printEvent (DocEnd True) = "-DOC ..."
125 | printEvent (DocEnd False) = "-DOC"
126 | printEvent (SeqStart f a t) = "+SEQ" ++ flow "[]" f ++ anchor a ++ tag t
127 | printEvent SeqEnd = "-SEQ"
128 | printEvent (MapStart f a t) = "+MAP" ++ flow "{}" f ++ anchor a ++ tag t
129 | printEvent MapEnd = "-MAP"
130 | printEvent (Scalar a t s v) =
131 | "=VAL" ++ anchor a ++ tag t ++ " " ++ singleton (sigil s) ++ value v
132 | printEvent (Alias a) = "=ALI *" ++ a
142 | constructor MkProps
143 | anchor : Maybe Anchor
148 | noProps = MkProps Nothing NoTag
151 | isNoProps : Props -> Bool
152 | isNoProps (MkProps Nothing NoTag) = True
153 | isNoProps _ = False
158 | record TagEnv where
160 | handles : List (String, String)
163 | defaultEnv : TagEnv
173 | data YErr : Type where
176 | MultipleAnchors : YErr
177 | MultipleTags : YErr
178 | UnknownHandle : String -> YErr
179 | DuplicateHandle : String -> YErr
180 | BadVersion : String -> YErr
181 | BadDirective : String -> YErr
182 | TrailingContent : YErr
188 | UndefinedAlias : Anchor -> YErr
193 | CyclicAlias : Anchor -> YErr
197 | DuplicateKey : String -> YErr
202 | UnexpectedEvent : String -> YErr
205 | UnexpectedEnd : YErr
207 | %runElab derive "YErr" [Show,Eq]
212 | resolveTag : TagEnv -> (handle, suffix : String) -> Either YErr Tag
213 | resolveTag env h sfx = case lookup h env.handles of
214 | Just pre => Right (Verbatim (pre ++ sfx))
215 | Nothing => case h of
216 | "!" => Right (Verbatim ("!" ++ sfx))
217 | "!!" => Right (Verbatim ("tag:yaml.org,2002:" ++ sfx))
218 | _ => Left (UnknownHandle h)
223 | mergeProps : Props -> Props -> Either YErr Props
224 | mergeProps (MkProps (Just _) _) (MkProps (Just _) _) = Left MultipleAnchors
225 | mergeProps (MkProps a1 NoTag) (MkProps a2 t) = Right (MkProps (a1 <|> a2) t)
226 | mergeProps (MkProps a1 t) (MkProps a2 NoTag) = Right (MkProps (a1 <|> a2) t)
227 | mergeProps _ _ = Left MultipleTags
230 | Interpolation YErr where
231 | interpolate TabIndent = "tab character used for indentation"
232 | interpolate BadIndent = "wrong indentation"
233 | interpolate MultipleAnchors = "more than one anchor for the same node"
234 | interpolate MultipleTags = "more than one tag for the same node"
235 | interpolate (UnknownHandle h) = "unknown tag handle: \{h}"
236 | interpolate (DuplicateHandle h) = "duplicate tag handle: \{h}"
237 | interpolate (BadVersion v) = "unsupported YAML version: \{v}"
238 | interpolate (BadDirective d) = "invalid directive: \{d}"
239 | interpolate TrailingContent = "content not allowed after document end"
240 | interpolate InvalidKey = "invalid mapping key"
241 | interpolate (UndefinedAlias a) = "undefined alias: *\{a}"
242 | interpolate (CyclicAlias a) = "alias *\{a} refers to its own ancestor"
243 | interpolate (DuplicateKey k) = "duplicate mapping key: \{k}"
244 | interpolate (UnexpectedEvent e) = "unexpected event: \{e}"
245 | interpolate UnexpectedEnd = "unexpected end of events"