@@ -4,6 +4,7 @@ module Main where
44import Control.Monad
55import qualified Data.Map as Map
66import qualified Data.List as List
7+import Data.Binary (encodeFile, decodeFile)
78import Data.Version (showVersion)
89import System.Console.CmdArgs
910import System.Directory
@@ -23,13 +24,15 @@ import Paths_Elm
2324
2425import Text.PrettyPrint as P
2526import qualified Type.Type as Type
26−
27+import qualified Parse.Type as Parse
28+import qualified Data.Traversable as Traverse
2729
2830data Flags =
2931 Flags { make :: Bool
3032 , files :: [FilePath]
3133 , runtime :: Maybe FilePath
3234 , only_js :: Bool
35+ , print_types :: Bool
3336 , scripts :: [FilePath]
3437 , no_prelude :: Bool
3538 , minify :: Bool
@@ -45,6 +48,8 @@ flags = Flags
4548 &= help "Specify a custom location for Elm's runtime system."
4649 , only_js = False
4750 &= help "Compile only to JavaScript."
51+ , print_types = False
52+ &= help "Print out infered types of top-level definitions."
4853 , scripts = [] &= typFile
4954 &= help "Load JavaScript files in generated HTML. Files will be included in the given order."
5055 , no_prelude = False
@@ -66,8 +71,6 @@ compileArgs flags =
6671 fs -> mapM_ (build flags) fs
6772
6873
69−type Interface = String
70−
7174file :: Flags -> FilePath -> String -> FilePath
7275file flags filePath ext = output_directory flags </> replaceExtension filePath ext
7376
@@ -76,10 +79,10 @@ elmo flags filePath = file flags filePath "elmo"
7679elmi flags filePath = file flags filePath "elmi"
7780
7881
79−buildFile :: Flags -> Int -> Int -> FilePath -> IO Interface
82+buildFile :: Flags -> Int -> Int -> FilePath -> IO ModuleInterface
8083buildFile flags moduleNum numModules filePath =
8184 do compiled <- alreadyCompiled
82− if compiled then readFile (elmo flags filePath) else compile
85+ if compiled then decodeFile (elmi flags filePath) else compile
8386
8487 where
8588 alreadyCompiled :: IO Bool
@@ -96,30 +99,35 @@ buildFile flags moduleNum numModules filePath =
9699 name :: String
97100 name = List.intercalate "." (splitDirectories (dropExtensions filePath))
98101
99− compile :: IO Interface
102+ compile :: IO ModuleInterface
100103 compile = do
101104 putStrLn (number ++ " Compiling " ++ name)
102105 source <- readFile filePath
103− (js, maybeModule) <-
104− if takeExtension filePath == ".js" then return (source, Nothing) else
105− case buildFromSource (no_prelude flags) source of
106− Left err -> mapM print err >> exitFailure
107− Right modul -> return (jsModule modul, Just modul)
108106 createDirectoryIfMissing True (output_directory flags)
107+ metaModule <-
108+ case buildFromSource Map.empty source of
109+ Left err -> mapM print err >> exitFailure
110+ Right modul -> return (modul :: MetadataModule () ())
111+ if print_types flags then printTypes metaModule else return ()
112+ tipes <- toSrcTypes (types metaModule)
113+ let fmt (name, tvars, ctors) = (name, (length tvars, map fst ctors))
114+ interface = ModuleInterface {
115+ iTypes = tipes,
116+ iAdts = Map.fromList . map fmt $ datatypes metaModule
117+ }
118+ encodeFile (elmi flags filePath) interface
119+ let js = jsModule metaModule
109120 writeFile (elmo flags filePath) js
110− writeTypes maybeModule
111− return js
121+ return interface
112122
113− writeTypes :: Maybe (MetadataModule () ()) -> IO ()
114− writeTypes maybeModule =
115− case maybeModule of
116− Nothing -> return ()
117− Just metaModule -> do
118− tipes <- forM (Map.toList (types metaModule)) $ \(n,t) -> do
119− pt <- Type.extraPretty t
120− return $ P.text n <+> P.text ":" <+> pt
121− writeFile (elmi flags filePath) (P.render $ P.vcat tipes)
123+toSrcTypes tipes = Traverse.traverse convert tipes
124+ where
125+ convert t = fmap (Parse.readType . P.render) (Type.extraPretty t)
122126
127+printTypes metaModule =
128+ forM_ (Map.toList $ types metaModule) $ \(n,t) -> do
129+ pt <- Type.extraPretty t
130+ print $ P.text n <+> P.text ":" <+> pt
123131
124132
125133getRuntime :: Flags -> IO FilePath
@@ -157,7 +165,7 @@ build flags rootFile = do
157165 [ Source (if minify flags then Minified else Readable) js ]
158166
159167
160−buildFiles :: Flags -> Int -> Map.Map String Interface -> [FilePath] -> IO ()
168+buildFiles :: Flags -> Int -> Map.Map String ModuleInterface -> [FilePath] -> IO ()
161169buildFiles _ _ _ [] = return ()
162170buildFiles flags numModules interfaces (filePath:rest) = do
163171 interface <- buildFile flags (numModules - length rest) numModules filePath