elm/compiler/Initialize.hs
Evan Czaplicki cb914d91ff Get all of the Haskell files compiling with the new type checker.
Does not actually work, undefined is used in some places as a
stopgap measure.
2013-07-11 12:48:37 +02:00

88 lines
2.9 KiB
Haskell

module Initialize (buildFromSource, getSortedModuleNames) where
import Control.Applicative ((<$>))
import Control.Monad.Error
import Data.List (lookup,nub)
import qualified Data.Map as Map
import Data.Data
import SourceSyntax.Everything
import Data.List (intercalate,partition)
import Parse.Parser (parseProgram, parseDependencies)
import qualified Metadata.Libraries as Libs
import Transform.Optimize
import System.Exit
import System.FilePath
{-- TODO: replace with new stuff
import Types.Hints (hints)
import Types.Unify (unify)
import Types.Alias (dealias, mistakes)
--}
mistakes = undefined
unify = undefined
hints = undefined
checkMistakes :: (Data t, Data v) => Module t v -> Either String (Module t v)
checkMistakes modul@(Module name ex im stmts) =
case mistakes stmts of
m:ms -> Left (unlines (m:ms))
[] -> return modul
checkTypes :: (Data t, Data v) => Module t v -> Either String (Module t v)
checkTypes modul =
do subs <- unify hints modul
subs `seq` return (optimize (renameModule modul))
check :: (Data t, Data v) => Module t v -> Either String (Module t v)
check = checkMistakes >=> checkTypes
buildFromSource :: (Data t, Data v) => Bool -> String -> Either String (Module t v)
buildFromSource noPrelude src =
let add = if noPrelude then id else Libs.addPrelude in
(check . add) =<< (parseProgram src)
getSortedModuleNames :: FilePath -> IO [String]
getSortedModuleNames root =
sortDeps =<< readDeps [] root
type Deps = (String, [String])
sortDeps :: [Deps] -> IO [String]
sortDeps deps = go [] (nub deps)
where
msg = "A cyclical or missing module dependency or was detected in: "
go :: [String] -> [Deps] -> IO [String]
go sorted [] = return (map toFilePath sorted)
go sorted unsorted =
case partition (all (`elem` sorted) . snd) unsorted of
([],m:ms) -> do putStrLn (msg ++ intercalate ", " (map fst (m:ms)) ++ show sorted ++ show unsorted)
exitFailure
(srtd,unsrtd) -> go (sorted ++ map fst srtd) unsrtd
readDeps :: [FilePath] -> FilePath -> IO [Deps]
readDeps seen root = do
txt <- readFile root
case parseDependencies txt of
Left err ->
let msg = "Error resolving dependencies in " ++ root ++ ":\n" in
putStrLn (msg ++ err) >> exitFailure
Right (name,deps) ->
do rest <- mapM (readDeps seen' . toFilePath) newDeps
return ((name, realDeps) : concat rest)
where
realDeps = filter (`notElem` builtIns) deps
newDeps = filter (\d -> d `notElem` seen && not (isNative d)) realDeps
seen' = root : seen ++ newDeps
builtIns = Map.keys Libs.libraries
isNative name = takeWhile (/='.') name == "Native"
toFilePath :: String -> FilePath
toFilePath name = map swapDots name ++ ext
where swapDots '.' = '/'
swapDots c = c
ext = if isNative name then ".js" else ".elm"