On 12/17/2009 09:02 AM, Charles Oliver Nutter wrote:
> I may be naive, but what we really want here is simply a set of common
> protocols for doing the following:
>
> * Requesting from a language what types and methods are provided by a
> set of source files
> * Providing to a language services to look up types from other languages
If there are no dependency cycles, and the dependencies are known, then
it is easy: If files in language A depend on files in language B, but
not vice versa, just compile the files in language B before those in
language A, and then have language A's compiler read the B .class files.
We all do this, at least in the case that B==Java.
To handle dependency cycles or unknown dependies one can use a "compile
for export" option. This just generates a stub .class file, that
contains no code, or private fields, or anything else that is not
part of the "public contract" of the module. The key is that it
should be possible to generate this without reading any other
class files, and so cycles or other dependencies aren't a problem.
Generating the stub for Java is in theory easy: You can generate
stub method bodies by replacing all method bodies by "return null"
or whatever is appropriate for the method's return type, and
otherwise not checking for type compatibility and so. The import
statements allow replacing class names by the full-qualified names.
There are some complications: one is that import-on-depend does need
to search for other classes. So you need one extra step, as below.
So the multi-language compiler-driver does:
(1) Figure out the set of source files to (possibly) compile.
(2) For each source file, figure out the compiler to use, presumably
using extensions, though it could also use mime-types or looking at
the source file itself or some property datebase.
(3) For each source file, ask its compiler the set of class names
it might generate, using some to-be-specified simple protocol.
(4) For each source file, compile it "for export". I.e. generate
the stub .classes mentioned above, leaving them in some temporary
location (ideally a "MemoryFileSystem").
(5) For each source file, compile it for real, setting up the class
path to search the above temporary location first. When it needs to
import definitions from another file or class, it just reads the
sub class in "the normal way". The compiler should have access to
the map generated in (3), and should have a mechanism to invoke
the corresponding compiler "out of order". For example, a Scheme
library may want to execute a macro at compile time, and that
macro may depend on methods in some other class; thus it would
be nice to have a "compile this file first" mechanism.
This approach still means an API invoking compilers with various
options, but we don't need to invent a protocol for representing
types and modules - we just use the .class files.
--
--Per Bothner
[email protected] http://per.bothner.com/
--
You received this message because you are subscribed to the Google Groups "JVM
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en.