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

A Java parser / Java to C converter.

上级 ee98e77a
...@@ -14,6 +14,17 @@ import java.util.LinkedHashMap; ...@@ -14,6 +14,17 @@ import java.util.LinkedHashMap;
*/ */
public class ClassObj { public class ClassObj {
/**
* The super class (null for java.lang.Object or primitive types).
*/
String superClassName;
/**
* The list of interfaces that this class implements.
*/
ArrayList<String> interfaceNames = new ArrayList<String>();
/** /**
* The fully qualified class name. * The fully qualified class name.
*/ */
...@@ -69,6 +80,9 @@ public class ClassObj { ...@@ -69,6 +80,9 @@ public class ClassObj {
*/ */
int id; int id;
/**
* Get the base type of this class.
*/
Type baseType; Type baseType;
ClassObj() { ClassObj() {
...@@ -117,13 +131,20 @@ public class ClassObj { ...@@ -117,13 +131,20 @@ public class ClassObj {
return name; return name;
} }
String getMethodName(String find, ArrayList<Expr> args) { /**
* Get the method.
*
* @param find the method name in the source code
* @param args the parameters
* @return the method
*/
MethodObj getMethod(String find, ArrayList<Expr> args) {
ArrayList<MethodObj> list = methods.get(find); ArrayList<MethodObj> list = methods.get(find);
if (list == null) { if (list == null) {
return name; throw new RuntimeException("Method not found: " + name);
} }
if (list.size() == 1) { if (list.size() == 1) {
return list.get(0).name; return list.get(0);
} }
for (MethodObj m : list) { for (MethodObj m : list) {
if (!m.isVarArgs && m.parameters.size() != args.size()) { if (!m.isVarArgs && m.parameters.size() != args.size()) {
...@@ -143,10 +164,10 @@ public class ClassObj { ...@@ -143,10 +164,10 @@ public class ClassObj {
} }
} }
if (match) { if (match) {
return m.name; return m;
} }
} }
return name; throw new RuntimeException("Method not found: " + name);
} }
} }
...@@ -156,6 +177,9 @@ public class ClassObj { ...@@ -156,6 +177,9 @@ public class ClassObj {
*/ */
class MethodObj { class MethodObj {
/**
* Whether the last parameter is a var args parameter.
*/
boolean isVarArgs; boolean isVarArgs;
/** /**
...@@ -168,6 +192,11 @@ class MethodObj { ...@@ -168,6 +192,11 @@ class MethodObj {
*/ */
boolean isPrivate; boolean isPrivate;
/**
* Whether this method is overridden.
*/
boolean isVirtual;
/** /**
* The name. * The name.
*/ */
...@@ -276,6 +305,9 @@ class Type { ...@@ -276,6 +305,9 @@ class Type {
*/ */
int arrayLevel; int arrayLevel;
/**
* Whether this is a var args parameter.
*/
boolean isVarArgs; boolean isVarArgs;
public String toString() { public String toString() {
......
...@@ -44,8 +44,14 @@ class CallExpr implements Expr { ...@@ -44,8 +44,14 @@ class CallExpr implements Expr {
} else { } else {
classObj = expr.getType().classObj; classObj = expr.getType().classObj;
} }
String methodName = classObj.getMethodName(name, args); MethodObj m = classObj.getMethod(name, args);
buff.append(JavaParser.toC(classObj.toString() + "." + methodName)).append("("); String methodName;
if (m.isVirtual) {
methodName = "*virtual_" + m.name + "[CLASS_ID("+expr.toString()+")]";
} else {
methodName = JavaParser.toC(classObj.toString() + "." + m.name);
}
buff.append(methodName).append("(");
int i = 0; int i = 0;
if (expr != null) { if (expr != null) {
buff.append(expr.toString()); buff.append(expr.toString());
......
...@@ -45,6 +45,7 @@ public class JavaParser { ...@@ -45,6 +45,7 @@ public class JavaParser {
private HashMap<String, String> importMap = new HashMap<String, String>(); private HashMap<String, String> importMap = new HashMap<String, String>();
private HashMap<String, ClassObj> classes = new HashMap<String, ClassObj>(); private HashMap<String, ClassObj> classes = new HashMap<String, ClassObj>();
private LinkedHashMap<String, FieldObj> localVars = new LinkedHashMap<String, FieldObj>(); private LinkedHashMap<String, FieldObj> localVars = new LinkedHashMap<String, FieldObj>();
private HashMap<String, MethodObj> allMethodsMap = new HashMap<String, MethodObj>();
private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>(); private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>();
...@@ -141,20 +142,37 @@ public class JavaParser { ...@@ -141,20 +142,37 @@ public class JavaParser {
nativeHeaders.add(s); nativeHeaders.add(s);
} }
while (true) { while (true) {
classObj = new ClassObj(); boolean isPublic = readIf("public");
classObj.id = classId++; boolean isInterface;
classObj.isPublic = readIf("public");
if (readIf("class")) { if (readIf("class")) {
classObj.isInterface = false; isInterface = false;
} else { } else {
read("interface"); read("interface");
classObj.isInterface = true; isInterface = true;
} }
String name = readIdentifier(); String name = readIdentifier();
classObj = BUILT_IN_TYPES.get(packageName + "." + name);
if (classObj == null) {
classObj = new ClassObj();
classObj.id = classId++;
}
classObj.isPublic = isPublic;
classObj.isInterface = isInterface;
classObj.name = packageName == null ? "" : (packageName + ".") + name; classObj.name = packageName == null ? "" : (packageName + ".") + name;
// import this class // import this class
importMap.put(name, classObj.name); importMap.put(name, classObj.name);
classes.put(classObj.name, classObj); classes.put(classObj.name, classObj);
if (readIf("extends")) {
classObj.superClassName = readQualifiedIdentifier();
}
if (readIf("implements")) {
while (true) {
classObj.interfaceNames.add(readQualifiedIdentifier());
if (!readIf(",")) {
break;
}
}
}
parseClassBody(); parseClassBody();
if (current.token == null) { if (current.token == null) {
break; break;
...@@ -274,6 +292,7 @@ public class JavaParser { ...@@ -274,6 +292,7 @@ public class JavaParser {
method.block = readStatement(); method.block = readStatement();
} }
classObj.addMethod(method); classObj.addMethod(method);
addMethod(method);
} else { } else {
String name = readIdentifier(); String name = readIdentifier();
method.name = name; method.name = name;
...@@ -283,6 +302,7 @@ public class JavaParser { ...@@ -283,6 +302,7 @@ public class JavaParser {
method.block = readStatement(); method.block = readStatement();
} }
classObj.addMethod(method); classObj.addMethod(method);
addMethod(method);
} else { } else {
FieldObj field = new FieldObj(); FieldObj field = new FieldObj();
field.type = type; field.type = type;
...@@ -311,6 +331,19 @@ public class JavaParser { ...@@ -311,6 +331,19 @@ public class JavaParser {
} }
} }
private void addMethod(MethodObj m) {
if (m.isStatic) {
return;
}
MethodObj old = allMethodsMap.get(m.name);
if (old != null) {
old.isVirtual = true;
m.isVirtual = true;
} else {
allMethodsMap.put(m.name, m);
}
}
private Expr readArrayInit(Type type) { private Expr readArrayInit(Type type) {
ArrayInitExpr expr = new ArrayInitExpr(); ArrayInitExpr expr = new ArrayInitExpr();
expr.type = new Type(); expr.type = new Type();
...@@ -423,10 +456,10 @@ public class JavaParser { ...@@ -423,10 +456,10 @@ public class JavaParser {
} else if (readIf("{")) { } else if (readIf("{")) {
StatementBlock stat = new StatementBlock(); StatementBlock stat = new StatementBlock();
while (true) { while (true) {
stat.instructions.add(readStatement());
if (readIf("}")) { if (readIf("}")) {
break; break;
} }
stat.instructions.add(readStatement());
} }
return stat; return stat;
} else if (readIf("if")) { } else if (readIf("if")) {
...@@ -496,6 +529,7 @@ public class JavaParser { ...@@ -496,6 +529,7 @@ public class JavaParser {
FieldObj f = new FieldObj(); FieldObj f = new FieldObj();
f.name = name; f.name = name;
f.type = type; f.type = type;
f.isLocal = true;
localVars.put(name, f); localVars.put(name, f);
read(":"); read(":");
forStat.iterableType = type; forStat.iterableType = type;
...@@ -831,9 +865,6 @@ public class JavaParser { ...@@ -831,9 +865,6 @@ public class JavaParser {
} }
} }
expr.field = f; expr.field = f;
if (f == null) {
System.out.println("?");
}
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;
...@@ -1306,6 +1337,25 @@ if (f == null) { ...@@ -1306,6 +1337,25 @@ if (f == null) {
} }
out.println(); out.println();
} }
out.println();
out.println("/* method pointers */");
for (MethodObj m : allMethodsMap.values()) {
out.print("extern " + m.returnType + " (*virtual_" + m.name + "[])(");
int i = 0;
if (!m.isConstructor) {
out.print("void*");
i++;
}
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(p.type);
i++;
}
out.println(");");
out.println();
}
} }
/** /**
...@@ -1314,6 +1364,32 @@ if (f == null) { ...@@ -1314,6 +1364,32 @@ if (f == null) {
* @param out the output writer * @param out the output writer
*/ */
void writeSource(PrintWriter out) { void writeSource(PrintWriter out) {
out.println("/* method pointers */");
for (MethodObj m : allMethodsMap.values()) {
out.print(m.returnType + " (*virtual_" + m.name + "[])(");
int i = 0;
if (!m.isConstructor) {
out.print("void*");
i++;
}
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(p.type);
i++;
}
out.println(") = {");
for (ClassObj c : classes.values()) {
if (c.methods.containsKey(m.name)) {
out.println(" " + toC(c.name) + "_" + m.name + ", ");
} else {
out.println(" 0, ");
}
}
out.println("};");
}
out.println();
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".c */"); out.println("/* " + c.name + ".c */");
for (Statement s : c.nativeCode) { for (Statement s : c.nativeCode) {
...@@ -1411,6 +1487,12 @@ if (f == null) { ...@@ -1411,6 +1487,12 @@ if (f == null) {
return classObj; return classObj;
} }
/**
* Get the class of the given name.
*
* @param className the name
* @return the class
*/
ClassObj getClassObj(String className) { ClassObj getClassObj(String className) {
ClassObj c = BUILT_IN_TYPES.get(className); ClassObj c = BUILT_IN_TYPES.get(className);
if (c == null) { if (c == null) {
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
package org.h2.java; package org.h2.java;
/** /**
* A test application. * A test application.
*/ */
...@@ -30,6 +29,10 @@ int main(int argc, char** argv) { ...@@ -30,6 +29,10 @@ int main(int argc, char** argv) {
System.out.println("Hello!"); System.out.println("Hello!");
} }
public int hashCode() {
return 1;
}
/** /**
* A test method. * A test method.
* *
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论