提交 167230d2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Java to C++ converter

上级 142c2e4b
......@@ -267,9 +267,14 @@ class FieldObj {
Type type;
/**
* Whether this is a local field.
* Whether this is a variable or parameter.
*/
boolean isLocal;
boolean isVariable;
/**
* Whether this is a local field (not separately garbage collected).
*/
boolean isLocalField;
/**
* The field name.
......
......@@ -23,21 +23,19 @@ public interface Expr {
*/
class CallExpr implements Expr {
final JavaParser context;
final Expr expr;
final ArrayList<Expr> args = new ArrayList<Expr>();
final boolean isStatic;
final String className;
final String name;
private final JavaParser context;
private final String className;
private final String name;
private Expr expr;
private ClassObj classObj;
private MethodObj method;
CallExpr(JavaParser context, Expr expr, String className, String name, boolean isStatic) {
CallExpr(JavaParser context, Expr expr, String className, String name) {
this.context = context;
this.expr = expr;
this.className = className;
this.name = name;
this.isStatic = isStatic;
}
private void initMethod() {
......@@ -50,6 +48,9 @@ class CallExpr implements Expr {
classObj = expr.getType().classObj;
}
method = classObj.getMethod(name, args);
if (method.isStatic) {
expr = null;
}
}
public String toString() {
......@@ -165,7 +166,7 @@ class LiteralExpr implements Expr {
public String toString() {
if ("null".equals(literal)) {
return JavaParser.toCType(type) + "()";
return JavaParser.toCType(type, true) + "()";
}
return literal;
}
......@@ -301,7 +302,7 @@ class NewExpr implements Expr {
}
buff.append("))");
} else {
buff.append("new " + JavaParser.toC(classObj.toString()));
buff.append("ptr<" + JavaParser.toC(classObj.toString()) + ">(new " + JavaParser.toC(classObj.toString()));
buff.append("(");
int i = 0;
for (Expr a : args) {
......@@ -310,7 +311,7 @@ class NewExpr implements Expr {
}
buff.append(a);
}
buff.append(")");
buff.append("))");
}
return buff.toString();
}
......@@ -458,9 +459,6 @@ class VariableExpr implements Expr {
private void init() {
if (field == null) {
if (base == null) {
System.out.println("??");
}
Type t = base.getType();
if (t.arrayLevel > 0) {
if ("length".equals(name)) {
......
......@@ -295,6 +295,7 @@ public class JavaParser {
annotations.add(annotation);
}
boolean isIgnore = annotations.contains("Ignore");
boolean isLocalField = annotations.contains("Local");
boolean isStatic = false;
boolean isFinal = false;
boolean isPrivate = false;
......@@ -369,6 +370,7 @@ public class JavaParser {
} else {
FieldObj field = new FieldObj();
field.isIgnore = isIgnore;
field.isLocalField = isLocalField;
field.type = type;
field.name = name;
field.isStatic = isStatic;
......@@ -430,7 +432,7 @@ public class JavaParser {
private void initThisPointer() {
thisPointer = new FieldObj();
thisPointer.isLocal = true;
thisPointer.isVariable = true;
thisPointer.name = "this";
thisPointer.type = new Type();
thisPointer.type.classObj = classObj;
......@@ -456,7 +458,7 @@ public class JavaParser {
}
while (true) {
FieldObj field = new FieldObj();
field.isLocal = true;
field.isVariable = true;
String typeName = readTypeOrIdentifier();
field.type = readType(typeName);
if (field.type.isVarArgs) {
......@@ -593,7 +595,7 @@ public class JavaParser {
FieldObj f = new FieldObj();
f.name = name;
f.type = type;
f.isLocal = true;
f.isVariable = true;
localVars.put(name, f);
read(":");
forStat.iterableType = type;
......@@ -646,7 +648,7 @@ public class JavaParser {
}
}
FieldObj f = new FieldObj();
f.isLocal = true;
f.isVariable = true;
f.type = dec.type;
f.name = varName;
localVars.put(varName, f);
......@@ -706,12 +708,163 @@ public class JavaParser {
}
private Expr readExpr2() {
Expr expr = readExpr2a();
while (true) {
String infixOp = current.token;
if (readIf("||")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2a();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2a() {
Expr expr = readExpr2b();
while (true) {
String infixOp = current.token;
if (readIf("&&")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2b();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2b() {
Expr expr = readExpr2c();
while (true) {
String infixOp = current.token;
if (readIf("|")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2c();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2c() {
Expr expr = readExpr2d();
while (true) {
String infixOp = current.token;
if (readIf("^")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2d();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2d() {
Expr expr = readExpr2e();
while (true) {
String infixOp = current.token;
if (readIf("&")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2e();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2e() {
Expr expr = readExpr2f();
while (true) {
String infixOp = current.token;
if (readIf("==") || readIf("!=")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2f();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2f() {
Expr expr = readExpr2g();
while (true) {
String infixOp = current.token;
if (readIf("<") || readIf(">") || readIf("<=") || readIf(">=")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2g();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2g() {
Expr expr = readExpr2h();
while (true) {
String infixOp = current.token;
if (readIf("<<") || readIf(">>") || readIf(">>>")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2h();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2h() {
Expr expr = readExpr2i();
while (true) {
String infixOp = current.token;
if (readIf("+") || readIf("-")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr2i();
expr = opExpr;
} else {
break;
}
}
return expr;
}
private Expr readExpr2i() {
Expr expr = readExpr3();
while (true) {
String infixOp = current.token;
if (readIf("||") || readIf("&&") || readIf("|") || readIf("^") || readIf("&") || readIf("==") || readIf("!=")
|| readIf("<") || readIf(">") || readIf("<=") || readIf(">=") || readIf("<<") || readIf(">>")
|| readIf(">>>") || readIf("+") || readIf("-") || readIf("*") || readIf("/") || readIf("%")) {
if (readIf("*") || readIf("/") || readIf("%")) {
OpExpr opExpr = new OpExpr(this);
opExpr.left = expr;
opExpr.op = infixOp;
......@@ -798,7 +951,7 @@ public class JavaParser {
if (readIf(".")) {
String n = readIdentifier();
if (readIf("(")) {
CallExpr e2 = new CallExpr(this, expr, null, n, false);
CallExpr e2 = new CallExpr(this, expr, null, n);
if (!readIf(")")) {
while (true) {
e2.args.add(readExpr());
......@@ -894,17 +1047,24 @@ public class JavaParser {
}
if (readIf("this")) {
VariableExpr expr = new VariableExpr(this);
expr.field = thisPointer;
if (thisPointer == null) {
throw getSyntaxException("'this' used in a static context");
}
expr.field = thisPointer;
return expr;
}
String name = readIdentifier();
if (readIf("(")) {
VariableExpr t = new VariableExpr(this);
VariableExpr t;
if (thisPointer == null) {
// static method calling another static method
t = null;
} else {
// non-static method calling a static or non-static method
t = new VariableExpr(this);
t.field = thisPointer;
CallExpr expr = new CallExpr(this, t, classObj.className, name, false);
}
CallExpr expr = new CallExpr(this, t, classObj.className, name);
if (!readIf(")")) {
while (true) {
expr.args.add(readExpr());
......@@ -937,7 +1097,7 @@ public class JavaParser {
if (readIf(".")) {
String n = readIdentifier();
if (readIf("(")) {
CallExpr e2 = new CallExpr(this, null, imp, n, true);
CallExpr e2 = new CallExpr(this, null, imp, n);
if (!readIf(")")) {
while (true) {
e2.args.add(readExpr());
......@@ -961,7 +1121,7 @@ public class JavaParser {
}
}
expr.field = f;
if (f != null && (!f.isLocal && !f.isStatic)) {
if (f != null && (!f.isVariable && !f.isStatic)) {
VariableExpr ve = new VariableExpr(this);
ve.field = thisPointer;
expr.base = ve;
......@@ -1391,7 +1551,6 @@ public class JavaParser {
out.println(s);
}
out.println();
// two classes, similar to the pimpl idiom
for (ClassObj c : classes.values()) {
out.println("class " + toC(c.className) + ";");
}
......@@ -1402,7 +1561,7 @@ public class JavaParser {
if (f.isFinal) {
buff.append("const ");
}
buff.append(toCType(f.type));
buff.append(toCType(f.type, !f.isLocalField));
buff.append(" ").append(toC(c.className + "." + f.name));
buff.append(";");
out.println(buff.toString());
......@@ -1413,14 +1572,14 @@ public class JavaParser {
continue;
}
if (m.isStatic) {
out.print(toCType(m.returnType));
out.print(toCType(m.returnType, true));
out.print(" " + toC(c.className + "_" + m.name) + "(");
int i = 0;
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(toCType(p.type) + " " + p.name);
out.print(toCType(p.type, false) + " " + p.name);
i++;
}
out.println(");");
......@@ -1441,7 +1600,7 @@ public class JavaParser {
out.println("public:");
for (FieldObj f : c.instanceFields.values()) {
out.print(" ");
out.print(toCType(f.type) + " " + f.name);
out.print(toCType(f.type, !f.isLocalField) + " " + f.name);
if (f.value != null) {
out.print(" = " + f.value);
}
......@@ -1459,14 +1618,14 @@ public class JavaParser {
if (m.isConstructor) {
out.print(" " + toC(c.className) + "(");
} else {
out.print(" " + toCType(m.returnType) + " " + m.name + "(");
out.print(" " + toCType(m.returnType, true) + " " + m.name + "(");
}
int i = 0;
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(toCType(p.type));
out.print(toCType(p.type, false));
out.print(" " + p.name);
i++;
}
......@@ -1499,7 +1658,7 @@ public class JavaParser {
if (f.isFinal) {
buff.append("const ");
}
buff.append(toCType(f.type));
buff.append(toCType(f.type, !f.isLocalField));
buff.append(" ").append(toC(c.className + "." + f.name));
if (f.value != null) {
buff.append(" = " + f.value);
......@@ -1513,18 +1672,18 @@ public class JavaParser {
continue;
}
if (m.isStatic) {
out.print(toCType(m.returnType) + " " + toC(c.className + "_" + m.name) + "(");
out.print(toCType(m.returnType, true) + " " + toC(c.className + "_" + m.name) + "(");
} else if (m.isConstructor) {
out.print(toC(c.className) + "::" + toC(c.className) + "(");
} else {
out.print(toCType(m.returnType) + " " + toC(c.className) + "::" + m.name + "(");
out.print(toCType(m.returnType, true) + " " + toC(c.className) + "::" + m.name + "(");
}
int i = 0;
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
out.print(toCType(p.type) + " " + p.name);
out.print(toCType(p.type, false) + " " + p.name);
i++;
}
out.println(") {");
......@@ -1578,18 +1737,35 @@ public class JavaParser {
return identifier.replace('.', '_');
}
static String toCType(Type type) {
static String toCType(Type type, boolean refCounted) {
// TODO not everything needs to be ref-counted
refCounted = true;
StringBuilder buff = new StringBuilder();
for (int i = 0; i < type.arrayLevel; i++) {
if (refCounted) {
buff.append("ptr<array< ");
} else {
buff.append("array< ");
}
}
if (type.classObj.isPrimitive) {
buff.append(toC(type.classObj.toString()));
} else {
if (refCounted) {
buff.append("ptr<").append(toC(type.classObj.toString())).append('>');
} else {
buff.append(toC(type.classObj.toString()));
}
}
for (int i = 0; i < type.arrayLevel; i++) {
if (refCounted) {
buff.append(" > >");
} else {
buff.append(" >");
}
}
if (!refCounted) {
buff.append("*");
}
return buff.toString();
}
......
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.java;
/**
* This annotation marks fields that are not shared and therefore don't need to
* be garbage collected separately.
*/
public @interface Local {
// empty
}
......@@ -44,7 +44,7 @@ class ReturnStatement extends StatementBase {
if (expr.getType().isSimplePrimitive()) {
return "return " + expr + ";";
}
return "return " + JavaParser.toCType(expr.getType()) + "(" + expr + ");";
return "return " + JavaParser.toCType(expr.getType(), true) + "(" + expr + ");";
}
}
......@@ -253,7 +253,7 @@ class VarDecStatement extends StatementBase {
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append(JavaParser.toCType(type)).append(' ');
buff.append(JavaParser.toCType(type, true)).append(' ');
StringBuilder assign = new StringBuilder();
for (int i = 0; i < variables.size(); i++) {
if (i > 0) {
......
......@@ -30,13 +30,16 @@ public class Test extends TestBase {
// chmod +x test
// ./test
// (for "mixed declarations and code")
// include files:
// /usr/include/c++/4.2.1/tr1/stdio.h
// /usr/include/stdio.h
// TODO initialize fields
// not supported yet:
// exceptions
// HexadecimalFloatingPointLiteral
// int x()[] { return null; }
// annotations
// import static
// import *
// initializer blocks
......@@ -66,6 +69,7 @@ public class Test extends TestBase {
parser.parse("src/tools/org/h2", "java.lang.String");
parser.parse("src/tools/org/h2", "java.lang.Math");
parser.parse("src/tools/org/h2", "java.lang.Integer");
parser.parse("src/tools/org/h2", "java.lang.Long");
parser.parse("src/tools/org/h2", "java.lang.StringBuilder");
parser.parse("src/tools/org/h2", "java.io.PrintStream");
parser.parse("src/tools/org/h2", "java.lang.System");
......
/*
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.java.lang;
/**
* A java.lang.Long implementation.
*/
public class Long {
public static final long MIN_VALUE = 1L << 63;
public static final long MAX_VALUE = (1L << 63) - 1;
/**
* Convert a value to a String.
*
* @param x the value
* @return the String
*/
public static String toString(long x) {
// c: wchar_t ch[30];
// c: swprintf(ch, 30, L"%ld", x);
// c: return STRING(ch);
// c: return;
if (x == MIN_VALUE) {
return String.wrap("-9223372036854775808");
}
char[] ch = new char[30];
int i = 30 - 1, count = 0;
boolean negative;
if (x < 0) {
negative = true;
x = -x;
} else {
negative = false;
}
for (; i >= 0; i--) {
ch[i] = (char) ('0' + (x % 10));
x /= 10;
count++;
if (x == 0) {
break;
}
}
if (negative) {
ch[--i] = '-';
count++;
}
return new String(ch, i, count);
}
}
......@@ -7,6 +7,7 @@
package org.h2.java.lang;
import org.h2.java.Ignore;
import org.h2.java.Local;
/* c:
......@@ -37,7 +38,7 @@ protected:
jint refCount;
public:
RefBase() {
refCount = 1;
refCount = 0;
}
void reference() {
refCount++;
......@@ -47,6 +48,8 @@ public:
delete this;
}
}
virtual ~RefBase() {
}
};
template <class T> class ptr {
T* pointer;
......@@ -137,6 +140,7 @@ public class String {
/**
* The character array.
*/
@Local
char[] chars;
private int hash;
......@@ -152,18 +156,17 @@ public class String {
}
public int hashCode() {
if (hash == 0) {
if (chars.length == 0) {
return 0;
}
int h = 0;
for (char c : chars) {
h = h * 31 + c;
int h = hash;
if (h == 0) {
int size = chars.length;
if (size != 0) {
for (int i = 0; i < size; i++) {
h = h * 31 + chars[i];
}
hash = h;
return h;
}
return hash;
}
return h;
}
/**
......
......@@ -56,4 +56,21 @@ public class System {
java.lang.System.arraycopy(src, srcPos, dest, destPos, length);
}
/**
* Get the current time in milliseconds since 1970-01-01.
*
* @return the milliseconds
*/
public static long nanoTime() {
/* c:
#if CLOCKS_PER_SEC == 1000000
return (jlong) clock() * 1000;
#else
return (jlong) clock() * 1000000 / CLOCKS_PER_SEC;
#endif
*/
// c: return;
return java.lang.System.nanoTime();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论