-runPipeline
- :: [ (Phase, IntermediateFileType, String) ] -- phases to run
- -> (String,String) -- input file
- -> Bool -- doing linking afterward?
- -> Bool -- take into account -o when generating output?
- -> IO (String, String) -- return final filename
-
-runPipeline pipeline (input_fn,suffix) do_linking use_ofile
- = pipeLoop pipeline (input_fn,suffix) do_linking use_ofile basename suffix
- where (basename, _) = splitFilename input_fn
-
-pipeLoop [] input_fn _ _ _ _ = return input_fn
-pipeLoop (all_phases@((phase, keep, o_suffix):phases))
- (input_fn,real_suff) do_linking use_ofile orig_basename orig_suffix
- = do
-
- output_fn <- outputFileName (null phases) keep o_suffix
-
- mbCarryOn <- run_phase phase orig_basename orig_suffix
- input_fn output_fn
- -- sometimes we bail out early, eg. when the compiler's recompilation
- -- checker has determined that recompilation isn't necessary.
- case mbCarryOn of
- Nothing -> do
- let (_,keep,final_suffix) = last all_phases
- ofile <- outputFileName True keep final_suffix
- return (ofile, final_suffix)
- -- carry on ...
- Just fn -> do
- {-
- Check to see whether we've reached the end of the
- pipeline, but did so with an ineffective last stage.
- (i.e., it returned the input_fn as the output filename).
-
- If we did and the output is persistent, copy the contents
- of input_fn into the file where the pipeline's output is
- expected to end up.
- -}
- atEnd <- finalStage (null phases)
- when (atEnd && fn == input_fn)
- (copy "Saving away compilation pipeline's output"
- input_fn
- output_fn)
- {-
- Notice that in order to keep the invariant that we can
- determine a compilation pipeline's 'start phase' just
- by looking at the input filename, the input filename
- to the next stage/phase is associated here with the suffix
- of the output file, *even* if it does not have that
- suffix in reality.
-
- Why is this important? Because we may run a compilation
- pipeline in stages (cf. Main.main.compileFile's two stages),
- so when generating the next stage we need to be precise
- about what kind of file (=> suffix) is given as input.
-
- [Not having to generate a pipeline in stages seems like
- the right way to go, but I've punted on this for now --sof]
-
- -}
- pipeLoop phases (fn, o_suffix) do_linking use_ofile
- orig_basename orig_suffix
- where
- finalStage lastPhase = do
- o_file <- readIORef v_Output_file
- return (lastPhase && not do_linking && use_ofile && isJust o_file)
-
- outputFileName last_phase keep suffix
- = do o_file <- readIORef v_Output_file
- atEnd <- finalStage last_phase
- if atEnd
- then case o_file of
- Just s -> return s
- Nothing -> error "outputFileName"
- else if keep == Persistent
- then odir_ify (orig_basename ++ '.':suffix)
- else newTempName suffix
-
-run_phase :: Phase
- -> String -- basename of original input source
- -> String -- its extension
- -> FilePath -- name of file which contains the input to this phase.
- -> FilePath -- where to stick the result.
- -> IO (Maybe FilePath)
- -- Nothing => stop the compilation pipeline
- -- Just fn => the result of this phase can be found in 'fn'
- -- (this can either be 'input_fn' or 'output_fn').