on master help sign in
Add --src-dir flag
de52cacEvan Czaplicki
compiler/Compiler.hs+5−1
@@ -42,6 +42,7 @@ data Flags =
42 , no_prelude :: Bool
42 , no_prelude :: Bool
43 , cache_dir :: FilePath
43 , cache_dir :: FilePath
44 , build_dir :: FilePath
44 , build_dir :: FilePath
45+ , src_dir :: [FilePath]
45 }
46 }
46 deriving (Data,Typeable,Show,Eq)
47 deriving (Data,Typeable,Show,Eq)
47
48
@@ -61,6 +62,8 @@ flags = Flags
61 &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
62 &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
62 , build_dir = "build" &= typFile
63 , build_dir = "build" &= typFile
63 &= help "Directory for generated HTML and JS files. Defaults to build/ directory."
64 &= help "Directory for generated HTML and JS files. Defaults to build/ directory."
65+ , src_dir = ["."] &= typFile
66+ &= help "Additional source directories besides project root. Searched when using --make"
64 , print_types = False
67 , print_types = False
65 &= help "Print out infered types of top-level definitions."
68 &= help "Print out infered types of top-level definitions."
66 , print_program = False
69 , print_program = False
@@ -173,7 +176,8 @@ getRuntime flags =
173build :: Flags -> FilePath -> IO ()
176build :: Flags -> FilePath -> IO ()
174build flags rootFile = do
177build flags rootFile = do
175 let noPrelude = no_prelude flags
178 let noPrelude = no_prelude flags
176− files <- if make flags then getSortedDependencies noPrelude rootFile else return [rootFile]
179+ files <- if make flags then getSortedDependencies (src_dir flags) noPrelude rootFile
180+ else return [rootFile]
177 let ifaces = if noPrelude then Map.empty else Prelude.interfaces
181 let ifaces = if noPrelude then Map.empty else Prelude.interfaces
178 (moduleName, interfaces) <- buildFiles flags (length files) ifaces "" files
182 (moduleName, interfaces) <- buildFiles flags (length files) ifaces "" files
179 js <- foldM appendToOutput BS.empty files
183 js <- foldM appendToOutput BS.empty files
compiler/Initialize.hs+23−9
@@ -6,6 +6,7 @@ import qualified Data.Graph as Graph
6import qualified Data.List as List
6import qualified Data.List as List
7import qualified Data.Map as Map
7import qualified Data.Map as Map
8import qualified Data.Set as Set
8import qualified Data.Set as Set
9+import System.Directory
9import System.Exit
10import System.Exit
10import System.FilePath as FP
11import System.FilePath as FP
11import Text.PrettyPrint (Doc)
12import Text.PrettyPrint (Doc)
@@ -62,9 +63,9 @@ buildFromSource noPrelude interfaces source =
62 return $ metaModule { types = types }
63 return $ metaModule { types = types }
63
64
64
65
65−getSortedDependencies :: Bool -> FilePath -> IO [String]
66+getSortedDependencies :: [FilePath] -> Bool -> FilePath -> IO [String]
66−getSortedDependencies noPrelude root =
67+getSortedDependencies srcDirs noPrelude root =
67− sortDeps =<< readDeps noPrelude root
68+ sortDeps =<< readDeps srcDirs noPrelude root
68
69
69type Deps = (FilePath, String, [String])
70type Deps = (FilePath, String, [String])
70
71
@@ -79,18 +80,18 @@ sortDeps depends =
79 mistakes = filter (\scc -> length scc > 1) sccs
80 mistakes = filter (\scc -> length scc > 1) sccs
80 msg = "A cyclical module dependency or was detected in: "
81 msg = "A cyclical module dependency or was detected in: "
81
82
82−readDeps :: Bool -> FilePath -> IO [Deps]
83+readDeps :: [FilePath] -> Bool -> FilePath -> IO [Deps]
83−readDeps noPrelude root = evalStateT (go root) Set.empty
84+readDeps srcDirs noPrelude root = evalStateT (go root) Set.empty
84 where
85 where
85 builtIns = if noPrelude then Set.empty
86 builtIns = if noPrelude then Set.empty
86 else Set.fromList (Map.keys Prelude.interfaces)
87 else Set.fromList (Map.keys Prelude.interfaces)
87
88
88 go :: FilePath -> StateT (Set.Set String) IO [Deps]
89 go :: FilePath -> StateT (Set.Set String) IO [Deps]
89 go root = do
90 go root = do
90− txt <- liftIO $ readFile root
91+ (root', txt) <- liftIO $ getFile srcDirs root
91 case Parse.dependencies txt of
92 case Parse.dependencies txt of
92 Left err -> liftIO (putStrLn msg >> print err >> exitFailure)
93 Left err -> liftIO (putStrLn msg >> print err >> exitFailure)
93− where msg = "Error resolving dependencies in " ++ root ++ ":"
94+ where msg = "Error resolving dependencies in " ++ root' ++ ":"
94
95
95 Right (name,deps) ->
96 Right (name,deps) ->
96 do seen <- get
97 do seen <- get
@@ -98,8 +99,21 @@ readDeps noPrelude root = evalStateT (go root) Set.empty
98 newDeps = Set.difference (Set.filter (not . isNative) realDeps) seen
99 newDeps = Set.difference (Set.filter (not . isNative) realDeps) seen
99 put (Set.insert name (Set.union newDeps seen))
100 put (Set.insert name (Set.union newDeps seen))
100 rest <- mapM (go . toFilePath) (Set.toList newDeps)
101 rest <- mapM (go . toFilePath) (Set.toList newDeps)
101− return ((makeRelative "." root, name, Set.toList realDeps) : concat rest)
102+ return ((makeRelative "." root', name, Set.toList realDeps) : concat rest)
102−
103+
104+getFile :: [FilePath] -> FilePath -> IO (FilePath,String)
105+getFile [] path = do
106+ putStrLn $ unlines [ "Could not find file: " ++ path
107+ , " If it is not in the root directory of your project, use"
108+ , " --src-dir to declare additional locations for source files." ]
109+ exitFailure
110+
111+getFile (dir:dirs) path = do
112+ let path' = dir </> path
113+ exists <- doesFileExist path'
114+ case exists of
115+ True -> (,) path' `fmap` readFile path'
116+ False -> getFile dirs path
103
117
104isNative name = List.isPrefixOf "Native." name
118isNative name = List.isPrefixOf "Native." name
105
119