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)
43 | data ByteBounds : Type where
44 | BB : (start, end : BytePos) -> ByteBounds
47 | %runElab derive "ByteBounds" [Show,Eq]
50 | Interpolation ByteBounds where
51 | interpolate (BB s e) = if s == e then "\{s}" else "\{s}--\{e}"
52 | interpolate NoBB = ""
55 | Semigroup ByteBounds where
58 | BB s1 e1 <+> BB s2 e2 = BB (min s1 s2) (max e1 e2)
61 | Monoid ByteBounds where
70 | record ByteBounded ty where
75 | %runElab derive "ByteBounded" [Show,Eq]
78 | fromBytePos : ByteBounded a -> BytePos -> ByteBounded a
79 | fromBytePos (B v $
BB (BP s) (BP e)) (BP p) = B v $
BB (BP $
s+p) (BP $
e+p)
80 | fromBytePos (B v NoBB) p = B v $
BB p p
83 | app : ByteBounded (a -> b) -> ByteBounded a -> ByteBounded b
84 | app (B vf b1) (B va b2) = B (vf va) (b1 <+> b2)
87 | bind : ByteBounded a -> (a -> ByteBounded b) -> ByteBounded b
93 | Functor ByteBounded where
94 | map f (B val bs) = B (f val) bs
97 | Applicative ByteBounded where
98 | pure v = B v neutral
102 | Monad ByteBounded where
106 | Foldable ByteBounded where
107 | foldr c n b = c b.val n
108 | foldl c n b = c n b.val
109 | foldMap f b = f b.val
114 | Traversable ByteBounded where
115 | traverse f (B v bs) = (`B` bs) <$> f v
122 | record PositionMap where
126 | arr : IArray size Position
128 | %runElab derive "PositionMap" [Show]
131 | Eq PositionMap where
132 | PM _ x == PM _ y = heq x y
135 | bytePositionMapFrom : Position -> ByteString -> PositionMap
136 | bytePositionMapFrom p (BS n bv) = PM (S n) $
positionMapFrom p bv
139 | stringPositionMapFrom : Position -> String -> PositionMap
140 | stringPositionMapFrom p = bytePositionMapFrom p . fromString
143 | bytePositionMap : ByteString -> PositionMap
144 | bytePositionMap (BS n bv) = PM (S n) $
positionMap bv
147 | stringPositionMap : String -> PositionMap
148 | stringPositionMap = bytePositionMap . fromString
150 | parameters {auto pm : PositionMap}
152 | position : BytePos -> Maybe Position
155 | Just0 x => Just $
atNat pm.arr n @{x}
156 | Nothing0 => Nothing
159 | toBounds : ByteBounds -> Bounds
160 | toBounds NoBB = NoBounds
161 | toBounds (BB x y) =
162 | let Just px := position x | _ => NoBounds
163 | Just py := position y | _ => NoBounds
167 | toBounded : ByteBounded a -> Bounded a
168 | toBounded (B v bs) = B v $
toBounds bs
171 | 0 BBErr : Type -> Type
172 | BBErr e = ByteBounded (InnerError e)
177 | toParseError : Origin -> String -> BBErr e -> ParseError e
178 | toParseError o s err =
179 | let mp := stringPositionMap s
180 | in toParseError o s (toBounded err)
187 | record ByteContext where
190 | bounds : ByteBounds
192 | %runElab derive "ByteContext" [Show,Eq]
195 | Interpolation ByteContext where
196 | interpolate (BC o NoBB) = interpolate o
197 | interpolate (BC o bs) = "\{o}: \{bs}"
200 | record ByteError e where
203 | bounds : ByteBounds
204 | content : Maybe ByteString
207 | %runElab derive "ByteError" [Show,Eq]
210 | 0 ByteErr : Type -> Type
211 | ByteErr = ByteError . InnerError
214 | byteError : Origin -> ByteBounded e -> ByteError e
215 | byteError o (B err bs) = BE o bs Nothing err
217 | boundsPart : ByteBounds -> String
218 | boundsPart NoBB = ""
219 | boundsPart (BB s e) =
221 | True => ", byte \{s}"
222 | False => ", bytes \{s}--\{e}"
225 | prettyByteErr : Interpolation e => ByteError e -> String
226 | prettyByteErr (BE o bb m err) =
228 | Nothing => "Error at \{o}\{boundsPart bb}: \{err}"
230 | let mp := bytePositionMap bs
231 | in interpolate $
toParseError o (toString bs) (toBounded $
B err bb)
234 | Interpolation e => Interpolation (ByteError e) where
235 | interpolate = prettyByteErr