on master help sign in
Merge pull request #3 from tweag/implement-parser

Implement basic parser for fooling around

commit912ea9b28d75e1a4a1d1d729c90e75d25d75b0c6 authorMark Karpov <markkarpov92@gmail.com> dateSat 8 Dec 2018, 17:40 (8 years ago) parentd94e08e02c6a58
4 files changed+85−6
app/Main.hs+24−1 ormolu.cabal+8−3 src/Ormolu/Parser.hs+20−1 src/Ormolu/Type.hs+33−1
app/Main.hs+24−1
@@ -1,4 +1,27 @@
11module Main (main) where
22
3+import Control.Monad
4+import Ormolu.Parser
5+import System.Environment (getArgs)
6+import qualified Outputable as GHC
7+
38main :: IO ()
4−main = return ()
9+main = do
10+ (path:_) <- getArgs
11+ input <- readFile path
12+ (ws, r) <- parseModule [] path input
13+ unless (null ws) $
14+ putStrLn "dynamic option warnings:"
15+ -- TODO print ws
16+ case r of
17+ Left (srcSpan, err) -> do
18+ putStrLn (showOutputable srcSpan)
19+ putStrLn err
20+ Right (anns, parsedModule) -> do
21+ putStrLn "\nannotations:\n"
22+ putStrLn (showOutputable anns)
23+ putStrLn "\nparsed module:\n"
24+ putStrLn (showOutputable parsedModule)
25+
26+showOutputable :: GHC.Outputable o => o -> String
27+showOutputable = GHC.showSDocUnsafe . GHC.ppr
ormolu.cabal+8−3
@@ -25,7 +25,11 @@ flag dev
2525
2626library
2727 hs-source-dirs: src
28− build-depends: base
28+ build-depends: base >= 4.8 && < 5.0
29+ , data-default-class
30+ , ghc >= 8.4.3
31+ , ghc-boot-th >= 8.4.3
32+ , ghc-exactprint >= 0.5.6
2933 exposed-modules: Ormolu
3034 , Ormolu.Parser
3135 , Ormolu.Printer
@@ -45,7 +49,7 @@ test-suite tests
4549 main-is: Main.hs
4650 hs-source-dirs: tests
4751 type: exitcode-stdio-1.0
48− build-depends: base
52+ build-depends: base >= 4.8 && < 5.0
4953 , ormolu
5054 if flag(dev)
5155 ghc-options: -Wall -Werror
@@ -56,7 +60,8 @@ test-suite tests
5660executable ormolu
5761 main-is: Main.hs
5862 hs-source-dirs: app
59− build-depends: base
63+ build-depends: base >= 4.8 && < 5.0
64+ , ghc >= 8.4.3
6065 , ormolu
6166 if flag(dev)
6267 ghc-options: -Wall -Werror -Wcompat
src/Ormolu/Parser.hs+20−1
@@ -1,3 +1,22 @@
11module Ormolu.Parser
2− ( )
2+ ( parseModule )
33where
4+
5+import Language.Haskell.GHC.ExactPrint.Parsers hiding (parseModule)
6+import Language.Haskell.GHC.ExactPrint.Types
7+import Ormolu.Type
8+import qualified CmdLineParser as GHC
9+import qualified DynFlags as GHC
10+import qualified GHC hiding (parseModule)
11+
12+-- | Parse a complete module from string.
13+
14+parseModule
15+ :: [DynOption] -- ^ Dynamic options that affect parsing
16+ -> FilePath -- ^ File name (only for source location annotations)
17+ -> String -- ^ Input for parser
18+ -> IO ([GHC.Warn], Either (GHC.SrcSpan, String) (Anns, GHC.ParsedSource))
19+parseModule dynOpts path input = ghcWrapper $ do
20+ dynFlags0 <- initDynFlagsPure path input
21+ (dynFlags1, _, ws) <- GHC.parseDynamicFilePragma dynFlags0 (dynOption <$> dynOpts)
22+ return (ws, parseModuleFromStringInternal dynFlags1 path input)
src/Ormolu/Type.hs+33−1
@@ -1,3 +1,35 @@
11module Ormolu.Type
2− ( )
2+ ( Config (..)
3+ , DynOption (..)
4+ , dynOption
5+ )
36where
7+
8+import Data.Default.Class
9+import qualified SrcLoc as GHC
10+
11+-- | Ormolu configuration.
12+
13+data Config = Config
14+ { cfgLineWidth :: Int
15+ , cfgIndentStep :: Int
16+ , cfgDynOptions :: [DynOption]
17+ }
18+
19+instance Default Config where
20+ def = Config
21+ { cfgLineWidth = 80
22+ , cfgIndentStep = 2
23+ , cfgDynOptions = []
24+ }
25+
26+-- | A wrapper for dynamic options.
27+
28+newtype DynOption = DynOption
29+ { unDynOption :: String
30+ } deriving (Eq, Ord, Show)
31+
32+-- | Convert 'DynOption' to @'GHC.Located' 'String'@.
33+
34+dynOption :: DynOption -> GHC.Located String
35+dynOption (DynOption o) = GHC.L GHC.noSrcSpan o