| www.delorie.com/gnu/docs/kawa/kawa-tour_17.html | search |
![]() Buy GNU books! | |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A Scheme quoted form or self-evaluating form expands to a QuoteExp.
Compiling a QuoteExp would seem a trivial exercise, but it is not.
There is no way to embed (say) a list literal in Java code.
Instead we create a static field in the top-level class
for a each (different) QuoteExp in the body we are compiling.
The code compiled for a QuoteExp then just needs
to load the value from the corresponding static field.
The tricky part is making sure that the static field gets
initialized (when the top-level class is loaded) to the
value of the quoted form.
The basic idea is that for:
(define (foo) '(3 . 4)) |
we compile:
class foo extends Procedure0 {
Object static lit1;
public foo ()
{ // Initializer
lit1 = new Pair(IntNum.make(3), IntNum.make(4));
}
public Object apply0 ()
{ return lit1; }
}
|
When the compiled class foo is loaded, we do:
Class fooCl = Class.forName("foo");
Procedure fooPr = (Procedure) fooCl.newInstance ();
// Using foo:
Object result = fooPr.apply0 ();
|
How does the Kawa compiler generate the appropriate new Pair
expression as shown above? A class whose instances may appear
in a quoted form implements the Compilable interface:
interface Compilable {
Literal makeLiteral (Compilation comp);
void emit (Literal literal, Compilation comp);
|
The makeLiteral creates a Literal object
that represents the value of this object.
That Literal is later passed to emit, which emits
bytecode instructions that (when evaluated) cause a value
equal to this to be pushed on the Java evaluation stack.
This two-part protocol may be overkill, but it makes it possible to combine duplicate constants and it also supports circularly defined constants. (Standard Scheme does not support self-referential constants, but Common Lisp does. See section 25.1.4 Similarity of Constants in G. L. Steele Jr.: Common Lisp - The Language, Digital Press and Prentice-Hall, second edition, 1990.
It is likely that the Compilable interface will
be replaced in the future with the serialization features
of JDK 1.1.
If we are compiling for immediate execution, we do not need
to generate code to regenerate the literal. In fact, we want to
re-use the literal from the original source form.
The problem is passing the source literal to the
byte-compiled class. To do that, we use the CompiledProc
interface.
interface CompiledProc {
public abstract void setLiterals (Object[] values);
}
|
An immediate class compiled from a top-level form implements
the CompiledProc form. After an instance of the ModuleBody
has been created, it is coerced to a CompiledProc, and
setLiterals is called. The argument to setLiterals
is an array of the necessary literal values, and the method
that implements it in the compiled code causes the array of literal
values to be saved in the ModuleBody instance, so it can
be accessed by the compiled code.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| webmaster donations bookstore | delorie software privacy |
| Copyright © 2003 by The Free Software Foundation | Updated Jun 2003 |