husk-scheme 3.5.2.1 → 3.5.2.2
raw patch · 3 files changed
+158/−2 lines, 3 filesdep +filepathdep +haskell98dep +processnew-component:exe:huskc
Dependencies added: filepath, haskell98, process
Files
- hs-src/Compiler/huskc.hs +151/−0
- hs-src/Language/Scheme/Core.hs +1/−1
- husk-scheme.cabal +6/−1
+ hs-src/Compiler/huskc.hs view
@@ -0,0 +1,151 @@+{- |+Module : Main+Copyright : Justin Ethier+Licence : MIT (see LICENSE in the distribution)++Maintainer : github.com/justinethier+Stability : experimental+Portability : portable++A front-end for an experimental compiler+-}++module Main where+import Paths_husk_scheme+import Language.Scheme.Compiler+import qualified Language.Scheme.Core+import Language.Scheme.Types -- Scheme data types+import Language.Scheme.Variables -- Scheme variable operations+import Control.Monad.Error+import System (getArgs)+import System.Cmd (system)+import System.Console.GetOpt+import System.FilePath (dropExtension)+import System.Environment+import System.Exit (ExitCode (..), exitWith, exitFailure)+import System.IO++main :: IO ()+main = do ++ putStrLn ""+ putStrLn "!!! This version of huskc is Experimental !!!"+ putStrLn ""+ putStrLn "It is recommended you consult the issue list prior to use:"+ putStrLn "https://github.com/justinethier/husk-scheme/issues"+ putStrLn ""++ -- Read command line args and process options+ args <- getArgs+ let (actions, nonOpts, msgs) = getOpt Permute options args+ opts <- foldl (>>=) (return defaultOptions) actions+ let Options {optOutput = output} = opts++ if null nonOpts+ then showUsage+ else do+ let inFile = nonOpts !! 0+ outExec = case output of+ Just inFile -> inFile+ Nothing -> dropExtension inFile+ process inFile outExec++-- +-- For an explanation of the command line options code, see:+-- http://leiffrenzel.de/papers/commandline-options-in-haskell.html+--++-- |Data type to handle command line options that take parameters+data Options = Options {+ optOutput :: Maybe String -- Executable file to write+ }++-- |Default values for the command line options+defaultOptions :: Options+defaultOptions = Options {+ optOutput = Nothing + }++-- |Command line options+options :: [OptDescr (Options -> IO Options)]+options = [+ Option ['V'] ["version"] (NoArg showVersion) "show version number",+ Option ['h', '?'] ["help"] (NoArg showHelp) "show usage information",+ Option ['o'] ["output"] (ReqArg writeExec "FILE") "output file to write"+ ]++-- |Determine executable file to write. +-- This version just takes a name from the command line option+writeExec arg opt = return opt { optOutput = Just arg }++-- TODO: would nice to have this as well as a 'real' usage printout, perhaps via --help++-- |Print a usage message+showUsage :: IO ()+showUsage = do+ putStrLn "huskc: no input files"++showHelp :: Options -> IO Options+showHelp _ = do+ putStrLn "Usage: huskc [options] file"+ putStrLn ""+ putStrLn "Options:"+ putStrLn " --help Display this information"+ putStrLn " --version Display husk version information"+ putStrLn " --output filename Write executable to the given filename"+ putStrLn ""+ exitWith ExitSuccess++-- |Print version information+showVersion :: Options -> IO Options+showVersion _ = do+ putStrLn Language.Scheme.Core.version+-- TODO: would be nice to be able to print the banner: Language.Scheme.Core.showBanner+ exitWith ExitSuccess++-- |High level code to compile the given file+process :: String -> String -> IO ()+process inFile outExec = do+ env <- liftIO $ nullEnv+ stdlib <- getDataFileName "stdlib.scm"+ result <- (runIOThrows $ liftM show $ compileSchemeFile env stdlib inFile)+ case result of+ "" -> compileHaskellFile outExec+ _ -> putStrLn result++-- |Compile a scheme file to haskell+compileSchemeFile :: Env -> String -> String -> IOThrowsError LispVal+compileSchemeFile env stdlib filename = do+ -- TODO: it is only temporary to compile the standard library each time. It should be + -- precompiled and just added during the ghc compilation+ libsC <- compileLisp env stdlib "run" (Just "exec")+ execC <- compileLisp env filename "exec" Nothing+ outH <- liftIO $ openFile "_tmp.hs" WriteMode+ _ <- liftIO $ writeList outH header+ _ <- liftIO $ writeList outH $ map show libsC+ _ <- liftIO $ writeList outH $ map show execC+ _ <- liftIO $ hClose outH+ if not (null execC)+ then return $ Nil "" -- Dummy value+ else throwError $ Default "Empty file" --putStrLn "empty file"++-- |Compile the intermediate haskell file using GHC+compileHaskellFile :: String -> IO() --ThrowsError LispVal+compileHaskellFile filename = do+ let ghc = "ghc" -- Need to make configurable??+ compileStatus <- system $ ghc ++ " -cpp --make -package ghc -fglasgow-exts -o " ++ filename ++ " _tmp.hs"++-- TODO: delete intermediate hs files if requested++ case compileStatus of+ ExitFailure _code -> exitWith compileStatus+ ExitSuccess -> return ()++-- |Helper function to write a list of abstract Haskell code to file+writeList outH (l : ls) = do+ hPutStrLn outH l+ writeList outH ls+writeList outH _ = do+ hPutStr outH ""++
hs-src/Language/Scheme/Core.hs view
@@ -34,7 +34,7 @@ import System.IO version :: String-version = "3.5.2.1"+version = "3.5.2.2" showBanner :: IO () showBanner = do
husk-scheme.cabal view
@@ -1,5 +1,5 @@ Name: husk-scheme-Version: 3.5.2.1+Version: 3.5.2.2 Synopsis: R5RS Scheme interpreter, compiler, and library. Description: A dialect of R5RS Scheme written in Haskell. Provides advanced features including continuations, hygienic macros, a Haskell FFI,@@ -45,3 +45,8 @@ Main-is: shell.hs Hs-Source-Dirs: hs-src/Interpreter +Executable huskc+ Build-Depends: husk-scheme, base >= 2.0 && < 5, array, containers, haskeline, transformers, mtl, parsec, directory, ghc, ghc-paths, process, filepath, haskell98+ Extensions: ExistentialQuantification CPP CPP+ Main-is: huskc.hs+ Hs-Source-Dirs: hs-src/Compiler