Skip to content

Commit 7b334af

Browse files
committed
Use idiom
1 parent a2d9883 commit 7b334af

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

src/Main.hs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
2+
{-# LANGUAGE QuasiQuotes #-}
13
{-# LANGUAGE OverloadedStrings #-}
24
{-# LANGUAGE PatternGuards #-}
35
{-# LANGUAGE RecordWildCards #-}
6+
{-# LANGUAGE ExtendedDefaultRules #-}
47
{-# LANGUAGE ExistentialQuantification #-}
58

69
{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-missing-signatures -fno-warn-type-defaults #-}
@@ -11,13 +14,15 @@
1114
module Main (main) where
1215

1316
import Control.Applicative
17+
import Control.Applicative.QQ.Idiom
1418
import Data.Data
1519
import Data.List
1620
import Data.Maybe
1721
import Data.Text (Text)
1822
import qualified Data.Text as T
1923
import Descriptive
2024
import Descriptive.Options
25+
import GHC.Tuple
2126
import Language.Haskell.Exts.Annotated
2227
import System.Environment
2328

@@ -58,7 +63,7 @@ data ParseType = Decl | Stmt
5863

5964
-- | Command line options.
6065
options :: Monad m => Consumer [Text] (Option ()) m (Action,ParseType,[Extension])
61-
options = (,,) <$> action <*> typ <*> exts
66+
options = [i|(,,) action typ exts|]
6267
where action =
6368
constant "parse" "Parse and spit out spans" Parse <|>
6469
constant "check" "Just check the syntax" Check
@@ -82,15 +87,16 @@ outputWith action typ exts code =
8287
-- | Output AST info for the given Haskell code.
8388
output :: Action -> Parser -> [Extension] -> String -> IO ()
8489
output action parser exts code =
85-
case parser parseMode {extensions = exts} code of
90+
case parser mode code of
8691
ParseFailed _ e -> error e
8792
ParseOk (D ast) ->
8893
case action of
8994
Check -> return ()
9095
Parse ->
9196
putStrLn ("[" ++
92-
concat (genHSE ast) ++
97+
concat (genHSE mode ast) ++
9398
"]")
99+
where mode = parseMode {extensions = exts}
94100

95101
-- | An umbrella parser to parse:
96102
--
@@ -126,19 +132,20 @@ parseMode =
126132
,fixities = Nothing}
127133

128134
-- | Generate a list of spans from the HSE AST.
129-
genHSE :: Data a => a -> [String]
130-
genHSE x =
135+
genHSE :: Data a => ParseMode -> a -> [String]
136+
genHSE mode x =
131137
case gmapQ D x of
132138
zs@(D y:ys) ->
133139
case cast y of
134140
Just s ->
135141
spanHSE (show (show (typeOf x)))
136142
(showConstr (toConstr x))
137143
(srcInfoSpan s) :
138-
concatMap (\(i,D d) -> pre x i ++ genHSE d)
139-
(zip [0..] ys)
144+
concatMap (\(i,D d) -> pre x i ++ genHSE mode d)
145+
(zip [0..] ys) ++
146+
post mode x
140147
_ ->
141-
concatMap (\(D d) -> genHSE d) zs
148+
concatMap (\(D d) -> genHSE mode d) zs
142149
_ -> []
143150

144151
-- | Pre-children tweaks for a given parent at index i.
@@ -170,6 +177,42 @@ pre x i =
170177
,Just (IRule _ _ _ (IHCon (SrcSpanInfo end _) _)) <- [listToMaybe (reverse ds)]]
171178
_ -> []
172179

180+
-- | Post-node tweaks for a parent, e.g. adding more children.
181+
post :: (Typeable a) => ParseMode -> a -> [String]
182+
post mode x =
183+
case cast x of
184+
Just (QuasiQuote (base :: SrcSpanInfo) qname content) ->
185+
case parseExpWithMode mode content of
186+
ParseOk ex -> genHSE mode (fmap (redelta qname base) ex)
187+
ParseFailed _ e -> error e
188+
_ -> []
189+
190+
-- | Apply a delta to the positions in the given span from the base.
191+
redelta :: String -> SrcSpanInfo -> SrcSpanInfo -> SrcSpanInfo
192+
redelta qname base (SrcSpanInfo (SrcSpan fp sl sc el ec) pts) =
193+
SrcSpanInfo
194+
(if sl == 1
195+
then SrcSpan fp
196+
(sl + lineOffset)
197+
(sc + columnOffset)
198+
(el + lineOffset)
199+
(if el == sl
200+
then ec + columnOffset
201+
else ec)
202+
else SrcSpan fp
203+
(sl + lineOffset)
204+
sc
205+
(el + lineOffset)
206+
ec)
207+
pts
208+
where lineOffset = sl' - 1
209+
columnOffset =
210+
sc' - 1 +
211+
length ("[" :: String) +
212+
length qname +
213+
length ("|" :: String)
214+
(SrcSpanInfo (SrcSpan _ sl' sc' _ _) _) = base
215+
173216
-- | Generate a span from a HSE SrcSpan.
174217
spanHSE :: String -> String -> SrcSpan -> String
175218
spanHSE typ cons SrcSpan{..} = "[" ++ spanContent ++ "]"

structured-haskell-mode.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,5 @@ executable structured-haskell-mode
4545
, haskell-src-exts == 1.16.*
4646
, text
4747
, descriptive >= 0.7 && < 0.9
48+
, applicative-quoters
49+
, ghc-prim

0 commit comments

Comments
 (0)