Java2D III

xs0 xs0 at xs0.com
Fri Jul 21 02:45:25 PDT 2006


BLS wrote:
> okay,
> the Java Parser, the Java AST Parser and very basic work on the D Emitter
> are done.
> 
> DEmitter > A class that can take an ANTLR Java AST and produce formatted
>  D Java code from it
> 
> I guess the string, array and modifiers stuff will be tricky.

Arrays will be the trickiest - they're objects in Java, but something 
completely different in D (better, but totally not-compatible). While it 
may seem that it can be easily be solved with a template Array object, 
it can't for the simple reason, that a Derived[] is also a Base[] (but 
you can't put non-Derived object inside), and that's just not 
practically doable. You'd have to list all superclasses/interfaces for 
each array class that appears..

I can't think of a reasonable implementation that would mimic the arrays 
in Java, so I guess the only choice is to have a single implementation 
(non-templated) which keeps the element class type at runtime and checks 
on writes. That's bad, because the information on types of arrays is 
lost in source..


> anyway, first things first :the following table has to be transformed :
> is somebody out there who is kind enough to give me advice regarding the
> modifieres stuff : well translationg the table to D is also highly welcome
> <g>

>   tokenNames[FINAL]="final";

becomes either final (for classes and methods) or const (for variables)

>   tokenNames[LITERAL_package]="package";

Ideally, you will take several classes and place them into one module; 
that way, their FQNs (full names) stay about the same. However, there is 
a problem there - you can't have both modules "foo.bar" and 
"foo.bar.baz" in D. But, since the packages do not form a hierarchy in 
Java (foo, foo.bar and foo.baz are as distinct as kuku, abc.def and 
qwe.dfg), you can rename them to something like foo.bar and foo_bar.baz 
for the above case.

>   tokenNames[LITERAL_import]="import";

This will be tricky; you can either import
a) a normal class (java.util.HashMap),
b) an inner class (java.util.Map.Entry),
c) all members of a package (java.util.*),

For the first two cases, you can also import
d) one static member (import static java.lang.Math.PI) or
e) all static members of a class (import static java.lang.Math.*)

Assuming you do convert packages into modules (so a module contains all 
classes from a Java package), those become

a)
static import java.util;
alias java.util.HashMap HashMap;

b)
static import java.util;
alias java.util.Map.Entry Entry;

c)
private import java.util; // private now optional

d)
static import java.lang;
alias java.lang.Math.PI PI;

e)
static import java.lang;
alias java.lang.Math.sin sin;
alias java.lang.Math.cos cos;
etc.

To get the last case just right, some analysis of class contents will 
have to be made...


>   tokenNames[LITERAL_private]="private";

this is still private, though it doesn't have the same effect - in Java 
private really means private, while in D it's module-private.

>   tokenNames[LITERAL_transient]="transient";

this is used for serialization only, can be dropped (and there is no 
equivalent in D)

>   tokenNames[LITERAL_native]="native";

luckily, no longer needed :) unluckily, you have to get the code for 
such a function from somewhere else, and it's probably C/C++

>   tokenNames[LITERAL_threadsafe]="threadsafe";

never heard of this..

>   tokenNames[LITERAL_synchronized]="synchronized";

when used with an expression, it's the same as in D, but can also be a 
modifier for functions. With non-static methods,

synchronized func()
{
}

becomes

func()
{
     synchronized(this) {
     }
}

With static methods, its synchronized(ClassName.class) in Java, I'm not 
sure whether something similar can be used in D (is TypeInfo an object 
or a struct?)

>   tokenNames[LITERAL_volatile]="volatile";

There are no volatile variables in D, so this is quite tricky; 
theoretically, you'd have to wrap each access of such a variable into a 
volatile statement...

>   tokenNames[LITERAL_throws]="throws";

These can be dropped (or even better - converted to DDoc ;)

>   tokenNames[LITERAL_case]="case";
>   tokenNames[LITERAL_default]="default";

Note that there's an implicit "default: assert(0)" in D, but an implicit 
"default: break" in Java.

>   tokenNames[LITERAL_instanceof]="instanceof";

expr instanceof ClassName
becomes
(cast(ClassName)expr)

No need to compare it to null, as it will be automatically done.

>   tokenNames[LITERAL_this]="this";

For inner classes, you can have an expressions OuterClass.this; no such 
thing in D..

>   tokenNames[LITERAL_new]="new";

In Java, you can write "new Foo().method()", in D it must be "(new 
Foo).method()".

Hope that helps :)


xs0



More information about the Digitalmars-d-announce mailing list