{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module Language.Haskell.Liquid.UX.ACSS (
hscolour
, hsannot
, AnnMap (..)
, breakS
, srcModuleName
, Status (..)
, tokeniseWithLoc
) where
import Prelude hiding (error)
import qualified Liquid.GHC.API as SrcLoc
import Language.Haskell.HsColour.Anchors
import Language.Haskell.HsColour.Classify as Classify
import Language.Haskell.HsColour.HTML (renderAnchors, escape)
import qualified Language.Haskell.HsColour.CSS as CSS
import Data.Either (partitionEithers)
import Data.Maybe (fromMaybe)
import qualified Data.HashMap.Strict as M
import Data.List (find, isPrefixOf, findIndex, elemIndices, intercalate, elemIndex)
import Data.Char (isSpace)
import Text.Printf
import Language.Haskell.Liquid.GHC.Misc
import Language.Haskell.Liquid.Types.Errors (panic, impossible)
data AnnMap = Ann
{ AnnMap -> HashMap Loc ([Char], [Char])
types :: M.HashMap Loc (String, String)
, AnnMap -> [(Loc, Loc, [Char])]
errors :: [(Loc, Loc, String)]
, AnnMap -> Status
status :: !Status
, AnnMap -> [(RealSrcSpan, ([Char], [Char]))]
sptypes :: ![(SrcLoc.RealSrcSpan, (String, String)) ]
}
data Status = Safe | Unsafe | Error | Crash
deriving (Status -> Status -> Bool
(Status -> Status -> Bool)
-> (Status -> Status -> Bool) -> Eq Status
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Status -> Status -> Bool
== :: Status -> Status -> Bool
$c/= :: Status -> Status -> Bool
/= :: Status -> Status -> Bool
Eq, Eq Status
Eq Status =>
(Status -> Status -> Ordering)
-> (Status -> Status -> Bool)
-> (Status -> Status -> Bool)
-> (Status -> Status -> Bool)
-> (Status -> Status -> Bool)
-> (Status -> Status -> Status)
-> (Status -> Status -> Status)
-> Ord Status
Status -> Status -> Bool
Status -> Status -> Ordering
Status -> Status -> Status
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Status -> Status -> Ordering
compare :: Status -> Status -> Ordering
$c< :: Status -> Status -> Bool
< :: Status -> Status -> Bool
$c<= :: Status -> Status -> Bool
<= :: Status -> Status -> Bool
$c> :: Status -> Status -> Bool
> :: Status -> Status -> Bool
$c>= :: Status -> Status -> Bool
>= :: Status -> Status -> Bool
$cmax :: Status -> Status -> Status
max :: Status -> Status -> Status
$cmin :: Status -> Status -> Status
min :: Status -> Status -> Status
Ord, Int -> Status -> ShowS
[Status] -> ShowS
Status -> [Char]
(Int -> Status -> ShowS)
-> (Status -> [Char]) -> ([Status] -> ShowS) -> Show Status
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Status -> ShowS
showsPrec :: Int -> Status -> ShowS
$cshow :: Status -> [Char]
show :: Status -> [Char]
$cshowList :: [Status] -> ShowS
showList :: [Status] -> ShowS
Show)
data Annotation = A {
Annotation -> Maybe [Char]
typ :: Maybe String
, Annotation -> Maybe [Char]
err :: Maybe String
, Annotation -> Maybe (Int, Int)
lin :: Maybe (Int, Int)
} deriving (Int -> Annotation -> ShowS
[Annotation] -> ShowS
Annotation -> [Char]
(Int -> Annotation -> ShowS)
-> (Annotation -> [Char])
-> ([Annotation] -> ShowS)
-> Show Annotation
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Annotation -> ShowS
showsPrec :: Int -> Annotation -> ShowS
$cshow :: Annotation -> [Char]
show :: Annotation -> [Char]
$cshowList :: [Annotation] -> ShowS
showList :: [Annotation] -> ShowS
Show)
hscolour :: Bool
-> Bool
-> String
-> String
hscolour :: Bool -> Bool -> ShowS
hscolour Bool
anchor Bool
lhs = Bool -> CommentTransform -> Bool -> ([Char], AnnMap) -> [Char]
hsannot Bool
anchor CommentTransform
forall a. Maybe a
Nothing Bool
lhs (([Char], AnnMap) -> [Char])
-> ([Char] -> ([Char], AnnMap)) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> ([Char], AnnMap)
splitSrcAndAnns
type = Maybe (String -> [(TokenType, String)])
hsannot :: Bool
-> CommentTransform
-> Bool
-> (String, AnnMap)
-> String
hsannot :: Bool -> CommentTransform -> Bool -> ([Char], AnnMap) -> [Char]
hsannot Bool
anchor CommentTransform
tx Bool
False ([Char], AnnMap)
z = Maybe Loc -> Bool -> CommentTransform -> ([Char], AnnMap) -> [Char]
hsannot' Maybe Loc
forall a. Maybe a
Nothing Bool
anchor CommentTransform
tx ([Char], AnnMap)
z
hsannot Bool
anchor CommentTransform
tx Bool
True ([Char]
s, AnnMap
m) = ((Lit, Loc) -> [Char]) -> [(Lit, Loc)] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Lit, Loc) -> [Char]
chunk ([(Lit, Loc)] -> [Char]) -> [(Lit, Loc)] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Lit] -> [(Lit, Loc)]
litSpans ([Lit] -> [(Lit, Loc)]) -> [Lit] -> [(Lit, Loc)]
forall a b. (a -> b) -> a -> b
$ [Lit] -> [Lit]
joinL ([Lit] -> [Lit]) -> [Lit] -> [Lit]
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Lit]
classify ([[Char]] -> [Lit]) -> [[Char]] -> [Lit]
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]]
inlines [Char]
s
where chunk :: (Lit, Loc) -> [Char]
chunk (Code [Char]
c, Loc
l) = Maybe Loc -> Bool -> CommentTransform -> ([Char], AnnMap) -> [Char]
hsannot' (Loc -> Maybe Loc
forall a. a -> Maybe a
Just Loc
l) Bool
anchor CommentTransform
tx ([Char]
c, AnnMap
m)
chunk (Lit [Char]
c , Loc
_) = [Char]
c
litSpans :: [Lit] -> [(Lit, Loc)]
litSpans :: [Lit] -> [(Lit, Loc)]
litSpans [Lit]
lits = [Lit] -> [Loc] -> [(Lit, Loc)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Lit]
lits ([Loc] -> [(Lit, Loc)]) -> [Loc] -> [(Lit, Loc)]
forall a b. (a -> b) -> a -> b
$ [Lit] -> [Loc]
spans [Lit]
lits
where spans :: [Lit] -> [Loc]
spans = Maybe Loc -> [[Char]] -> [Loc]
tokenSpans Maybe Loc
forall a. Maybe a
Nothing ([[Char]] -> [Loc]) -> ([Lit] -> [[Char]]) -> [Lit] -> [Loc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Lit -> [Char]) -> [Lit] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Lit -> [Char]
unL
hsannot' :: Maybe Loc
-> Bool -> CommentTransform -> (String, AnnMap) -> String
hsannot' :: Maybe Loc -> Bool -> CommentTransform -> ([Char], AnnMap) -> [Char]
hsannot' Maybe Loc
baseLoc Bool
anchor CommentTransform
tx =
ShowS
CSS.pre
ShowS -> (([Char], AnnMap) -> [Char]) -> ([Char], AnnMap) -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Bool
anchor then (Either [Char] (TokenType, [Char], Annotation) -> [Char])
-> [Either [Char] (TokenType, [Char], Annotation)] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((TokenType, [Char], Annotation) -> [Char])
-> Either [Char] (TokenType, [Char], Annotation) -> [Char]
forall a. (a -> [Char]) -> Either [Char] a -> [Char]
renderAnchors (TokenType, [Char], Annotation) -> [Char]
renderAnnotToken)
([Either [Char] (TokenType, [Char], Annotation)] -> [Char])
-> ([(TokenType, [Char], Annotation)]
-> [Either [Char] (TokenType, [Char], Annotation)])
-> [(TokenType, [Char], Annotation)]
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(TokenType, [Char], Annotation)]
-> [Either [Char] (TokenType, [Char], Annotation)]
forall a.
[(TokenType, [Char], a)] -> [Either [Char] (TokenType, [Char], a)]
insertAnnotAnchors
else ((TokenType, [Char], Annotation) -> [Char])
-> [(TokenType, [Char], Annotation)] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (TokenType, [Char], Annotation) -> [Char]
renderAnnotToken)
([(TokenType, [Char], Annotation)] -> [Char])
-> (([Char], AnnMap) -> [(TokenType, [Char], Annotation)])
-> ([Char], AnnMap)
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Loc
-> CommentTransform
-> ([Char], AnnMap)
-> [(TokenType, [Char], Annotation)]
annotTokenise Maybe Loc
baseLoc CommentTransform
tx
tokeniseWithLoc :: CommentTransform -> String -> [(TokenType, String, Loc)]
tokeniseWithLoc :: CommentTransform -> [Char] -> [(TokenType, [Char], Loc)]
tokeniseWithLoc CommentTransform
tx [Char]
str = ((TokenType, [Char]) -> Loc -> (TokenType, [Char], Loc))
-> [(TokenType, [Char])] -> [Loc] -> [(TokenType, [Char], Loc)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(TokenType
x,[Char]
y) Loc
z -> (TokenType
x, [Char]
y, Loc
z)) [(TokenType, [Char])]
toks [Loc]
spans
where
toks :: [(TokenType, [Char])]
toks = CommentTransform -> [Char] -> [(TokenType, [Char])]
tokeniseWithCommentTransform CommentTransform
tx [Char]
str
spans :: [Loc]
spans = Maybe Loc -> [[Char]] -> [Loc]
tokenSpans Maybe Loc
forall a. Maybe a
Nothing ([[Char]] -> [Loc]) -> [[Char]] -> [Loc]
forall a b. (a -> b) -> a -> b
$ ((TokenType, [Char]) -> [Char])
-> [(TokenType, [Char])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (TokenType, [Char]) -> [Char]
forall a b. (a, b) -> b
snd [(TokenType, [Char])]
toks
annotTokenise :: Maybe Loc -> CommentTransform -> (String, AnnMap) -> [(TokenType, String, Annotation)]
annotTokenise :: Maybe Loc
-> CommentTransform
-> ([Char], AnnMap)
-> [(TokenType, [Char], Annotation)]
annotTokenise Maybe Loc
baseLoc CommentTransform
tx ([Char]
src, AnnMap
annm) = ((TokenType, [Char])
-> Annotation -> (TokenType, [Char], Annotation))
-> [(TokenType, [Char])]
-> [Annotation]
-> [(TokenType, [Char], Annotation)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(TokenType
x,[Char]
y) Annotation
z -> (TokenType
x,[Char]
y,Annotation
z)) [(TokenType, [Char])]
toks [Annotation]
annots
where
toks :: [(TokenType, [Char])]
toks = CommentTransform -> [Char] -> [(TokenType, [Char])]
tokeniseWithCommentTransform CommentTransform
tx [Char]
src
spans :: [Loc]
spans = Maybe Loc -> [[Char]] -> [Loc]
tokenSpans Maybe Loc
baseLoc ([[Char]] -> [Loc]) -> [[Char]] -> [Loc]
forall a b. (a -> b) -> a -> b
$ ((TokenType, [Char]) -> [Char])
-> [(TokenType, [Char])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (TokenType, [Char]) -> [Char]
forall a b. (a, b) -> b
snd [(TokenType, [Char])]
toks
annots :: [Annotation]
annots = (Loc -> Annotation) -> [Loc] -> [Annotation]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> AnnMap -> Loc -> Annotation
spanAnnot Int
linWidth AnnMap
annm) [Loc]
spans
linWidth :: Int
linWidth = [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show (Int -> [Char]) -> Int -> [Char]
forall a b. (a -> b) -> a -> b
$ [[Char]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[Char]] -> Int) -> [[Char]] -> Int
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]]
lines [Char]
src
spanAnnot :: Int -> AnnMap -> Loc -> Annotation
spanAnnot :: Int -> AnnMap -> Loc -> Annotation
spanAnnot Int
w (Ann HashMap Loc ([Char], [Char])
ts [(Loc, Loc, [Char])]
es Status
_ [(RealSrcSpan, ([Char], [Char]))]
_) Loc
loc = Maybe [Char] -> Maybe [Char] -> Maybe (Int, Int) -> Annotation
A Maybe [Char]
t Maybe [Char]
e Maybe (Int, Int)
b
where
t :: Maybe [Char]
t = (([Char], [Char]) -> [Char])
-> Maybe ([Char], [Char]) -> Maybe [Char]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char], [Char]) -> [Char]
forall a b. (a, b) -> b
snd (Loc -> HashMap Loc ([Char], [Char]) -> Maybe ([Char], [Char])
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Loc
loc HashMap Loc ([Char], [Char])
ts)
e :: Maybe [Char]
e = [Char]
"ERROR" [Char] -> Maybe (Loc, Loc) -> Maybe [Char]
forall a b. a -> Maybe b -> Maybe a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ((Loc, Loc) -> Bool) -> [(Loc, Loc)] -> Maybe (Loc, Loc)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (Loc
loc Loc -> (Loc, Loc) -> Bool
`inRange`) [(Loc
x,Loc
y) | (Loc
x,Loc
y,[Char]
_) <- [(Loc, Loc, [Char])]
es]
b :: Maybe (Int, Int)
b = Int -> Loc -> Maybe (Int, Int)
forall t. t -> Loc -> Maybe (Int, t)
spanLine Int
w Loc
loc
spanLine :: t -> Loc -> Maybe (Int, t)
spanLine :: forall t. t -> Loc -> Maybe (Int, t)
spanLine t
w (L (Int
l, Int
c))
| Int
c Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = (Int, t) -> Maybe (Int, t)
forall a. a -> Maybe a
Just (Int
l, t
w)
| Bool
otherwise = Maybe (Int, t)
forall a. Maybe a
Nothing
inRange :: Loc -> (Loc, Loc) -> Bool
inRange :: Loc -> (Loc, Loc) -> Bool
inRange (L (Int
l0, Int
c0)) (L (Int
l, Int
c), L (Int
l', Int
c'))
= Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l0 Bool -> Bool -> Bool
&& Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
c0 Bool -> Bool -> Bool
&& Int
l0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l' Bool -> Bool -> Bool
&& Int
c0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
c'
tokeniseWithCommentTransform :: Maybe (String -> [(TokenType, String)]) -> String -> [(TokenType, String)]
CommentTransform
Nothing = [Char] -> [(TokenType, [Char])]
tokenise
tokeniseWithCommentTransform (Just [Char] -> [(TokenType, [Char])]
g) = ((TokenType, [Char]) -> [(TokenType, [Char])])
-> [(TokenType, [Char])] -> [(TokenType, [Char])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([Char] -> [(TokenType, [Char])])
-> (TokenType, [Char]) -> [(TokenType, [Char])]
forall {t}.
(t -> [(TokenType, t)]) -> (TokenType, t) -> [(TokenType, t)]
expand [Char] -> [(TokenType, [Char])]
g) ([(TokenType, [Char])] -> [(TokenType, [Char])])
-> ([Char] -> [(TokenType, [Char])])
-> [Char]
-> [(TokenType, [Char])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [(TokenType, [Char])]
tokenise
where expand :: (t -> [(TokenType, t)]) -> (TokenType, t) -> [(TokenType, t)]
expand t -> [(TokenType, t)]
f (TokenType
Comment, t
s) = t -> [(TokenType, t)]
f t
s
expand t -> [(TokenType, t)]
_ (TokenType, t)
z = [(TokenType, t)
z]
tokenSpans :: Maybe Loc -> [String] -> [Loc]
tokenSpans :: Maybe Loc -> [[Char]] -> [Loc]
tokenSpans = (Loc -> [Char] -> Loc) -> Loc -> [[Char]] -> [Loc]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Loc -> [Char] -> Loc
plusLoc (Loc -> [[Char]] -> [Loc])
-> (Maybe Loc -> Loc) -> Maybe Loc -> [[Char]] -> [Loc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Loc -> Maybe Loc -> Loc
forall a. a -> Maybe a -> a
fromMaybe ((Int, Int) -> Loc
L (Int
1, Int
1))
plusLoc :: Loc -> String -> Loc
plusLoc :: Loc -> [Char] -> Loc
plusLoc (L (Int
l, Int
c)) [Char]
s
= case Char
'\n' Char -> [Char] -> [Int]
forall a. Eq a => a -> [a] -> [Int]
`elemIndices` [Char]
s of
[] -> (Int, Int) -> Loc
L (Int
l, Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
[Int]
is -> (Int, Int) -> Loc
L (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
is, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Int]
is)
where n :: Int
n = [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
s
renderAnnotToken :: (TokenType, String, Annotation) -> String
renderAnnotToken :: (TokenType, [Char], Annotation) -> [Char]
renderAnnotToken (TokenType
x, [Char]
y, Annotation
a) = Maybe (Int, Int) -> ShowS
forall t t1.
(Show t, PrintfArg t1, PrintfType t1) =>
Maybe (t, Int) -> t1 -> t1
renderLinAnnot (Annotation -> Maybe (Int, Int)
lin Annotation
a)
ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Maybe [Char] -> ShowS
forall t1 t. (PrintfArg t1, PrintfType t1) => Maybe t -> t1 -> t1
renderErrAnnot (Annotation -> Maybe [Char]
err Annotation
a)
ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Maybe [Char] -> ShowS
forall t. (PrintfArg t, PrintfType t) => Maybe [Char] -> t -> t
renderTypAnnot (Annotation -> Maybe [Char]
typ Annotation
a)
ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ (TokenType, [Char]) -> [Char]
CSS.renderToken (TokenType
x, [Char]
y)
renderTypAnnot :: (PrintfArg t, PrintfType t) => Maybe String -> t -> t
renderTypAnnot :: forall t. (PrintfArg t, PrintfType t) => Maybe [Char] -> t -> t
renderTypAnnot (Just [Char]
ann) t
s = [Char] -> [Char] -> t -> t
forall r. PrintfType r => [Char] -> r
printf [Char]
"<a class=annot href=\"#\"><span class=annottext>%s</span>%s</a>" (ShowS
escape [Char]
ann) t
s
renderTypAnnot Maybe [Char]
Nothing t
s = t
s
renderErrAnnot :: (PrintfArg t1, PrintfType t1) => Maybe t -> t1 -> t1
renderErrAnnot :: forall t1 t. (PrintfArg t1, PrintfType t1) => Maybe t -> t1 -> t1
renderErrAnnot (Just t
_) t1
s = [Char] -> t1 -> t1
forall r. PrintfType r => [Char] -> r
printf [Char]
"<span class=hs-error>%s</span>" t1
s
renderErrAnnot Maybe t
Nothing t1
s = t1
s
renderLinAnnot :: (Show t, PrintfArg t1, PrintfType t1)
=> Maybe (t, Int) -> t1 -> t1
renderLinAnnot :: forall t t1.
(Show t, PrintfArg t1, PrintfType t1) =>
Maybe (t, Int) -> t1 -> t1
renderLinAnnot (Just (t, Int)
d) t1
s = [Char] -> [Char] -> t1 -> t1
forall r. PrintfType r => [Char] -> r
printf [Char]
"<span class=hs-linenum>%s: </span>%s" ((t, Int) -> [Char]
forall t. Show t => (t, Int) -> [Char]
lineString (t, Int)
d) t1
s
renderLinAnnot Maybe (t, Int)
Nothing t1
s = t1
s
lineString :: Show t => (t, Int) -> [Char]
lineString :: forall t. Show t => (t, Int) -> [Char]
lineString (t
i, Int
w) = Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
is) Char
' ' [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
is
where is :: [Char]
is = t -> [Char]
forall a. Show a => a -> [Char]
show t
i
insertAnnotAnchors :: [(TokenType, String, a)] -> [Either String (TokenType, String, a)]
insertAnnotAnchors :: forall a.
[(TokenType, [Char], a)] -> [Either [Char] (TokenType, [Char], a)]
insertAnnotAnchors [(TokenType, [Char], a)]
toks
= [((TokenType, [Char]), (TokenType, [Char], a))]
-> [Either [Char] (TokenType, [Char])]
-> [Either [Char] (TokenType, [Char], a)]
forall b c a. Eq b => [(b, c)] -> [Either a b] -> [Either a c]
stitch ([(TokenType, [Char])]
-> [(TokenType, [Char], a)]
-> [((TokenType, [Char]), (TokenType, [Char], a))]
forall a b. [a] -> [b] -> [(a, b)]
zip [(TokenType, [Char])]
toks' [(TokenType, [Char], a)]
toks) ([Either [Char] (TokenType, [Char])]
-> [Either [Char] (TokenType, [Char], a)])
-> [Either [Char] (TokenType, [Char])]
-> [Either [Char] (TokenType, [Char], a)]
forall a b. (a -> b) -> a -> b
$ [(TokenType, [Char])] -> [Either [Char] (TokenType, [Char])]
insertAnchors [(TokenType, [Char])]
toks'
where toks' :: [(TokenType, [Char])]
toks' = [(TokenType
x,[Char]
y) | (TokenType
x,[Char]
y,a
_) <- [(TokenType, [Char], a)]
toks]
stitch :: Eq b => [(b, c)] -> [Either a b] -> [Either a c]
stitch :: forall b c a. Eq b => [(b, c)] -> [Either a b] -> [Either a c]
stitch [(b, c)]
xys ((Left a
a) : [Either a b]
rest)
= a -> Either a c
forall a b. a -> Either a b
Left a
a Either a c -> [Either a c] -> [Either a c]
forall a. a -> [a] -> [a]
: [(b, c)] -> [Either a b] -> [Either a c]
forall b c a. Eq b => [(b, c)] -> [Either a b] -> [Either a c]
stitch [(b, c)]
xys [Either a b]
rest
stitch ((b
x,c
y):[(b, c)]
xys) ((Right b
x'):[Either a b]
rest)
| b
x b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
x'
= c -> Either a c
forall a b. b -> Either a b
Right c
y Either a c -> [Either a c] -> [Either a c]
forall a. a -> [a] -> [a]
: [(b, c)] -> [Either a b] -> [Either a c]
forall b c a. Eq b => [(b, c)] -> [Either a b] -> [Either a c]
stitch [(b, c)]
xys [Either a b]
rest
| Bool
otherwise
= Maybe SrcSpan -> [Char] -> [Either a c]
forall a. HasCallStack => Maybe SrcSpan -> [Char] -> a
panic Maybe SrcSpan
forall a. Maybe a
Nothing [Char]
"stitch"
stitch [(b, c)]
_ []
= []
stitch [(b, c)]
_ [Either a b]
_
= Maybe SrcSpan -> [Char] -> [Either a c]
forall a. Maybe SrcSpan -> [Char] -> a
impossible Maybe SrcSpan
forall a. Maybe a
Nothing [Char]
"stitch: cannot happen"
splitSrcAndAnns :: String -> (String, AnnMap)
splitSrcAndAnns :: [Char] -> ([Char], AnnMap)
splitSrcAndAnns [Char]
s =
let ls :: [[Char]]
ls = [Char] -> [[Char]]
lines [Char]
s in
case [Char] -> [[Char]] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex [Char]
breakS [[Char]]
ls of
Maybe Int
Nothing -> ([Char]
s, HashMap Loc ([Char], [Char])
-> [(Loc, Loc, [Char])]
-> Status
-> [(RealSrcSpan, ([Char], [Char]))]
-> AnnMap
Ann HashMap Loc ([Char], [Char])
forall k v. HashMap k v
M.empty [] Status
Safe [(RealSrcSpan, ([Char], [Char]))]
forall a. Monoid a => a
mempty)
Just Int
i -> ([Char]
src, AnnMap
ann)
where ([[Char]]
codes, [Char]
_:[Char]
mname:[[Char]]
annots) = Int -> [[Char]] -> ([[Char]], [[Char]])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
i [[Char]]
ls
ann :: AnnMap
ann = [Char] -> [Char] -> AnnMap
annotParse [Char]
mname ([Char] -> AnnMap) -> [Char] -> AnnMap
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines [[Char]]
annots
src :: [Char]
src = [[Char]] -> [Char]
unlines [[Char]]
codes
srcModuleName :: String -> String
srcModuleName :: ShowS
srcModuleName = [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"Main" (Maybe [Char] -> [Char]) -> ([Char] -> Maybe [Char]) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(TokenType, [Char])] -> Maybe [Char]
tokenModule ([(TokenType, [Char])] -> Maybe [Char])
-> ([Char] -> [(TokenType, [Char])]) -> [Char] -> Maybe [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [(TokenType, [Char])]
tokenise
tokenModule :: [(TokenType, [Char])] -> Maybe [Char]
tokenModule :: [(TokenType, [Char])] -> Maybe [Char]
tokenModule [(TokenType, [Char])]
toks
= do i <- (TokenType, [Char]) -> [(TokenType, [Char])] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex (TokenType
Keyword, [Char]
"module") [(TokenType, [Char])]
toks
let (_, toks') = splitAt (i+2) toks
j <- findIndex ((Space ==) . fst) toks'
let (toks'', _) = splitAt j toks'
return $ concatMap snd toks''
breakS :: [Char]
breakS :: [Char]
breakS = [Char]
"MOUSEOVER ANNOTATIONS"
annotParse :: String -> String -> AnnMap
annotParse :: [Char] -> [Char] -> AnnMap
annotParse [Char]
mname [Char]
s = HashMap Loc ([Char], [Char])
-> [(Loc, Loc, [Char])]
-> Status
-> [(RealSrcSpan, ([Char], [Char]))]
-> AnnMap
Ann ([(Loc, ([Char], [Char]))] -> HashMap Loc ([Char], [Char])
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList [(Loc, ([Char], [Char]))]
ts) [(Loc
x,Loc
y,[Char]
"") | (Loc
x,Loc
y) <- [(Loc, Loc)]
es] Status
Safe [(RealSrcSpan, ([Char], [Char]))]
forall a. Monoid a => a
mempty
where
([(Loc, ([Char], [Char]))]
ts, [(Loc, Loc)]
es) = [Either (Loc, ([Char], [Char])) (Loc, Loc)]
-> ([(Loc, ([Char], [Char]))], [(Loc, Loc)])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either (Loc, ([Char], [Char])) (Loc, Loc)]
-> ([(Loc, ([Char], [Char]))], [(Loc, Loc)]))
-> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
-> ([(Loc, ([Char], [Char]))], [(Loc, Loc)])
forall a b. (a -> b) -> a -> b
$ [Char]
-> Int -> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines [Char]
mname Int
0 ([[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)])
-> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]]
lines [Char]
s
parseLines :: [Char]
-> Int
-> [[Char]]
-> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines :: [Char]
-> Int -> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines [Char]
_ Int
_ []
= []
parseLines [Char]
mname Int
i ([Char]
"":[[Char]]
ls)
= [Char]
-> Int -> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines [Char]
mname (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [[Char]]
ls
parseLines [Char]
mname Int
i ([Char]
_:[Char]
_:[Char]
l:[Char]
c:[Char]
"0":[Char]
l':[Char]
c':[[Char]]
rest')
= (Loc, Loc) -> Either (Loc, ([Char], [Char])) (Loc, Loc)
forall a b. b -> Either a b
Right ((Int, Int) -> Loc
L (Int
line, Int
col), (Int, Int) -> Loc
L (Int
line', Int
col')) Either (Loc, ([Char], [Char])) (Loc, Loc)
-> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
-> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
forall a. a -> [a] -> [a]
: [Char]
-> Int -> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines [Char]
mname (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) [[Char]]
rest'
where line :: Int
line = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
l :: Int
col :: Int
col = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
c :: Int
line' :: Int
line' = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
l' :: Int
col' :: Int
col' = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
c' :: Int
parseLines [Char]
mname Int
i ([Char]
x:[Char]
f:[Char]
l:[Char]
c:[Char]
n:[[Char]]
rest)
| [Char]
f [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Char]
mname
= [Char]
-> Int -> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines [Char]
mname (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
num) [[Char]]
rest'
| Bool
otherwise
= (Loc, ([Char], [Char]))
-> Either (Loc, ([Char], [Char])) (Loc, Loc)
forall a b. a -> Either a b
Left ((Int, Int) -> Loc
L (Int
line, Int
col), ([Char]
x, [Char]
anns)) Either (Loc, ([Char], [Char])) (Loc, Loc)
-> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
-> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
forall a. a -> [a] -> [a]
: [Char]
-> Int -> [[Char]] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
parseLines [Char]
mname (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
num) [[Char]]
rest'
where line :: Int
line = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
l :: Int
col :: Int
col = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
c :: Int
num :: Int
num = [Char] -> Int
forall a. Read a => [Char] -> a
read [Char]
n :: Int
anns :: [Char]
anns = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"\n" ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> [[Char]] -> [[Char]]
forall a. Int -> [a] -> [a]
take Int
num [[Char]]
rest
rest' :: [[Char]]
rest' = Int -> [[Char]] -> [[Char]]
forall a. Int -> [a] -> [a]
drop Int
num [[Char]]
rest
parseLines [Char]
_ Int
i [[Char]]
_
= Maybe SrcSpan
-> [Char] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
forall a. HasCallStack => Maybe SrcSpan -> [Char] -> a
panic Maybe SrcSpan
forall a. Maybe a
Nothing ([Char] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)])
-> [Char] -> [Either (Loc, ([Char], [Char])) (Loc, Loc)]
forall a b. (a -> b) -> a -> b
$ [Char]
"Error Parsing Annot Input on Line: " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
instance Show AnnMap where
show :: AnnMap -> [Char]
show (Ann HashMap Loc ([Char], [Char])
ts [(Loc, Loc, [Char])]
es Status
_ [(RealSrcSpan, ([Char], [Char]))]
_) = [Char]
"\n\n"
[Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ((Loc, ([Char], [Char])) -> [Char])
-> [(Loc, ([Char], [Char]))] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Loc, ([Char], [Char])) -> [Char]
forall t t1.
(PrintfArg t, PrintfType t1) =>
(Loc, (t, [Char])) -> t1
ppAnnotTyp (HashMap Loc ([Char], [Char]) -> [(Loc, ([Char], [Char]))]
forall k v. HashMap k v -> [(k, v)]
M.toList HashMap Loc ([Char], [Char])
ts)
[Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ((Loc, Loc) -> [Char]) -> [(Loc, Loc)] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Loc, Loc) -> [Char]
forall t. PrintfType t => (Loc, Loc) -> t
ppAnnotErr [(Loc
x,Loc
y) | (Loc
x,Loc
y,[Char]
_) <- [(Loc, Loc, [Char])]
es]
ppAnnotTyp :: (PrintfArg t, PrintfType t1) => (Loc, (t, String)) -> t1
ppAnnotTyp :: forall t t1.
(PrintfArg t, PrintfType t1) =>
(Loc, (t, [Char])) -> t1
ppAnnotTyp (L (Int
l, Int
c), (t
x, [Char]
s)) = [Char] -> t -> Int -> Int -> Int -> [Char] -> t1
forall r. PrintfType r => [Char] -> r
printf [Char]
"%s\n%d\n%d\n%d\n%s\n\n\n" t
x Int
l Int
c ([[Char]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[Char]] -> Int) -> [[Char]] -> Int
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]]
lines [Char]
s) [Char]
s
ppAnnotErr :: PrintfType t => (Loc, Loc) -> t
ppAnnotErr :: forall t. PrintfType t => (Loc, Loc) -> t
ppAnnotErr (L (Int
l, Int
c), L (Int
l', Int
c')) = [Char] -> Int -> Int -> Int -> Int -> t
forall r. PrintfType r => [Char] -> r
printf [Char]
" \n%d\n%d\n0\n%d\n%d\n\n\n\n" Int
l Int
c Int
l' Int
c'
data Lit = Code {Lit -> [Char]
unL :: String} | Lit {unL :: String} deriving (Int -> Lit -> ShowS
[Lit] -> ShowS
Lit -> [Char]
(Int -> Lit -> ShowS)
-> (Lit -> [Char]) -> ([Lit] -> ShowS) -> Show Lit
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Lit -> ShowS
showsPrec :: Int -> Lit -> ShowS
$cshow :: Lit -> [Char]
show :: Lit -> [Char]
$cshowList :: [Lit] -> ShowS
showList :: [Lit] -> ShowS
Show)
inlines :: String -> [String]
inlines :: [Char] -> [[Char]]
inlines [Char]
str = [Char] -> ShowS -> [[Char]]
lines' [Char]
str ShowS
forall a. a -> a
id
where
lines' :: [Char] -> ShowS -> [[Char]]
lines' [] ShowS
acc = [ShowS
acc []]
lines' (Char
'\^M':Char
'\n':[Char]
s) ShowS
acc = ShowS
acc [Char
'\n'] [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char] -> ShowS -> [[Char]]
lines' [Char]
s ShowS
forall a. a -> a
id
lines' (Char
'\n':[Char]
s) ShowS
acc = ShowS
acc [Char
'\n'] [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char] -> ShowS -> [[Char]]
lines' [Char]
s ShowS
forall a. a -> a
id
lines' (Char
c:[Char]
s) ShowS
acc = [Char] -> ShowS -> [[Char]]
lines' [Char]
s (ShowS
acc ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char
cChar -> ShowS
forall a. a -> [a] -> [a]
:))
classify :: [String] -> [Lit]
classify :: [[Char]] -> [Lit]
classify [] = []
classify ([Char]
x:[[Char]]
xs) | [Char]
"\\begin{code}"[Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`[Char]
x
= [Char] -> Lit
Lit [Char]
xLit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [Char] -> [[Char]] -> [Lit]
allProg [Char]
"code" [[Char]]
xs
classify ([Char]
x:[[Char]]
xs) | [Char]
"\\begin{spec}"[Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`[Char]
x
= [Char] -> Lit
Lit [Char]
xLit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [Char] -> [[Char]] -> [Lit]
allProg [Char]
"spec" [[Char]]
xs
classify ((Char
'>':[Char]
x):[[Char]]
xs) = [Char] -> Lit
Code (Char
'>'Char -> ShowS
forall a. a -> [a] -> [a]
:[Char]
x) Lit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [[Char]] -> [Lit]
classify [[Char]]
xs
classify ([Char]
x:[[Char]]
xs) = [Char] -> Lit
Lit [Char]
xLit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [[Char]] -> [Lit]
classify [[Char]]
xs
allProg :: [Char] -> [[Char]] -> [Lit]
allProg :: [Char] -> [[Char]] -> [Lit]
allProg [Char]
name = [[Char]] -> [Lit]
go
where
end :: [Char]
end = [Char]
"\\end{" [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
"}"
go :: [[Char]] -> [Lit]
go [] = []
go ([Char]
x:[[Char]]
xs) | [Char]
end `isPrefixOf `[Char]
x
= [Char] -> Lit
Lit [Char]
xLit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [[Char]] -> [Lit]
classify [[Char]]
xs
go ([Char]
x:[[Char]]
xs) = [Char] -> Lit
Code [Char]
xLit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [[Char]] -> [Lit]
go [[Char]]
xs
joinL :: [Lit] -> [Lit]
joinL :: [Lit] -> [Lit]
joinL [] = []
joinL (Code [Char]
c:Code [Char]
c2:[Lit]
xs) = [Lit] -> [Lit]
joinL ([Char] -> Lit
Code ([Char]
c[Char] -> ShowS
forall a. [a] -> [a] -> [a]
++[Char]
c2)Lit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
:[Lit]
xs)
joinL (Lit [Char]
c :Lit [Char]
c2 :[Lit]
xs) = [Lit] -> [Lit]
joinL ([Char] -> Lit
Lit ([Char]
c[Char] -> ShowS
forall a. [a] -> [a] -> [a]
++[Char]
c2)Lit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
:[Lit]
xs)
joinL (Lit
lit:[Lit]
xs) = Lit
litLit -> [Lit] -> [Lit]
forall a. a -> [a] -> [a]
: [Lit] -> [Lit]
joinL [Lit]
xs