Saturday, June 25, 2011

Dumbing down the GhcOptions record

I've decided to change the approach I'm taking to my Summer of Code project allowing Cabal's code for building with GHC to accommodate interpretation. Previously I had planned make the options record describing the arguments given to GHC very high level, essentially consisting of a mode option (ie executable, library, interpretation, abi-hash, etc) and a stage option (C stage, Template Haskell stage, link stage, etc). A rendering function would translate this pair of options to a list of command line flags.

Now, the GhcOptions record has become a direct representation of the command line options; every flag used in building Cabal packages can be adjusted individually. Creating the options for a particular mode and stage consists of glueing together (through mappend) a long list of GhcOptions pieces. There's pieces for (among others) build options, c options and verbosity options, allowing much more fine grained control of the options given to GHC.

Wednesday, June 15, 2011

Reloading GHCi

Starting GHCi with Cabal is fairly easy, as the interpreter takes most of the same arguments we've been feeding GHC. But reloading it is a little more difficult. Admittedly, there are a number of things we don't have to do when reloading:

  • All the options given to the interpreter initially seem to come along for the ride with each :reload command, so rendering GHC command line options isn't necessary.
  • Preparing the build directory and auto-generated files already took place when the interpreter was started, so that stuff isn't required for a reload.

In fact, there are only really two things that need doing. First, there's preprocessing. This is a high level operation not specific to a compiler. At the same time, there's C sources, a step in building restricted to GHC.

I propose adding a flag (--reload, perhaps) to the repl command to handle these two operations, handled by the high level Build.hs code to perform preprocessing and the compiler specific GHC.hs code to perform C source building. Macros would be defined in GHCi to shadow those commands resulting in code reloading, calling cabal repl FILENAME --reload first.

To define these macros, I think I'll need to modify GHCi to take a custom .ghci file. I can't just sneakily add to the user one, and piping in the commands through cat or something would look ugly. As it is, I think the best approach is to add an option for an extra .ghci file. Cabal would write its set of macros to shadow default commands to some place in the dist directory, telling GHCi about the the file.

Tuesday, June 14, 2011

Almost a Quine

To allow reloading from GHCi to trigger all the necessary Cabal preparation, I need to define macros to shadow the default commands (:r, :l, etc) . The basic idea for each of these macros is pretty simple:
  • Call whatever programs needed for preparing the package for building
  • Un-define the command so that the default behavior returns
  • Call the default command
  • Respecify the custom implementation
  • Redefine the command
Each of these macros must thus define itself again, creating a macro within a macro. Naturally, as this behavior is shared by all the overloaded GHCi commands, I created a macro to abstract this pattern. That's a string defining a macro to make a macro to make a macro. While this kind of thing is fine (almost expected) in Lisp, it doesn't work quite so well in Haskell, especially as syntax is just represented as a string.