1module Initialize (build, buildFromSource) where
3import Control.Applicative ((<$>))
4import Control.Monad.Error
5import Data.List (lookup,nub)
6import qualified Data.Map as Map
9import Data.Either (lefts,rights)
10import Data.List (intercalate,partition)
11import Parse.Parser (parseProgram, preParse)
13import qualified Libraries as Libs
14import Types.Types ((-:))
15import Types.Hints (hints)
17import Types.Alias (dealias, mistakes)
19import CompileToJS (jsModule)
21checkMistakes :: Module -> Either String Module
22checkMistakes modul@(Module name ex im stmts) =
23 case mistakes stmts of
24 m:ms -> Left (unlines (m:ms))
27checkTypes :: Module -> Either String Module
29 do subs <- unify hints modul
30 subs `seq` return (optimize (renameModule modul))
32check :: Module -> Either String Module
33check = checkMistakes >=> checkTypes
35buildFromSource :: Bool -> String -> Either String Module
36buildFromSource withPrelude src = (check . add) =<< (parseProgram src)
37 where add = if withPrelude then Libs.addPrelude else id
39build :: Bool -> FilePath -> IO (Either String [Module])
40build withPrelude root = do
41 names <- getSortedModuleNames root
43 Left err -> return (Left err)
44 Right ns -> do srcs <- zipWithM buildFile' [1..] ns
45 return (sequence srcs)
47 buildFile' n name = putStrLn (msg n name) >> buildFile withPrelude name
48 msg n name = "["++show n++" of "++show (length ns)++"] Compiling "++name
50buildFile :: Bool -> String -> IO (Either String Module)
51buildFile withPrelude moduleName =
52 let filePath = toFilePath moduleName in
53 case isNative moduleName of
54 True -> return (Right $ Module [moduleName] [] [] [])
55 --return (Left "Can't do that yet")
56 --Right `liftM` readFile filePath
57 False -> do txt <- readFile filePath
58 return $ buildFromSource withPrelude txt
61getSortedModuleNames :: FilePath -> IO (Either String [String])
62getSortedModuleNames root = do
63 deps <- readDeps [] root
64 return (sortDeps =<< deps)
66type Deps = (String, [String])
68sortDeps :: [Deps] -> Either String [String]
69sortDeps deps = go [] (nub deps)
71 msg = "A cyclical or missing module dependency or was detected in: "
73 go :: [String] -> [Deps] -> Either String [String]
74 go sorted [] = Right sorted
76 case partition (all (`elem` sorted) . snd) unsorted of
77 ([],m:ms) -> Left (msg ++ intercalate ", " (map fst (m:ms)) ++ show sorted ++ show unsorted)
78 (srtd,unsrtd) -> go (sorted ++ map fst srtd) unsrtd
80readDeps :: [FilePath] -> FilePath -> IO (Either String [Deps])
81readDeps seen root = do
84 Left err -> return (Left err)
85 Right (name,deps) -> do rest <- mapM (readDeps seen' . toFilePath) newDeps
86 return $ do rs <- sequence rest
87 return ((name, realDeps) : concat rs)
88 where realDeps = filter (`notElem` builtIns) deps
89 newDeps = filter (`notElem` seen) realDeps
90 seen' = root : seen ++ newDeps
91 builtIns = Map.keys Libs.libraries
93isNative name = takeWhile (/='.') name == "Native"
94toFilePath name = map swapDots name ++ ext
95 where swapDots '.' = '/'
97 ext = if isNative name then ".js" else ".elm"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list