99
1010module Gibbon.Compiler
1111 ( -- * Compiler entrypoints
12- compile , compileCmd
12+ compile , compileFromL0 , compileCmd
1313 -- * Configuration options and parsing
1414 , Config (.. ), Mode (.. ), Input (.. )
1515 , configParser , configWithArgs , defaultConfig
@@ -163,7 +163,8 @@ configParser = Config <$> inputParser
163163 flag' RunMPL (long " mpl-run" <> help " Emit SML, compile with MPL, and run" ) <|>
164164 (Bench . toVar <$> strOption (short ' b' <> long " bench-fun" <> metavar " FUN" <>
165165 help (" Generate code to benchmark a 1-argument FUN against a input packed file." ++
166- " If --bench-input is provided, then the benchmark is run as well." )))
166+ " If --bench-input is provided, then the benchmark is run as well." ))) <|>
167+ (Library <$> toVar <$> strOption (long " lib" <> metavar " FUN" <> help (" Compile as a library with its entry point given." )))
167168
168169 -- use C as the default backend
169170 backendParser :: Parser Backend
@@ -210,7 +211,7 @@ data CompileState a = CompileState
210211-- | Compiler entrypoint, given a full configuration and a list of
211212-- files to process, do the thing.
212213compile :: Config -> FilePath -> IO ()
213- compile config@ Config {mode, input,verbosity,backend,cfile } fp0 = do
214+ compile config@ Config {input,verbosity} fp0 = do
214215 -- set the env var DEBUG, to verbosity, when > 1
215216 setDebugEnvVar verbosity
216217
@@ -219,6 +220,11 @@ compile config@Config{mode,input,verbosity,backend,cfile} fp0 = do
219220 let fp1 = dir </> fp0
220221 -- Parse the input file
221222 ((l0, cnt0), fp) <- parseInput config input fp1
223+ compileFromL0 config cnt0 fp l0
224+
225+
226+ compileFromL0 :: Config -> Int -> FilePath -> L0. Prog0 -> IO ()
227+ compileFromL0 config@ Config {mode,backend,cfile} cnt0 fp l0 = do
222228 let config' = config { srcFile = Just fp }
223229
224230 let initTypeChecked :: L0. Prog0
@@ -272,19 +278,8 @@ compile config@Config{mode,input,verbosity,backend,cfile} fp0 = do
272278 C -> codegenProg config' l4
273279
274280
275-
276- LLVM -> error $ " Cannot execute through the LLVM backend. To build Gibbon with LLVM: "
277- ++ " stack build --flag gibbon:llvm_enabled"
278-
279- -- The C code is long, so put this at a higher verbosity level.
280- dbgPrint passChatterLvl $ " [compiler] Final C codegen: " ++ show (length str) ++ " characters."
281- dbgPrintLn 4 $ sepline ++ " \n " ++ str
282-
283- clearFile outfile
284- writeFile outfile str
285-
286281 -- (Stage 3) Code written, now compile if warranted.
287- when (mode == ToExe || mode == RunExe || isBench mode ) $ do
282+ when (mode == ToExe || mode == RunExe || isBench mode || isLibrary mode ) $ do
288283 compileAndRunExe config fp >>= putStr
289284 return ()
290285
@@ -423,6 +418,7 @@ compileAndRunExe cfg@Config{backend,arrayInput,benchInput,mode,cfile,exefile} fp
423418 _ -> return " "
424419 where outfile = getOutfile backend fp cfile
425420 exe = getExeFile backend fp exefile
421+ doto = replaceExtension fp " .o"
426422 pointer = gopt Opt_Pointer (dynflags cfg)
427423 links = if pointer
428424 then " -lgc -lm "
@@ -432,13 +428,14 @@ compileAndRunExe cfg@Config{backend,arrayInput,benchInput,mode,cfile,exefile} fp
432428 lib_dir <- getRTSBuildDir
433429 let rts_o_path = lib_dir </> " gibbon_rts.o"
434430 let compile_prog_cmd = compilationCmd backend cfg
435- ++ " -o " ++ exe
431+ ++ ( if isLibrary mode then ( " -c - o " ++ doto) else ( " -o " ++ exe))
436432 ++ " -I" ++ lib_dir
437433 ++ " -L" ++ lib_dir
438434 ++ " -Wl,-rpath=" ++ lib_dir ++ " "
439435 ++ outfile ++ " " ++ rts_o_path
440436 ++ links ++ " -lgibbon_rts_ng"
441437
438+ putStrLn compile_prog_cmd
442439 execCmd
443440 Nothing
444441 compile_prog_cmd
@@ -541,6 +538,10 @@ isBench :: Mode -> Bool
541538isBench (Bench _) = True
542539isBench _ = False
543540
541+ isLibrary :: Mode -> Bool
542+ isLibrary (Library _) = True
543+ isLibrary _ = False
544+
544545-- | The debug level at which we start to call the interpreter on the program during compilation.
545546interpDbgLevel :: Int
546547interpDbgLevel = 5
0 commit comments