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

A Java parser / Java to C converter.

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