summaryrefslogtreecommitdiff
path: root/src/LambdaCube
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-02-17 11:21:35 +0100
committerPéter Diviánszky <divipp@gmail.com>2016-02-17 11:21:35 +0100
commited7cff18118bddc2b57fe1738e7edb2fb0064305 (patch)
treeac38ae6e0e66103429a779c86ce36fc30ea465b3 /src/LambdaCube
parent02d18fe787cbe69d422ad9f76a5324f6ba86f4da (diff)
better path handling
Diffstat (limited to 'src/LambdaCube')
-rw-r--r--src/LambdaCube/Compiler.hs53
1 files changed, 25 insertions, 28 deletions
diff --git a/src/LambdaCube/Compiler.hs b/src/LambdaCube/Compiler.hs
index 5f7bd4fd..fc9068cc 100644
--- a/src/LambdaCube/Compiler.hs
+++ b/src/LambdaCube/Compiler.hs
@@ -24,8 +24,8 @@ module LambdaCube.Compiler
24 , prettyShowUnlines 24 , prettyShowUnlines
25 ) where 25 ) where
26 26
27import Data.Char
28import Data.List 27import Data.List
28import Data.Function
29import Data.Map.Strict (Map) 29import Data.Map.Strict (Map)
30import qualified Data.Map.Strict as Map 30import qualified Data.Map.Strict as Map
31import Control.Monad.State 31import Control.Monad.State
@@ -39,7 +39,6 @@ import Control.Exception hiding (catch, bracket, finally, mask)
39import Control.Arrow hiding ((<+>)) 39import Control.Arrow hiding ((<+>))
40import System.Directory 40import System.Directory
41import System.FilePath 41import System.FilePath
42--import Debug.Trace
43import qualified Data.Text as T 42import qualified Data.Text as T
44import qualified Data.Text.IO as TIO 43import qualified Data.Text.IO as TIO
45import qualified Text.Show.Pretty as PP 44import qualified Text.Show.Pretty as PP
@@ -59,7 +58,7 @@ type EName = String
59type MName = String 58type MName = String
60 59
61type Modules = Map FilePath (Either Doc (PolyEnv, String)) 60type Modules = Map FilePath (Either Doc (PolyEnv, String))
62type ModuleFetcher m = Maybe FilePath -> MName -> m (FilePath, String) 61type ModuleFetcher m = Maybe FilePath -> MName -> m (FilePath, MName, String)
63 62
64-- todo: use RWS 63-- todo: use RWS
65newtype MMT m a = MMT { runMMT :: ExceptT String (ReaderT (ModuleFetcher (MMT m)) (StateT Modules (WriterT Infos m))) a } 64newtype MMT m a = MMT { runMMT :: ExceptT String (ReaderT (ModuleFetcher (MMT m)) (StateT Modules (WriterT Infos m))) a }
@@ -94,7 +93,7 @@ catchMM m e = mapMMT (lift . mapReaderT (mapStateT $ lift . runWriterT >=> f) .
94 f ((Right x, m), is) = tell is >> return (Right x, m) 93 f ((Right x, m), is) = tell is >> return (Right x, m)
95 f ((Left e, m), is) = return (Left (e, is), m) 94 f ((Left e, m), is) = return (Left (e, is), m)
96 95
97-- TODO: remove dependent modules from cache too 96-- TODO: remove dependent modules from cache too?
98removeFromCache :: Monad m => FilePath -> MMT m () 97removeFromCache :: Monad m => FilePath -> MMT m ()
99removeFromCache f = modify $ Map.delete f 98removeFromCache f = modify $ Map.delete f
100 99
@@ -110,34 +109,32 @@ ioFetch :: MonadIO m => [FilePath] -> ModuleFetcher (MMT m)
110ioFetch paths imp n = do 109ioFetch paths imp n = do
111 preludePath <- (</> "lc") <$> liftIO getDataDir 110 preludePath <- (</> "lc") <$> liftIO getDataDir
112 let 111 let
113 f [] = throwError $ show $ "can't find module" <+> hsep (map text fnames) 112 fnames = nubBy ((==) `on` fst) $ map (first normalise) $ concatMap lcModuleFile $ paths ++ [preludePath]
114 f (x:xs) = liftIO (readFile' x) >>= \case 113 lcModuleFile path = g imp
115 Nothing -> f xs
116 Just src -> do
117 --liftIO $ putStrLn $ "loading " ++ x
118 return (x, src)
119 fnames = map normalise . concatMap lcModuleFile $ nub $ preludePath : paths
120 lcModuleFile path = (++ ".lc") <$> g imp
121 where 114 where
122 g Nothing = [path </> n] 115 g _ | takeExtension n == ".lc" = [(path </> n, intercalate "." $ remDot $ (\(a, b) -> a ++ [b]) $ map takeDirectory . splitPath *** id $ splitFileName $ dropExtension $ normalise n)]
123 g (Just fn) = [path </> hn, fst (splitMPath fn) </> hn] 116 | otherwise = [(path </> hn n ++ ".lc", n)]
124 117
125 hn = h [] n 118 remDot (".": xs) = xs
119 remDot xs = xs
120
121 hn = h []
126 h acc [] = reverse acc 122 h acc [] = reverse acc
127 h acc ('.':cs) = reverse acc </> h [] cs 123 h acc ('.':cs) = reverse acc </> hn cs
128 h acc (c: cs) = h (c: acc) cs 124 h acc (c: cs) = h (c: acc) cs
129 f fnames
130
131splitMPath fn = (joinPath as, intercalate "." $ bs ++ [y])
132 where
133 (as, bs) = span (\x -> null x || not (isUpper $ head x)) xs
134 (xs, y) = map takeDirectory . splitPath *** id $ splitFileName $ dropExtension fn
135 125
126 f [] = throwError $ show $ "can't find module" <+> text n <+> "in path" <+> hsep (map text paths)
127 f ((x, mn): xs) = liftIO (readFile' x) >>= \case
128 Nothing -> f xs
129 Just src -> do
130 --liftIO $ putStrLn $ "loading " ++ x
131 return (x, mn, src)
132 f fnames
136 133
137loadModule :: MonadMask m => Maybe FilePath -> MName -> MMT m (FilePath, PolyEnv) 134loadModule :: MonadMask m => Maybe FilePath -> MName -> MMT m (FilePath, PolyEnv)
138loadModule imp mname = do 135loadModule imp mname_ = do
139 fetch <- ask 136 fetch <- ask
140 (fname, src) <- fetch imp mname 137 (fname, mname, src) <- fetch imp mname_
141 c <- gets $ Map.lookup fname 138 c <- gets $ Map.lookup fname
142 case c of 139 case c of
143 Just (Right (m, _)) -> return (fname, m) 140 Just (Right (m, _)) -> return (fname, m)
@@ -161,11 +158,11 @@ loadModule imp mname = do
161 ExportId (snd -> d) -> case Map.lookup d $ getPolyEnv x of 158 ExportId (snd -> d) -> case Map.lookup d $ getPolyEnv x of
162 Just def -> PolyEnv (Map.singleton d def) mempty 159 Just def -> PolyEnv (Map.singleton d def) mempty
163 Nothing -> error $ d ++ " is not defined" 160 Nothing -> error $ d ++ " is not defined"
164 ExportModule (snd -> m) | m == snd (splitMPath fname) -> x 161 ExportModule (snd -> m) | m == mname -> x
165 ExportModule m -> case [ ms 162 ExportModule m -> case [ ms
166 | ((m', is), ms) <- zip (moduleImports e) ms, m' == m] of 163 | ((m', is), ms) <- zip (moduleImports e) ms, m' == m] of
167 [PolyEnv x infos] -> PolyEnv x mempty -- TODO 164 [PolyEnv x infos] -> PolyEnv x mempty -- TODO
168 [] -> error $ "empty export list: " ++ show (fname, m, map fst $ moduleImports e, snd (splitMPath fname)) 165 [] -> error $ "empty export list: " ++ show (fname, m, map fst $ moduleImports e, mname)
169 _ -> error "export list: internal error" 166 _ -> error "export list: internal error"
170 modify $ Map.insert fname $ Right (x', src) 167 modify $ Map.insert fname $ Right (x', src)
171 return (fname, x') 168 return (fname, x')
@@ -211,8 +208,8 @@ preCompile paths paths' backend mod = do
211 first (compilePipeline backend) <$> parseAndToCoreMain "Main" 208 first (compilePipeline backend) <$> parseAndToCoreMain "Main"
212 where 209 where
213 fetch imp = \case 210 fetch imp = \case
214 "Prelude" -> return ("./Prelude.lc", undefined) 211 "Prelude" -> return ("./Prelude.lc", "Prelude", undefined)
215 "Main" -> return ("./Main.lc", src) 212 "Main" -> return ("./Main.lc", "Main", src)
216 n -> ioFetch paths' imp n 213 n -> ioFetch paths' imp n
217 214
218prettyShowUnlines :: Show a => a -> String 215prettyShowUnlines :: Show a => a -> String