How to modularize parse analyze phases in the compiler

raph-amiard edited this page May 25, 2012 · 3 revisions


Some parts in the parse/analyze phases of the compiler are specific to Javascript, and thus need to be modularized. Here is a list of those things. I may have forgotten things, so don't hesitate to tell me if i did.

  • Functions
    • munge
    • js-var
  • Vars
    • js-reserved

For the moment, this seems to be mainly related to the handling of symbols and vars in the target language.

There are several ways of making those things modular. The global idea is that the parse/analyze phases will be called as a library by the backend implementers. Those will have to provide the backend specific parts before calling the analyzer. This could be done in one of the following ways :

### First option : Dynamically bound vars for all modular parts

The first option is to make all the things that are backend specific dynamically bound

    (def ^:dynamic js-reserved #{...})

This is the simplest option. It has the advantage of being easy to implement, but it has several drawbacks:

  • You have to bind every of them in the context in which you want to use the analyzer
  • It forms a disparate interface that you can't document in one place in the code
  • There is no "unique" point of dispatch

Second option : Use a protocol

The second option is to regroup all moving part into a protocol

(defprotocol Emitter
  (js-reserved [e])
  (munge [e s])
  (js-var [e s]))

This solution overcomes the drawbacks of the previous option, but you still have to provide an instance of a type implementing the protocol to the analyzer.

How to provide the protocol instance ?

  • The first option is to pass it around explicitly as a function argument everywhere in the compiler's code. This implies a quite large (albeit simple) refactor, and we're taking the risk of making the code harder to understand.
  • The second option is to bind it dynamically. It will be less explicit, so maybe harder to understand for a newcomer, but easier to manage right now as an incremental refactoring, and could (in my opinion) make the code clearer and easier to maintain by not cluttering it with passing the same parameter around everywhere.

I'm open to suggestions ! I can't post on confluence right now, so if you have suggestions, just mail them to me.