on 294fdfd help sign in
elk/compiler/Compiler.hs
102 lines 4.2 kB history raw
1{-# LANGUAGE DeriveDataTypeable #-}
2module Main where
4import Data.Either (lefts, rights)
5import Data.List (intersect, intercalate,lookup)
6import Data.Maybe (fromMaybe)
7import Data.Version (showVersion)
8import System.Console.CmdArgs
9import System.Exit
10import System.FilePath
11import Text.Blaze.Html.Renderer.String (renderHtml)
13import qualified Text.Jasmine as JS
14import qualified Data.ByteString.Lazy.Char8 as BS
16import Ast
17import Initialize
18import CompileToJS
19import GenerateHtml
20import Paths_Elm
22data ELM =
23 ELM { make :: Bool
24 , files :: [FilePath]
25 , runtime :: Maybe FilePath
26 , separate_js :: Bool
27 , only_js :: Bool
28 , import_js :: [FilePath]
29 , no_prelude :: Bool
30 , noscript :: Bool
31 , minify :: Bool
32 , output_directory :: Maybe FilePath
33 }
34 deriving (Data,Typeable,Show,Eq)
36elm = ELM { make = False &= help "automatically compile dependencies."
37 , files = def &= args &= typ "FILES"
38 , runtime = Nothing &= typFile &=
39 help "Specify a custom location for Elm's runtime system."
40 , separate_js = False &= help "Compile to separate HTML and JS files."
41 , only_js = False &= help "Compile only to JavaScript."
42 , import_js = [] &= typFile &= help "Include a JavaScript file before the body of the Elm program. Can be used many times. Files will be included in the given order."
43 , no_prelude = False &= help "Do not import Prelude by default, used only when compiling standard libraries."
44 , noscript = True &= help "Add generated <noscript> tag to HTML output."
45 , minify = False &= help "Minify generated JavaScript"
46 , output_directory = Nothing &= typFile &= help "Output files to directory specified. Defaults to the location of original file."
47 } &=
48 help "Compile Elm programs to HTML, CSS, and JavaScript." &=
49 summary ("The Elm Compiler " ++ showVersion version ++ ", (c) Evan Czaplicki")
51main = do
52 args <- cmdArgs elm
53 mini <- getDataFileName "elm-runtime.js"
54 compileArgs mini args
56compileArgs mini flags =
57 case files flags of
58 [] -> putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
59 fs -> mapM_ (fileTo flags what loc) fs
60 where loc = fromMaybe mini (runtime flags)
61 what | only_js flags = JS
62 | separate_js flags = Split
63 | otherwise = HTML
65data What = JS | HTML | Split
67fileTo flags what rtLoc file = do
68 let jsStyle = if minify flags then Minified else Readable
69 formatJS = if minify flags then BS.unpack . JS.minify . BS.pack else id
70 ems <- if make flags then build file
71 else do src <- readFile file
72 return (fmap (:[]) (buildFromSource src))
73 jss <- concat `fmap` mapM readFile (import_js flags)
74 case ems of
75 Left err -> do putStrLn $ "Error while compiling " ++ file ++ ":\n" ++ err
76 exitFailure
77 Right ms' ->
78 let path = fromMaybe "" (output_directory flags) </> file
79 js = replaceExtension path ".js"
80 html = replaceExtension path ".html"
81 ms = if no_prelude flags then ms' else map addPrelude ms'
82 txt = jss ++ concatMap jsModule ms
83 in case what of
84 JS -> writeFile js (formatJS txt)
85 HTML -> writeFile html . renderHtml $
86 modulesToHtml jsStyle "" rtLoc jss (noscript flags) ms
87 Split ->
88 do writeFile html . renderHtml $ linkedHtml rtLoc js ms
89 writeFile js (formatJS txt)
91addPrelude (Module name exs ims stmts) = Module name exs (prelude ++ ims) stmts
92 where prelude = concatMap addModule allModules
94 addModule (n, method) = case lookup n ims of
95 Nothing -> [(n, method)]
96 Just _ -> []
97 modules = [ "Prelude", "Signal", "List", "Maybe"
98 , "Time", "Graphics.Element", "Graphics.Color" ]
100 text = ("Graphics.Text", Hiding ["link", "color"])
102 allModules = text : map (\n -> (n, Hiding [])) modules