2 | import Data.Array.Core
3 | import Data.Array.Mutable
5 | import Data.ByteString
6 | import Derive.Prelude
10 | %language ElabReflection
19 | record Position where
27 | %runElab derive "Position" [Show,Eq,Ord]
30 | Interpolation Position where
31 | interpolate (P l c) = show (l+1) ++ ":" ++ show (c+1)
39 | Semigroup Position where
40 | P l1 c1 <+> P 0 c2 = P l1 (c1+c2)
41 | P l1 c1 <+> P l2 c2 = P (l1+l2) c2
44 | Monoid Position where
53 | public export %inline
54 | incCol : Position -> Position
59 | public export %inline
60 | incLine : Position -> Position
61 | incLine p = P (S p.line) 0
64 | public export %inline
65 | addCol : Nat -> Position -> Position
66 | addCol n = {col $= (+ n)}
72 | relativeTo : (p2,p1 : Position) -> Position
73 | relativeTo (P l c) (P ls cs) =
74 | if l <= ls then P 0 (c `minus` cs) else P (l `minus` ls) c
83 | incString : String -> Position -> Position
84 | incString s (P l c) = go l c (unpack s)
86 | go : Nat -> Nat -> List Char -> Position
88 | go l c ('\n' :: xs) = go (S l) 0 xs
89 | go l c (x :: xs) = go l (S c) xs
92 | isStartByte : Bits8 -> Bool
93 | isStartByte b = (b .&. 128) == 0 || (b .&. 0b1100_0000) == 0b1100_0000
102 | incByte : Bits8 -> Position -> Position
103 | incByte 0x0a p = incLine p
104 | incByte b p = if isStartByte b then incCol p else p
114 | incBytes : ByteString -> Position -> Position
115 | incBytes (BS n bv) (P l c) = go l c n
117 | go : Nat -> Nat -> (k : Nat) -> (x : Ix k n) => Position
121 | 0x0a => go (S l) 0 k
122 | b => case isStartByte b of
123 | True => go l (S c) k
126 | parameters (bv : ByteVect n)
127 | (m : MArray s (S n) Position)
129 | skip : (k : Nat) -> (ix : Ix k n) => Position -> F1' s
131 | fillMap : (k : Nat) -> (ix : Ix k n) => Position -> F1' s
132 | fillMap 0 p t = () # t
133 | fillMap (S k) p t =
134 | let _ # t := setIx m _ {x = succIx ix} p t
135 | in case ByteVect.ix bv k of
136 | 0x0a => fillMap k (incLine p) t
137 | b => case b < 128 of
138 | True => fillMap k (incCol p) t
139 | False => skip k p t
141 | skip 0 p t = () # t
143 | let _ # t := setIx m _ {x = succIx ix} p t
144 | in if isStartByte (ByteVect.ix bv k)
145 | then fillMap (S k) (incCol p) t
148 | setLast : {n : _} -> MArray s (S n) Position -> F1' s
149 | setLast {n = 0} m t = () # t
150 | setLast {n = S k} m t =
151 | let p # t := Array.Core.get m (weaken last) t
152 | in Array.Core.set m last (incCol p) t
164 | -> IArray (S n) Position
165 | positionMapFrom p bv =
167 | let m # t := marray1 (S n) p t
168 | _ # t := fillMap bv m n p t
169 | _ # t := setLast m t
170 | in unsafeFreeze m t
177 | positionMap : {n : _} -> ByteVect n -> IArray (S n) Position
178 | positionMap = positionMapFrom (P 0 0)
184 | public export %inline
185 | next : Char -> Position -> Position
186 | next '\n' = incLine
196 | data Bounds : Type where
197 | BS : (start, end : Position) -> Bounds
200 | %runElab derive "Bounds" [Show,Eq]
204 | relativeTo : Bounds -> Position -> Bounds
205 | relativeTo NoBounds _ = NoBounds
206 | relativeTo (BS s e) p = BS (s `relativeTo` p) (e `relativeTo` p)
209 | public export %inline
210 | oneChar : Position -> Bounds
211 | oneChar p = BS p $
incCol p
214 | Interpolation Bounds where
215 | interpolate (BS s e) = if s == e then "\{s}" else "\{s}--\{e}"
216 | interpolate NoBounds = ""
219 | Semigroup Bounds where
222 | BS s1 e1 <+> BS s2 e2 = BS (min s1 s2) (max e1 e2)
225 | Monoid Bounds where
234 | record Bounded ty where
239 | %runElab derive "Bounded" [Show,Eq]
243 | bounded : a -> (start,end : Position) -> Bounded a
244 | bounded v s e = B v $
BS s e
247 | public export %inline
248 | oneChar : a -> Position -> Bounded a
249 | oneChar v p = B v $
oneChar p
253 | app : Bounded (a -> b) -> Bounded a -> Bounded b
254 | app (B vf b1) (B va b2) = B (vf va) (b1 <+> b2)
258 | bind : Bounded a -> (a -> Bounded b) -> Bounded b
261 | in B vb (b1 <+> b2)
264 | fromPosition : Bounded a -> Position -> Bounded a
265 | fromPosition (B v $
BS s e) y = B v $
BS (y <+> s) (y <+> e)
266 | fromPosition (B v NoBounds) y = B v $
BS y (incCol y)
269 | Functor Bounded where
270 | map f (B val bs) = B (f val) bs
272 | public export %inline
273 | Applicative Bounded where
274 | pure v = B v neutral
277 | public export %inline
278 | Monad Bounded where
282 | Foldable Bounded where
283 | foldr c n b = c b.val n
284 | foldl c n b = c n b.val
285 | foldMap f b = f b.val
290 | Traversable Bounded where
291 | traverse f (B v bs) = (`B` bs) <$> f v
294 | noBounds : Bounded t -> Bounded t
295 | noBounds = {bounds := NoBounds}