Thursday, December 22, 2011

Frege meets Eclipse

In this last post of 2011, I want to talk about my work on the upcoming Eclipse plugin for Frege -- codename fregIDE.
Update Jan 15, 2012:  fregIDE is meanwhile available for download, for details see the tutorial.

As I wrote in the previous post, I am using the IDE Meta Tooling Platform (IMP) and it looks like this was a fair choice. The  approach of IMP is very appealing (to me, anyway), here is a quote from their web page:
IMP lets you focus on your language, not Eclipse componentry.
IMP interfaces keep you focused on the stuff you know best: your language, and your models. Almost all of the complexities of Eclipse are hidden from you.
Although the last sentence is a bit of an exaggeration, it was indeed easy to get an editor with syntax coloring and error marking working. The most work to do here was on the Frege scanner. The scanner used to record line number and column for each token, but the syntax coloring mechanism requires source code offsets.

It turned out that I would need to keep the list of tokens to accommodate the way the Eclipse/IMP editor works: when there are any changes in the text (like when one types a character), it calls the component one has to supply called the Parser, which has to return a reference to something that is supposed to be an abstract syntax tree. Yet this value is never inspected or interpreted by IMP itself. Rather, it is given to other user supplied classes,  like the syntax coloring class. For example, IMP gives the value it got from the parser to the syntax colorer and says: I've got this from the parser, could you extract from this a token iterator for me? And later on, it calls a method that is supposed to color a single token and passes one of the tokens extracted from the iterator, where the type of the tokens is also opaque to the framework.

This approach is quite different from other frameworks I researched. For example, XText requires one to write the language from scratch with their own supplied tools. This may be nice when developing a small DSL that should forever live within the Eclipse world, but is completely inappropriate if one already has a compiler. IDEA apparently requires that one fits the language one wants to have supported in a Procrustean bed of interfaces they supply.  And so on.

Conversely, because the Frege compiler is essentially a computation in a state monad, it was too easy to fulfill the needs of the IMP. Just add a new field to the compiler state for the token list (that up to now used to get passed to the parser right away and then was forgotten), write a small helper class that implements the Iterator<T> interface and iterates over Frege lists and that was that. The abstract syntax tree is, of course, nothing but the compiler state. The IMP Frege parser (i.e. compiler driver written in java) does in essence nothing more than what the batch compiler driver does: it goes down the list of compiler passes and executes one after the other.

In short, I had to do only very small changes on existing compiler passes (with the exception of the scanner, see above). I just separated the concerns of compiler passes and compiler driver a bit clearer. For example, instead of just printing error messages to standard error, the messages are now collected and the compiler driver decides what to do with them. The batch compiler driver still writes them to standard error, while the fregIDE compiler driver creates error annotations in the source code editor.

This looks all very promising and I hope to provide the community with a basic version of the fregIDE early next year, which will then get enriched with features over time. The initial version will have project and preferences management, the editor with syntax coloring and live error markers and last but not least an incremental project builder. Support for run configurations will come for free because a Frege Project can only be established on top of a Java Project.