1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
{-
Kaya - My favourite toy language.
Copyright (C) 2004-2006 Edwin Brady
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-}
module Main where
import Driver
import Options
import Language
import Chaser
import Module
import REPL
import Monad
import Debug.Trace
import System
import System.Directory
main :: IO ()
main = do args <- getArgs
(mfn,extra,opts) <- usage args
libdirs <- getAllLibDirs opts
defaultRepl <- findLib libdirs "__REPLMain.k"
let (fn, ok)
= case mfn of
Just x -> (x, True)
Nothing ->
case defaultRepl of
Just d -> (d, False)
Nothing -> error "Can't find default REPL input"
mainWith ok defaultRepl fn fn extra opts
mainWith ok defaultRepl fn realfn extra opts =
do let fn' = stripDot fn
mt <- getDeps fn' opts []
bw <- buildWhat opts mt
doBuildAll ok defaultRepl fn' realfn opts extra (reverse bw)
runProgram mt extra
exitWith ExitSuccess
where stripDot ('.':'/':fn) = checkExt fn
stripDot x = checkExt x
checkExt xs | elem '.' xs = xs
| otherwise = xs ++ ".k"
-- buildAll returns the result of a REPL, namely, what we should do next.
-- If there's no REPL, this will just tell us to Quit. Otherwise, we go
-- round again...
-- 'repl' tells us what to load if there's an error. 'fn' is the file we're
-- currently using, 'realfn' is the one we should reload, if we ever want that.
-- If 'ok' is False, we're building REPLMain.
doBuildAll ok repl fn realfn optsin exts xs
= do let opts = if (not ok) then (Quiet:optsin) else optsin
res <- buildAll opts exts xs
if (not ok) then removeFile "__REPLMain.o" else return ()
case res of
Reload -> mainWith True repl realfn realfn exts optsin
Load fn -> mainWith True repl fn realfn exts optsin
CompError -> do case repl of
(Just f) -> mainWith False repl f realfn exts optsin
Nothing -> putStrLn "Can't find default REPL input"
_ -> return ()
buildAll :: Options -> [String] -> [CompileNeeded] -> IO REPLRes
buildAll _ extras [] = return Quit
buildAll opts extras ((Comp fn ty mod need):xs)
-- Don't skip of this is the main file and we want a REPL
| not need && (length xs > 0 || not (mkso opts))
= do when (not (quiet opts) && (ty/=Shebang) && (not (mkso opts))) $
putStrLn $ "Skipping " ++ show ty ++ " "++showuser mod
buildAll opts extras xs
| otherwise = do when (not (quiet opts) && (ty/=Shebang)) $
putStrLn $ "Compiling " ++ show ty ++ " "++showuser mod
if (length xs == 0 && mkso opts)
then do compileFile ty mod fn extras opts True
else do
res <- compileFile ty mod fn extras opts False
case res of
CompError -> exitWith (ExitFailure 1)
_ -> buildAll opts extras xs
runProgram :: ModuleTree -> [String] -> IO ()
runProgram (Mod fn Shebang mod _) args
= do exit <- system ("./"++(outputfile Shebang mod)++" "++showargs args)
if (exit /= ExitSuccess)
then exitWith exit
else return ()
where showargs [] = ""
showargs (x:xs) = x ++ " " ++ showargs xs
runProgram _ _ = return ()
|