CompilerOverview

Overview

This topic is intended to provide an overview of the compiler in its goals, structure, and functioning. Please read and make notes to improve the clarity and quality of this document.

Broadly, the compiler follows the classical architecture in the following ways. TheReader encompasses the scanner and parser, taking in the lisp code and spitting out a lisp style list datastructure (see lisp.common.list). The job of the compiler is to generate java byte code from this list.

compiler_arch.jpg clj_compiler_arch.jpg

Compile

The compiler is invoked by calling the 'compile' function from lisp: (compile foo). This correlates to the java class found in Compile.java under the lisp.system.compiler package. Perusing Compile.java will find the following lines (more or less):

java.util.Vector v = (java.util.Vector)icg.funcall(sa.funcall(obj));
OolongClass[] oc = (OolongClass[])v.toArray(new OolongClass[v.size()]);
classBytes = assembler.assemble(oc);
classesLoaded = loadClasses(classBytes, oc);

Here 'obj' is compiled and loaded by first passing through the SemanticAnalyzer: sa.funcall(obj). Then through the IntermediateCodeGeneration: icg.funcall( ... ). The resulting vector of OolongClass? objects is converted to an array and passed to the oolong assembler: assembler.assemble(oc). The resulting java bytecode classes are loaded using the CompilerClassLoader? : loadClasses(classBytes, oc). The classes are then passed back to the calling function where the classes can then be instantiated and funcalls made.

SemanticAnalyzer

At the time of writing the SemanticAnalyzer is largely unformed, but the current plan is to create a set of macros that will transform and annotate the list for the icg to process. The list will be recursively iterated through checking for proper semantics and calling the macro transformations.

IntermediateCodeGeneration

The format of the IntermediateCodeGeneration is based mostly around the emitter found in Emitter.java.

Emitter:

The function of the emitter is to provide a clean interface to constructing OolongClass? objects (the output of the icg). The emitter allows the creation of new classes through the newClass(), new fields with the newField() method, and new methods through the newMethod() method. Classes are kept in a stack so new classes can be created before finishing with the old class. To finish the creation of a class the endClass() method is invoked, the class is popped off the stack and the emitter now emits to the class on top of the stack. Methods do not need to be ended (since they are not on a stack). Simply creating a new method will end the current one.

Emitting lines into a method is done by calling the emit...() methods. There is one emit method for each of the oolong bytecodes (mostly the same as the java bytecodes, see Engel's book) plus a few for handiness (such as emitNil()). For example, to emit 'aload_0' into the method you would call

emitter.emitAload(0);

OolongClass? :

The OolongClass? objects represent the new oolong coded classes in the making. They are turned into streams of characters (which oolong then assembles) via the toString() method. See javadoc for further details.

References

  • Programming for the Java Virtual Machine, Joshua Engel
  • CLJcompiler

Implementation

Core Java Classes
Compile.java
SemanticAnalyzer.java
IntermediateCodeGeneration.java
Oolong.java
OolongClass? .java
OolongMethod? .java
OolongField? .java

Discussions

Links to Blog issues

Current Status of CompilerOverview

Status:

Release Level:

Open bug count:

Topic revision: r5 - 2009-03-11 - 20:26:23 - MadelineWilliams
 
Home
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback