提交 cbdbbfd0 authored 作者: Thomas Mueller's avatar Thomas Mueller

A Java parser / Java to C converter.

上级 aa8d9681
...@@ -54,7 +54,9 @@ public class ClassObj { ...@@ -54,7 +54,9 @@ public class ClassObj {
*/ */
LinkedHashMap<String, MethodObj> methods = new LinkedHashMap<String, MethodObj>(); LinkedHashMap<String, MethodObj> methods = new LinkedHashMap<String, MethodObj>();
ArrayList<Statement> nativeInitializers = new ArrayList<Statement>(); ArrayList<Statement> nativeCode = new ArrayList<Statement>();
String id;
/** /**
* Add a method. * Add a method.
......
...@@ -21,14 +21,33 @@ public interface Expr { ...@@ -21,14 +21,33 @@ public interface Expr {
*/ */
class CallExpr implements Expr { class CallExpr implements Expr {
Expr expr; final JavaParser context;
String name; final Expr expr;
ArrayList<Expr> args = new ArrayList<Expr>(); final ArrayList<Expr> args = new ArrayList<Expr>();
final boolean isStatic;
final String className;
final String name;
CallExpr(JavaParser context, Expr expr, String className, String name, boolean isStatic) {
this.context = context;
this.expr = expr;
this.className = className;
this.name = name;
this.isStatic = isStatic;
}
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append(expr.toString() + "_" + JavaParser.toC(name)).append("("); if (className != null) {
buff.append(JavaParser.toC(className + "." + name)).append("(");
} else {
buff.append(JavaParser.toC(expr.getType().type.name + "." + name)).append("(");
}
int i = 0; int i = 0;
if (expr != null) {
buff.append(expr.toString());
i++;
}
for (Expr a : args) { for (Expr a : args) {
if (i > 0) { if (i > 0) {
buff.append(", "); buff.append(", ");
...@@ -38,10 +57,12 @@ class CallExpr implements Expr { ...@@ -38,10 +57,12 @@ class CallExpr implements Expr {
} }
return buff.append(")").toString(); return buff.append(")").toString();
} }
public Type getType() { public Type getType() {
// TODO // TODO
return null; return null;
} }
} }
/** /**
...@@ -136,9 +157,23 @@ class NewExpr implements Expr { ...@@ -136,9 +157,23 @@ class NewExpr implements Expr {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append("new " + type); if (arrayInitExpr.size() > 0) {
for (Expr e : arrayInitExpr) { if (type.isPrimitive) {
buff.append("[").append(e).append("]"); buff.append("NEW_ARRAY(sizeof(" + type + ")");
buff.append(", 1 ");
for (Expr e : arrayInitExpr) {
buff.append("* ").append(e);
}
buff.append(")");
} else {
buff.append("NEW_OBJ_ARRAY(1 ");
for (Expr e : arrayInitExpr) {
buff.append("* ").append(e);
}
buff.append(")");
}
} else {
buff.append("NEW_OBJ(" + type.id + ", " + type + ")");
} }
return buff.toString(); return buff.toString();
} }
...@@ -237,13 +272,23 @@ class VariableExpr implements Expr { ...@@ -237,13 +272,23 @@ class VariableExpr implements Expr {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
if (base != null) { if (field != null && "length".equals(field.name) && base != null && base.getType() != null && base.getType().arrayLevel > 0) {
buff.append(base.toString()).append("->"); buff.append("LENGTH(");
} buff.append(base.toString());
if (field != null) { buff.append(")");
buff.append(field.name);
} else { } else {
buff.append(JavaParser.toC(name)); if (base != null) {
buff.append(base.toString()).append("->");
}
if (field != null) {
if (field.isStatic) {
buff.append(JavaParser.toC(field.type.type.name + "." + field.name));
} else {
buff.append(field.name);
}
} else {
buff.append(JavaParser.toC(name));
}
} }
return buff.toString(); return buff.toString();
} }
...@@ -262,12 +307,12 @@ class VariableExpr implements Expr { ...@@ -262,12 +307,12 @@ class VariableExpr implements Expr {
*/ */
class ArrayExpr implements Expr { class ArrayExpr implements Expr {
Expr obj; Expr expr;
ArrayList<Expr> indexes = new ArrayList<Expr>(); ArrayList<Expr> indexes = new ArrayList<Expr>();
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append(obj.toString()); buff.append(expr.toString());
for (Expr e : indexes) { for (Expr e : indexes) {
buff.append('[').append(e.toString()).append(']'); buff.append('[').append(e.toString()).append(']');
} }
...@@ -275,7 +320,7 @@ class ArrayExpr implements Expr { ...@@ -275,7 +320,7 @@ class ArrayExpr implements Expr {
} }
public Type getType() { public Type getType() {
return obj.getType(); return expr.getType();
} }
} }
...@@ -10,6 +10,7 @@ import java.io.IOException; ...@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
...@@ -41,6 +42,8 @@ public class JavaParser { ...@@ -41,6 +42,8 @@ public class JavaParser {
private HashMap<String, ClassObj> classes = new HashMap<String, ClassObj>(); private HashMap<String, ClassObj> classes = new HashMap<String, ClassObj>();
private LinkedHashMap<String, FieldObj> localFields = new LinkedHashMap<String, FieldObj>(); private LinkedHashMap<String, FieldObj> localFields = new LinkedHashMap<String, FieldObj>();
private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>();
static { static {
String[] list = new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "if", String[] list = new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements", "package", "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements",
...@@ -122,6 +125,13 @@ public class JavaParser { ...@@ -122,6 +125,13 @@ public class JavaParser {
importMap.put(importClass, importPackageName); importMap.put(importClass, importPackageName);
read(";"); read(";");
} }
while (true) {
Statement s = readNativeStatementIf();
if (s == null) {
break;
}
nativeHeaders.add(s);
}
while (true) { while (true) {
classObj = new ClassObj(); classObj = new ClassObj();
classObj.isPublic = readIf("public"); classObj.isPublic = readIf("public");
...@@ -192,9 +202,12 @@ public class JavaParser { ...@@ -192,9 +202,12 @@ public class JavaParser {
break; break;
} }
thisPointer = null; thisPointer = null;
Statement s = readNativeStatementIf(); while (true) {
if (s != null) { Statement s = readNativeStatementIf();
classObj.nativeInitializers.add(s); if (s == null) {
break;
}
classObj.nativeCode.add(s);
} }
thisPointer = null; thisPointer = null;
boolean isStatic = false; boolean isStatic = false;
...@@ -354,6 +367,7 @@ public class JavaParser { ...@@ -354,6 +367,7 @@ public class JavaParser {
} }
StatementNative stat = new StatementNative(); StatementNative stat = new StatementNative();
stat.code = source.substring(start, current.index).trim(); stat.code = source.substring(start, current.index).trim();
current.index += 2;
read(); read();
return stat; return stat;
} }
...@@ -618,9 +632,7 @@ public class JavaParser { ...@@ -618,9 +632,7 @@ public class JavaParser {
if (readIf(".")) { if (readIf(".")) {
String n = readIdentifier(); String n = readIdentifier();
if (readIf("(")) { if (readIf("(")) {
CallExpr e2 = new CallExpr(); CallExpr e2 = new CallExpr(this, expr, null, n, false);
e2.expr = expr;
e2.name = n;
if (!readIf(")")) { if (!readIf(")")) {
while (true) { while (true) {
e2.args.add(readExpr()); e2.args.add(readExpr());
...@@ -696,11 +708,7 @@ public class JavaParser { ...@@ -696,11 +708,7 @@ public class JavaParser {
} }
String name = readIdentifier(); String name = readIdentifier();
if (readIf("(")) { if (readIf("(")) {
CallExpr expr = new CallExpr(); CallExpr expr = new CallExpr(this, null, classObj.name, name, false);
expr.name = name;
VariableExpr ve = new VariableExpr();
ve.field = thisPointer;
expr.expr = ve;
if (!readIf(")")) { if (!readIf(")")) {
while (true) { while (true) {
expr.args.add(readExpr()); expr.args.add(readExpr());
...@@ -720,13 +728,41 @@ public class JavaParser { ...@@ -720,13 +728,41 @@ public class JavaParser {
f = classObj.instanceFields.get(name); f = classObj.instanceFields.get(name);
if (f == null) { if (f == null) {
String imp = importMap.get(name); String imp = importMap.get(name);
if (imp == null) {
imp = JAVA_IMPORT_MAP.get(name);
}
if (imp != null) { if (imp != null) {
name = imp; name = imp;
if (readIf(".")) {
String n = readIdentifier();
if (readIf("(")) {
CallExpr e2 = new CallExpr(this, null, imp, n, true);
if (!readIf(")")) {
while (true) {
e2.args.add(readExpr());
if (!readIf(",")) {
read(")");
break;
}
}
}
return e2;
}
VariableExpr e2 = new VariableExpr();
// static member variable
e2.name = imp + "." + n;
ClassObj c = classes.get(imp);
FieldObj sf = c.staticFields.get(n);
e2.field = sf;
return e2;
}
// TODO static field or method of a class
} }
} else {
expr.field = f;
} }
} }
} }
expr.field = f;
if (f != null && (!f.isLocal && !f.isStatic)) { if (f != null && (!f.isLocal && !f.isStatic)) {
VariableExpr ve = new VariableExpr(); VariableExpr ve = new VariableExpr();
ve.field = thisPointer; ve.field = thisPointer;
...@@ -1143,16 +1179,17 @@ public class JavaParser { ...@@ -1143,16 +1179,17 @@ public class JavaParser {
* @param out the output writer * @param out the output writer
*/ */
void writeHeader(PrintWriter out) { void writeHeader(PrintWriter out) {
for (Statement s : nativeHeaders) {
out.println(s);
}
out.println();
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".h */"); out.println("/* " + c.name + ".h */");
for (FieldObj f : c.staticFields.values()) { for (FieldObj f : c.staticFields.values()) {
if (f.isFinal) { if (f.isFinal) {
out.println("#define " + toC(c.name + "." + f.name) + " (" + f.value + ")"); out.println("#define " + toC(c.name + "." + f.name) + " (" + f.value + ")");
} else { } else {
out.print("extern " + toC(f.type.toString()) + " " + f.name); out.print("extern " + toC(f.type.toString()) + " " + toC(c.name + "." + f.name));
if (f.value != null) {
out.print(" = " + f.value);
}
out.println(";"); out.println(";");
} }
} }
...@@ -1164,7 +1201,11 @@ public class JavaParser { ...@@ -1164,7 +1201,11 @@ public class JavaParser {
} }
out.println(";"); out.println(";");
} }
if (c.instanceFields.size() == 0) {
out.println("int dummy;");
}
out.println("};"); out.println("};");
out.println("typedef struct " + toC(c.name) + " " + toC(c.name) + ";");
for (MethodObj m : c.methods.values()) { for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "("); out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0; int i = 0;
...@@ -1193,9 +1234,18 @@ public class JavaParser { ...@@ -1193,9 +1234,18 @@ public class JavaParser {
void writeSource(PrintWriter out) { void writeSource(PrintWriter out) {
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".c */"); out.println("/* " + c.name + ".c */");
for (Statement s : c.nativeInitializers) { for (Statement s : c.nativeCode) {
out.println(s); out.println(s);
} }
for (FieldObj f : c.staticFields.values()) {
if (!f.isFinal) {
out.print(toC(f.type.toString()) + " " + toC(c.name + "." + f.name));
if (f.value != null) {
out.print(" = " + f.value);
}
out.println(";");
}
}
for (MethodObj m : c.methods.values()) { for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "("); out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0; int i = 0;
...@@ -1257,6 +1307,10 @@ public class JavaParser { ...@@ -1257,6 +1307,10 @@ public class JavaParser {
return identifier.replace('.', '_'); return identifier.replace('.', '_');
} }
ClassObj getClassObj() {
return classObj;
}
} }
/** /**
......
...@@ -12,7 +12,9 @@ import java.util.ArrayList; ...@@ -12,7 +12,9 @@ import java.util.ArrayList;
* A statement. * A statement.
*/ */
public interface Statement { public interface Statement {
// toString // toString
} }
/** /**
...@@ -143,9 +145,21 @@ class ForStatement implements Statement { ...@@ -143,9 +145,21 @@ class ForStatement implements Statement {
StringBuffer buff = new StringBuffer(); StringBuffer buff = new StringBuffer();
buff.append("for ("); buff.append("for (");
if (iterableType != null) { if (iterableType != null) {
buff.append(iterableType).append(' '); Type it = iterable.getType();
buff.append(iterableVariable).append(": "); if (it != null && it.arrayLevel > 0) {
buff.append(iterable); String idx = "i_" + iterableVariable;
buff.append("int " + idx + " = 0; " + idx + " < LEN(" + iterable + "); " + idx + "++");
buff.append(") {\n");
buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable + "["+ idx +"];\n"));
buff.append(block.toString()).append("}");
} else {
// TODO iterate over a collection
buff.append(iterableType).append(' ');
buff.append(iterableVariable).append(": ");
buff.append(iterable);
buff.append(") {\n");
buff.append(block.toString()).append("}");
}
} else { } else {
buff.append(init.toString()); buff.append(init.toString());
buff.append(" ").append(condition.toString()).append("; "); buff.append(" ").append(condition.toString()).append("; ");
...@@ -155,9 +169,9 @@ class ForStatement implements Statement { ...@@ -155,9 +169,9 @@ class ForStatement implements Statement {
} }
buff.append(updates.get(i)); buff.append(updates.get(i));
} }
buff.append(") {\n");
buff.append(block.toString()).append("}");
} }
buff.append(") {\n");
buff.append(block.toString()).append("}");
return buff.toString(); return buff.toString();
} }
} }
......
...@@ -34,7 +34,6 @@ public class Test extends TestBase { ...@@ -34,7 +34,6 @@ public class Test extends TestBase {
// import * // import *
// initializer blocks // initializer blocks
// access to static fields with instance variable // access to static fields with instance variable
// method call with "this": this.toString()
// final variables (within blocks, parameter list) // final variables (within blocks, parameter list)
// Identifier : (labels) // Identifier : (labels)
// ClassOrInterfaceDeclaration within blocks (or any other nested classes) // ClassOrInterfaceDeclaration within blocks (or any other nested classes)
...@@ -56,6 +55,7 @@ public class Test extends TestBase { ...@@ -56,6 +55,7 @@ public class Test extends TestBase {
assertEquals("6.022137e+23f", JavaParser.readNumber("6.022137e+23f+1")); assertEquals("6.022137e+23f", JavaParser.readNumber("6.022137e+23f+1"));
JavaParser parser = new JavaParser(); JavaParser parser = new JavaParser();
parser.parse("src/tools/org/h2", "java.lang.Object");
parser.parse("src/tools/org/h2", "java.lang.String"); parser.parse("src/tools/org/h2", "java.lang.String");
parser.parse("src/tools/org/h2", "java.io.PrintStream"); parser.parse("src/tools/org/h2", "java.io.PrintStream");
parser.parse("src/tools/org/h2", "java.lang.System"); parser.parse("src/tools/org/h2", "java.lang.System");
......
package org.h2.java.lang; package org.h2.java.lang;
/* c:
#define boolean int
#define LENGTH(a) (*(((int*)(a))-1))
#define NEW_ARRAY(size, length) new_array(0, size, length)
#define NEW_OBJ_ARRAY(length) new_array(1, sizeof(void*), length)
#define NEW_OBJ(type, size) new_object(type, sizeof(struct type))
#define SET(variable, p) set_object(variable, p)
void* new_array(int object, int size, int length);
void* new_object(int type, int size);
void* set_object(void** target, void* o);
*/
/** /**
* A java.lang.String implementation. * A java.lang.String implementation.
*/ */
public class String { public class String {
/* c:
#include <stdlib.h>
void* new_array(int object, int size, int length) {
int count = sizeof(int) * 2 + size * length;
int* m = (int*) calloc(1, count);
*m = object << 31 + length;
*(m+1) = 1;
return m + 2;
}
void* new_object(int type, int size) {
int count = sizeof(int) * 2 + size;
int* m = (int*) calloc(1, count);
*m = type;
*(m+1) = 1;
return m + 2;
}
void* set_object(void** target, void* o) {
int* m = (int*) target;
if (*(m - 2) == 1) {
free(m - 1);
} else {
(*(m - 2))--;
}
*target = o;
m = (int*) target;
if (o != 0) {
(*(m - 2))++;
}
}
*/
private char[] chars; private char[] chars;
private int hashCode; private int hashCode;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论