2 | import Data.ByteString
4 | import Derive.Prelude
8 | %language ElabReflection
11 | data Origin : Type where
12 | FileSrc : (path : String) -> Origin
15 | %runElab derive "Origin" [Show,Eq]
18 | Interpolation Origin where
19 | interpolate (FileSrc p) = p
20 | interpolate Virtual = "virtual"
23 | record FileContext where
28 | public export %inline
29 | fromBounded : Origin -> Bounded a -> (FileContext, a)
30 | fromBounded o (B val bounds) = (FC o bounds, val)
32 | public export %inline
33 | virtualFromBounded : Bounded a -> (FileContext, a)
34 | virtualFromBounded = fromBounded Virtual
36 | %runElab derive "FileContext" [Show,Eq]
39 | Interpolation FileContext where
40 | interpolate (FC o NoBounds) = interpolate o
41 | interpolate (FC o b) = "\{o}: \{b}"
43 | nextRem : Fin 4 -> Bits8 -> Fin 4
45 | if m < 0b1000_0000 then 0
46 | else if m < 0b1110_0000 then 1
47 | else if m < 0b1111_0000 then 2
49 | nextRem (FS x) m = weaken x
54 | toPosition : Nat -> ByteString -> Position
55 | toPosition n (BS x bv) = go 0 0 x 0
60 | go : (l,c : Nat) -> (n : Nat) -> Fin 4 -> (y : Ix n x) => Position
63 | let byte := bv `ix` k
64 | nxt := nextRem rem byte
66 | 0 => case ixToNat y >= n of
68 | False => case byte of
69 | 0x0a => go (l+1) 0 k nxt
70 | _ => go l (c+1) k nxt
73 | range : Nat -> Nat -> List a -> List a
74 | range s e = take ((e `minus` s) + 1) . drop s
76 | lineNumbers : SnocList String -> Nat -> Nat -> List String -> SnocList String
77 | lineNumbers sl _ _ [] = sl
78 | lineNumbers sl size n (h::t) =
80 | pre := padLeft size '0' $
show k
81 | in lineNumbers (sl :< " \{pre} | \{h}") size k t
96 | -> (relBounds : Bounds)
97 | -> (sourceLines : List String)
99 | printFC fc@(FC _ $
BS (P so _) (P eo _)) (BS (P sr sc) (P er ec)) ls =
100 | let nsize := length $
show (eo + 1)
102 | in case sr == er of
104 | lineNumbers [<"",head] nsize so (range sr (min er $
sr+5) ls) <>> []
109 | cemph := max 1 $
ec `minus` sc
110 | emph := indent (nsize + sc + 4) (replicate cemph '^')
112 | begin := so `minus` (er `minus` fr)
113 | in lineNumbers [<"",head] nsize begin (range fr er ls) <>> [emph]
114 | printFC fc _ _ = [interpolate fc]