0 | module Text.TOML.Parser
3 | import Data.SortedMap
4 | import Text.Parse.Manual
5 | import Text.Parse.Syntax
6 | import Text.TOML.Lexer
7 | import Text.TOML.Types
12 | data ElemType : Type where
13 | Table : TableType -> ElemType
14 | Array : ArrayType -> ElemType
17 | 0 ParentType : ElemType -> Type
18 | ParentType (Table _) = TomlTable
19 | ParentType (Array _) = SnocList TomlValue
24 | record PathElem where
27 | parent : ParentType tpe
31 | record TOMLView where
33 | path : SnocList PathElem
34 | cur : Maybe TomlValue
38 | -> (List KeyToken -> TomlParseError)
39 | -> Either (Bounded TomlErr) a
41 | let ks := map key (sx <>> [])
42 | in Left (B (Custom $
f ks) $
concatMap bounds ks)
49 | -> Either (Bounded TomlErr) TOMLView
50 | pth sx [] m = Right $
TV sx m
51 | pth sx (x :: xs) m = case m of
52 | Nothing => pth (sx :< PE (Table None) empty x) xs Nothing
53 | Just (TTbl Inline _) => keyErr sx InlineTableExists
54 | Just (TTbl tag t) => pth (sx :< PE (Table tag) t x) xs (lookup x.key t)
55 | Just (TArr Static _) => keyErr sx StaticArray
56 | Just (TArr tag sv) => case sv of
57 | [<] => pth (sx :< PE (Array tag) [<TTbl None empty] x) xs Nothing
58 | (_ :< TTbl Inline _) => keyErr sx InlineTableExists
59 | (_ :< TTbl tg t) => pth (sx :< PE (Array tag) sv x) xs (lookup x.key t)
60 | _ => keyErr sx ValueExists
61 | Just v => keyErr sx ValueExists
64 | path : List KeyToken -> (root : TomlValue) -> Either (Bounded TomlErr) TOMLView
65 | path xs root = pth [<] xs (Just root)
67 | ins : SnocList PathElem -> TomlValue -> TomlValue
69 | ins (sx :< PE (Table x) t k) v = ins sx (TTbl x $
insert k.key v t)
70 | ins (sx :< PE (Array x) sv k) v = case sv of
71 | sy :< TTbl tag t => ins sx (TArr x $
sy :< (TTbl tag $
insert k.key v t))
72 | _ => ins sx (TArr x sv)
74 | append : SnocList PathElem -> SnocList TomlValue -> TomlValue -> TomlValue
75 | append p sx = ins p . TArr OfTables . (sx :<)
80 | -> (root : TomlValue)
81 | -> Either (Bounded TomlErr) (SnocList PathElem, TomlValue)
82 | tableAt xs root = case path (forget xs) root of
83 | Left err => Left err
84 | Right (TV path Nothing) => Right (path, TTbl Table empty)
85 | Right (TV path (Just $
TTbl None t)) => Right (path, TTbl Table t)
86 | Right (TV path (Just $
TTbl Inline t)) => keyErr path InlineTableExists
87 | Right (TV path (Just $
TTbl Table t)) => keyErr path TableExists
88 | Right (TV path (Just x)) => keyErr path ValueExists
93 | -> (root : TomlValue)
94 | -> Either (Bounded TomlErr) (SnocList PathElem, SnocList TomlValue)
95 | arrayAt xs root = case path (forget xs) root of
96 | Left err => Left err
97 | Right (TV path Nothing) => Right (path, [<])
98 | Right (TV path (Just $
TTbl _ t)) => keyErr path TableExists
99 | Right (TV path (Just $
TArr Static t)) => keyErr path StaticArray
100 | Right (TV path (Just $
TArr OfTables sv)) => Right (path, sv)
101 | Right (TV path (Just x)) => keyErr path ValueExists
106 | -> (val,root : TomlValue)
107 | -> Either (Bounded TomlErr) TomlValue
108 | tryInsert x val root = case path (forget x) root of
110 | Right (TV path Nothing) => Right $
ins path val
111 | Right (TV path _) => keyErr path ValueExists
114 | data TomlItem : Type where
115 | TableName : List1 KeyToken -> TomlItem
116 | ArrayName : List1 KeyToken -> TomlItem
117 | KeyVal : List1 KeyToken -> TomlValue -> TomlItem
119 | toTable : TomlValue -> TomlItem -> AccumRes TomlValue (Bounded TomlErr)
120 | toTable root (KeyVal k v) = either Error Cont $
tryInsert k v root
125 | -> (items : List TomlItem)
126 | -> (0 acc : SuffixAcc items)
127 | -> Either (Bounded TomlErr) TomlValue
128 | assemble top (x :: xs) (SA r) = case x of
130 | let Right t1 := tryInsert k v top | Left err => Left err
131 | Succ0 t2 ys := accumErr t1 id toTable xs | Fail0 err => Left err
132 | in assemble t2 ys r
134 | let Right (p,t) := tableAt k top | Left e => Left e
135 | Succ0 t2 ys := accumErr t (ins p) toTable xs | Fail0 e => Left e
136 | in assemble t2 ys r
138 | let Right (p,sv) := arrayAt k top | Left e => Left e
139 | t := TTbl Table empty
140 | Succ0 t2 ys := accumErr t (append p sv) toTable xs | Fail0 e => Left e
141 | in assemble t2 ys r
142 | assemble top [] _ = Right top
152 | fromString : String -> TomlToken
155 | 0 AccRule : Bool -> Type -> Type
156 | AccRule b = AccGrammar b TomlToken TomlParseError
158 | 0 Rule : Bool -> Type -> Type
159 | Rule b = Grammar b TomlToken TomlParseError
161 | array : Bounds -> SnocList TomlValue -> AccRule True TomlValue
163 | table : Bounds -> TomlValue -> AccRule True TomlValue
165 | value : AccRule True TomlValue
166 | value (B (TVal v) _ :: xs) _ = Succ0 v xs
167 | value (B "[" _ :: B "]" _ :: xs) _ = Succ0 (TArr Static [<]) xs
168 | value (B "{" _ :: B "}" _ :: xs) _ = Succ0 (TTbl Inline empty) xs
169 | value (B "[" b :: xs) (SA r) = succT $
array b [<] xs r
170 | value (B "{" b :: xs) (SA r) = succT $
table b (TTbl None empty) xs r
171 | value xs _ = fail xs
173 | array b sx xs acc@(SA r) = case value xs acc of
174 | Succ0 v (B "," _ :: B "]" _ :: ys) => Succ0 (TArr Static $
sx :< v) ys
175 | Succ0 v (B "," _ :: ys) => succT $
array b (sx :< v) ys r
176 | Succ0 v (B "]" _ :: ys) => Succ0 (TArr Static $
sx :< v) ys
177 | res => failInParen b "[" res
179 | key : Rule True (List1 KeyToken)
180 | key = terminal $
\case TKey x => Just x;
_ => Nothing
182 | keyVal : AccRule True (List1 KeyToken,TomlValue)
183 | keyVal (B (TKey x) _ :: B "=" _ :: xs) (SA r) = (x,) <$> succT (value xs r)
184 | keyVal (B (TKey _) _ :: x :: xs) _ = expected x.bounds "=" "\{x.val}"
185 | keyVal xs _ = fail xs
187 | inline : TomlValue -> TomlValue
188 | inline (TTbl _ y) = TTbl Inline y
191 | table b tbl xs acc@(SA r) = case keyVal xs acc of
192 | Succ0 (bk,v) ys => case fromEither {b = True} ys $
tryInsert bk v tbl of
193 | Succ0 tbl1 (B "," _ :: ys) => succT $
table b tbl1 ys r
194 | Succ0 tbl1 (B "}" _ :: ys) => Succ0 (inline tbl1) ys
195 | res => failInParen b "{" res
196 | res => failInParen b "{" res
198 | item : Rule True TomlItem
199 | item (B "[" b1 :: xs) = TableName <$> succT (before key "]" xs)
200 | item (B "[[" b1 :: xs) = ArrayName <$> succT (before key "]]" xs)
201 | item ts = uncurry KeyVal <$> acc keyVal ts
205 | -> (ts : List $
Bounded TomlToken)
206 | -> (0 acc : SuffixAcc ts)
207 | -> Either (Bounded TomlErr) (List TomlItem)
208 | items sx [] _ = Right $
sx <>> []
209 | items sx (B NL _ :: xs) (SA r) = items sx xs r
210 | items sx xs (SA r) = case item xs of
211 | Succ0 i (B NL _ :: xs) => items (sx :< i) xs r
212 | Succ0 i (x::xs) => unexpected x
213 | Succ0 i [] => Right (sx <>> [i])
214 | Fail0 err => Left err
217 | parse : Origin -> String -> Either (ParseError TomlParseError) TomlValue
218 | parse o s = mapFst (toParseError o s) $
do
220 | ti <- items [<] ts suffixAcc
221 | assemble (TTbl Table empty) ti suffixAcc