0 | module Text.ByteBounds
2 | import Data.Array.Core
4 | import Data.ByteString
5 | import Derive.Prelude
6 | import public Text.Bounds
7 | import public Text.FC
8 | import public Text.ParseError
11 | %language ElabReflection
19 | record BytePos where
23 | %runElab derive "BytePos" [Show,Eq,Ord,FromInteger]
25 | public export %inline
26 | Interpolation BytePos where
27 | interpolate = show . pos
32 | incLen : Nat -> BytePos -> BytePos
33 | incLen (S n) (BP p) = BP (n+p)
41 | endPos : (from, till : Nat) -> BytePos
43 | case prim__lt_Integer (cast from) (cast till) of
54 | data ByteBounds : Type where
55 | BB : (start, end : BytePos) -> ByteBounds
58 | %runElab derive "ByteBounds" [Show,Eq]
61 | Interpolation ByteBounds where
62 | interpolate (BB s e) = if s == e then "\{s}" else "\{s}--\{e}"
63 | interpolate NoBB = ""
66 | Semigroup ByteBounds where
69 | BB s1 e1 <+> BB s2 e2 = BB (min s1 s2) (max e1 e2)
72 | Monoid ByteBounds where
76 | interface MapBounds (0 a : Type) where
77 | mapBounds : (ByteBounds -> ByteBounds) -> a -> a
80 | clearBounds : MapBounds a => a -> a
81 | clearBounds = mapBounds (const NoBB)
84 | MapBounds ByteBounds where mapBounds = id
87 | MapBounds a => MapBounds (Maybe a) where
88 | mapBounds = map . mapBounds
91 | MapBounds a => MapBounds (List a) where
92 | mapBounds = map . mapBounds
95 | MapBounds a => MapBounds (SnocList a) where
96 | mapBounds = map . mapBounds
99 | MapBounds a => MapBounds b => MapBounds (a,b) where
100 | mapBounds f (x,y) = (mapBounds f x, mapBounds f y)
103 | MapBounds a => MapBounds b => MapBounds (Either a b) where
104 | mapBounds f (Left x) = Left $
mapBounds f x
105 | mapBounds f (Right x) = Right $
mapBounds f x
108 | fromPos : Cast t ByteBounds => BytePos -> t -> ByteBounds
109 | fromPos p x = BB p p <+> cast x
112 | tillPos : Cast t ByteBounds => t -> BytePos -> ByteBounds
113 | tillPos x p = cast x <+> BB p p
116 | Cast BytePos ByteBounds where cast b = BB b b
124 | record ByteBounded ty where
127 | bounds : ByteBounds
129 | %runElab derive "ByteBounded" [Show,Eq]
132 | fromBytePos : ByteBounded a -> BytePos -> ByteBounded a
133 | fromBytePos (B v $
BB (BP s) (BP e)) (BP p) = B v $
BB (BP $
s+p) (BP $
e+p)
134 | fromBytePos (B v NoBB) p = B v $
BB p p
137 | app : ByteBounded (a -> b) -> ByteBounded a -> ByteBounded b
138 | app (B vf b1) (B va b2) = B (vf va) (b1 <+> b2)
141 | bind : ByteBounded a -> (a -> ByteBounded b) -> ByteBounded b
144 | in B vb (b1 <+> b2)
147 | Functor ByteBounded where
148 | map f (B val bs) = B (f val) bs
151 | Applicative ByteBounded where
152 | pure v = B v neutral
156 | Monad ByteBounded where
160 | Foldable ByteBounded where
161 | foldr c n b = c b.val n
162 | foldl c n b = c n b.val
163 | foldMap f b = f b.val
168 | Traversable ByteBounded where
169 | traverse f (B v bs) = (`B` bs) <$> f v
172 | MapBounds (ByteBounded a) where mapBounds f = {bounds $= f}
179 | record PositionMap where
183 | arr : IArray size Position
185 | %runElab derive "PositionMap" [Show]
188 | Eq PositionMap where
189 | PM _ x == PM _ y = heq x y
192 | bytePositionMapFrom : Position -> ByteString -> PositionMap
193 | bytePositionMapFrom p (BS n bv) = PM (S n) $
positionMapFrom p bv
196 | stringPositionMapFrom : Position -> String -> PositionMap
197 | stringPositionMapFrom p = bytePositionMapFrom p . fromString
200 | bytePositionMap : ByteString -> PositionMap
201 | bytePositionMap (BS n bv) = PM (S n) $
positionMap bv
204 | stringPositionMap : String -> PositionMap
205 | stringPositionMap = bytePositionMap . fromString
207 | parameters {auto pm : PositionMap}
209 | position : BytePos -> Maybe Position
212 | Just0 x => Just $
atNat pm.arr n @{x}
213 | Nothing0 => Nothing
216 | toBounds : ByteBounds -> Bounds
217 | toBounds NoBB = NoBounds
218 | toBounds (BB x y) =
219 | let Just px := position x | _ => NoBounds
220 | Just py := position y | _ => NoBounds
224 | toBounded : ByteBounded a -> Bounded a
225 | toBounded (B v bs) = B v $
toBounds bs
228 | 0 BBErr : Type -> Type
229 | BBErr e = ByteBounded (InnerError e)
234 | toParseError : Origin -> String -> BBErr e -> ParseError e
235 | toParseError o s err =
236 | let mp := stringPositionMap s
237 | in toParseError o s (toBounded err)
244 | record ByteContext where
247 | bounds : ByteBounds
249 | %runElab derive "ByteContext" [Show,Eq]
252 | Interpolation ByteContext where
253 | interpolate (BC o NoBB) = interpolate o
254 | interpolate (BC o bs) = "\{o}: \{bs}"
257 | MapBounds ByteContext where mapBounds f = {bounds $= f}
260 | record ByteError e where
263 | bounds : ByteBounds
264 | content : Maybe ByteString
267 | %runElab derive "ByteError" [Show,Eq]
270 | MapBounds (ByteError e) where mapBounds f = {bounds $= f}
273 | 0 ByteErr : Type -> Type
274 | ByteErr = ByteError . InnerError
277 | byteError : Origin -> ByteBounded e -> ByteError e
278 | byteError o (B err bs) = BE o bs Nothing err
280 | boundsPart : ByteBounds -> String
281 | boundsPart NoBB = ""
282 | boundsPart (BB s e) =
284 | True => ", byte \{s}"
285 | False => ", bytes \{s}--\{e}"
288 | prettyByteErr : Interpolation e => ByteError e -> String
289 | prettyByteErr (BE o bb m err) =
291 | Nothing => "Error at \{o}\{boundsPart bb}: \{err}"
293 | let mp := bytePositionMap bs
294 | in interpolate $
toParseError o (toString bs) (toBounded $
B err bb)
297 | Interpolation e => Interpolation (ByteError e) where
298 | interpolate = prettyByteErr