提交 0163a2a2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Java to C converter (moving forward C++ will be used)

上级 b8c6a437
...@@ -204,6 +204,11 @@ class MethodObj { ...@@ -204,6 +204,11 @@ class MethodObj {
*/ */
boolean isVirtual; boolean isVirtual;
/**
* Whether this method is to be ignored (using the Ignore annotation).
*/
boolean isIgnore;
/** /**
* The name. * The name.
*/ */
...@@ -285,6 +290,11 @@ class FieldObj { ...@@ -285,6 +290,11 @@ class FieldObj {
*/ */
boolean isPublic; boolean isPublic;
/**
* Whether this method is to be ignored (using the Ignore annotation).
*/
boolean isIgnore;
/** /**
* The initial value expression (may be null). * The initial value expression (may be null).
*/ */
...@@ -317,6 +327,15 @@ class Type { ...@@ -317,6 +327,15 @@ class Type {
*/ */
boolean isVarArgs; boolean isVarArgs;
/**
* Whether this is a non-array primitive type.
*
* @return true if yes
*/
public boolean isSimplePrimitive() {
return arrayLevel == 0 && classObj.isPrimitive;
}
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append(JavaParser.toC(classObj.toString())); buff.append(JavaParser.toC(classObj.toString()));
......
...@@ -54,25 +54,37 @@ class CallExpr implements Expr { ...@@ -54,25 +54,37 @@ class CallExpr implements Expr {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
String methodName; String methodName;
initMethod(); initMethod();
if (method.isVirtual) { if (method.isIgnore) {
methodName = "virtual_" + method.name + "[CLASS_ID("+expr.toString()+")]"; if (args.size() == 0) {
// ignore
} else if (args.size() == 1) {
buff.append(args.get(0));
} else {
throw new IllegalArgumentException(
"Cannot ignore method with multiple arguments: " + method);
}
} else { } else {
methodName = JavaParser.toC(classObj.toString() + "." + method.name); if (method.isVirtual) {
} methodName = "virtual_" + method.name + "[CLASS_ID("+expr.toString()+")]";
buff.append(methodName).append("("); } else {
int i = 0; methodName = JavaParser.toC(classObj.toString() + "." + method.name);
if (expr != null) { }
buff.append(expr.toString()); buff.append(methodName).append("(");
i++; int i = 0;
} if (expr != null) {
for (Expr a : args) { buff.append(expr.toString());
if (i > 0) { i++;
buff.append(", "); }
for (Expr a : args) {
if (i > 0) {
buff.append(", ");
}
i++;
buff.append(a);
} }
i++; buff.append(")");
buff.append(a);
} }
return buff.append(")").toString(); return buff.toString();
} }
public Type getType() { public Type getType() {
...@@ -92,12 +104,17 @@ class AssignExpr implements Expr { ...@@ -92,12 +104,17 @@ class AssignExpr implements Expr {
Expr right; Expr right;
public String toString() { public String toString() {
return left + " " + op + " " + right; if (left.getType().isSimplePrimitive()) {
return left + " " + op + " " + right;
}
if (right.toString().equals("null")) {
return "release(" + left + ")";
}
return left + " = set(" + left + ", " + right + ")";
} }
public Type getType() { public Type getType() {
// TODO return left.getType();
return null;
} }
} }
...@@ -115,8 +132,7 @@ class ConditionalExpr implements Expr { ...@@ -115,8 +132,7 @@ class ConditionalExpr implements Expr {
} }
public Type getType() { public Type getType() {
// TODO return ifTrue.getType();
return null;
} }
} }
...@@ -288,6 +304,11 @@ class NewExpr implements Expr { ...@@ -288,6 +304,11 @@ class NewExpr implements Expr {
*/ */
class StringExpr implements Expr { class StringExpr implements Expr {
/**
* The constant name.
*/
String constantName;
/** /**
* The literal. * The literal.
*/ */
...@@ -301,7 +322,7 @@ class StringExpr implements Expr { ...@@ -301,7 +322,7 @@ class StringExpr implements Expr {
} }
public String toString() { public String toString() {
return "STRING(\"" + javaEncode(text) + "\")"; return constantName;
} }
public Type getType() { public Type getType() {
...@@ -407,13 +428,16 @@ class VariableExpr implements Expr { ...@@ -407,13 +428,16 @@ class VariableExpr implements Expr {
private void init() { private void init() {
if (field == null) { if (field == null) {
if (base == null) {
System.out.println("??");
}
Type t = base.getType(); Type t = base.getType();
if (t.arrayLevel > 0) { if (t.arrayLevel > 0) {
if ("length".equals(name)) { if ("length".equals(name)) {
field = new FieldObj(); field = new FieldObj();
field.type = context.getClassObj("int").baseType; field.type = context.getClassObj("int").baseType;
} else { } else {
throw new RuntimeException("Unknown array method: " + name); throw new IllegalArgumentException("Unknown array method: " + name);
} }
} else { } else {
field = t.classObj.getField(name); field = t.classObj.getField(name);
......
/*
* 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 methods that are only needed for testing.
*/
public @interface Ignore {
// empty
}
...@@ -13,66 +13,93 @@ import java.util.ArrayList; ...@@ -13,66 +13,93 @@ import java.util.ArrayList;
*/ */
public interface Statement { public interface Statement {
boolean isEnd();
// toString // toString
} }
/**
* The base class for statements.
*/
abstract class StatementBase implements Statement {
public boolean isEnd() {
return false;
}
}
/** /**
* A "return" statement. * A "return" statement.
*/ */
class ReturnStatement implements Statement { class ReturnStatement extends StatementBase {
Expr expr; Expr expr;
public String toString() { public String toString() {
return "return " + (expr == null ? "" : expr) + ";"; return "return " + (expr == null ? "" : expr) + ";";
} }
} }
/** /**
* A "do .. while" statement. * A "do .. while" statement.
*/ */
class DoWhileStatement implements Statement { class DoWhileStatement extends StatementBase {
Expr condition; Expr condition;
Statement block; Statement block;
public String toString() { public String toString() {
return "do {\n" + block + "} while (" + condition + ");"; return "do {\n" + block + "} while (" + condition + ");";
} }
} }
/** /**
* A "continue" statement. * A "continue" statement.
*/ */
class ContinueStatement implements Statement { class ContinueStatement extends StatementBase {
public String toString() { public String toString() {
return "continue;"; return "continue;";
} }
} }
/** /**
* A "break" statement. * A "break" statement.
*/ */
class BreakStatement implements Statement { class BreakStatement extends StatementBase {
public String toString() { public String toString() {
return "break;"; return "break;";
} }
} }
/** /**
* An empty statement. * An empty statement.
*/ */
class EmptyStatement implements Statement { class EmptyStatement extends StatementBase {
public String toString() { public String toString() {
return ";"; return ";";
} }
} }
/** /**
* A "switch" statement. * A "switch" statement.
*/ */
class SwitchStatement implements Statement { class SwitchStatement extends StatementBase {
Expr expr; Expr expr;
StatementBlock defaultBlock; StatementBlock defaultBlock;
ArrayList<Expr> cases = new ArrayList<Expr>(); ArrayList<Expr> cases = new ArrayList<Expr>();
ArrayList<StatementBlock> blocks = new ArrayList<StatementBlock>(); ArrayList<StatementBlock> blocks = new ArrayList<StatementBlock>();
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append("switch (").append(expr).append(") {\n"); buff.append("switch (").append(expr).append(") {\n");
...@@ -87,38 +114,47 @@ class SwitchStatement implements Statement { ...@@ -87,38 +114,47 @@ class SwitchStatement implements Statement {
buff.append("}"); buff.append("}");
return buff.toString(); return buff.toString();
} }
} }
/** /**
* An expression statement. * An expression statement.
*/ */
class ExprStatement implements Statement { class ExprStatement extends StatementBase {
Expr expr; Expr expr;
public String toString() { public String toString() {
return expr + ";"; return expr + ";";
} }
} }
/** /**
* A "while" statement. * A "while" statement.
*/ */
class WhileStatement implements Statement { class WhileStatement extends StatementBase {
Expr condition; Expr condition;
Statement block; Statement block;
public String toString() { public String toString() {
String w = "while (" + condition + ")"; String w = "while (" + condition + ")";
String s = block.toString(); String s = block.toString();
return w + "\n" + s; return w + "\n" + s;
} }
} }
/** /**
* An "if" statement. * An "if" statement.
*/ */
class IfStatement implements Statement { class IfStatement extends StatementBase {
Expr condition; Expr condition;
Statement block; Statement block;
Statement elseBlock; Statement elseBlock;
public String toString() { public String toString() {
String w = "if (" + condition + ") {\n"; String w = "if (" + condition + ") {\n";
String s = block.toString(); String s = block.toString();
...@@ -127,12 +163,14 @@ class IfStatement implements Statement { ...@@ -127,12 +163,14 @@ class IfStatement implements Statement {
} }
return w + s + "}"; return w + s + "}";
} }
} }
/** /**
* A "for" statement. * A "for" statement.
*/ */
class ForStatement implements Statement { class ForStatement extends StatementBase {
Statement init; Statement init;
Expr condition; Expr condition;
Expr update; Expr update;
...@@ -141,6 +179,7 @@ class ForStatement implements Statement { ...@@ -141,6 +179,7 @@ class ForStatement implements Statement {
Type iterableType; Type iterableType;
String iterableVariable; String iterableVariable;
Expr iterable; Expr iterable;
public String toString() { public String toString() {
StringBuffer buff = new StringBuffer(); StringBuffer buff = new StringBuffer();
buff.append("for ("); buff.append("for (");
...@@ -174,54 +213,81 @@ class ForStatement implements Statement { ...@@ -174,54 +213,81 @@ class ForStatement implements Statement {
} }
return buff.toString(); return buff.toString();
} }
} }
/** /**
* A statement block. * A statement block.
*/ */
class StatementBlock implements Statement { class StatementBlock extends StatementBase {
ArrayList<Statement> instructions = new ArrayList<Statement>(); ArrayList<Statement> instructions = new ArrayList<Statement>();
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
for (Statement s : instructions) { for (Statement s : instructions) {
if (s.isEnd()) {
break;
}
buff.append(JavaParser.indent(s.toString())); buff.append(JavaParser.indent(s.toString()));
} }
return buff.toString(); return buff.toString();
} }
} }
/** /**
* A variable declaration. * A variable declaration.
*/ */
class VarDecStatement implements Statement { class VarDecStatement extends StatementBase {
Type type; Type type;
ArrayList<String> variables = new ArrayList<String>(); ArrayList<String> variables = new ArrayList<String>();
ArrayList<Expr> values = new ArrayList<Expr>(); ArrayList<Expr> values = new ArrayList<Expr>();
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append(type).append(' '); buff.append(type).append(' ');
StringBuilder assign = new StringBuilder();
for (int i = 0; i < variables.size(); i++) { for (int i = 0; i < variables.size(); i++) {
if (i > 0) { if (i > 0) {
buff.append(", "); buff.append(", ");
} }
buff.append(variables.get(i)); String varName = variables.get(i);
buff.append(varName);
Expr value = values.get(i); Expr value = values.get(i);
if (value != null) { if (value != null) {
buff.append(" = ").append(value); if (value.getType().isSimplePrimitive()) {
buff.append(" = ").append(value);
} else {
assign.append(varName).append(" = reference(").append(value).append(");\n");
}
} }
} }
buff.append(";"); buff.append(";");
if (assign.length() > 0) {
buff.append("\n");
buff.append(assign);
}
return buff.toString(); return buff.toString();
} }
} }
/** /**
* A native statement. * A native statement.
*/ */
class StatementNative implements Statement { class StatementNative extends StatementBase {
String code; String code;
public String toString() { public String toString() {
return code; return code;
} }
public boolean isEnd() {
return code.equals("return;");
}
} }
...@@ -26,10 +26,14 @@ public class Test extends TestBase { ...@@ -26,10 +26,14 @@ public class Test extends TestBase {
} }
public void test() throws IOException { public void test() throws IOException {
// gcc --std=c99 test.c // gcc --std=c99 -o test test.cpp
// chmod +x test
// ./test
// (for "mixed declarations and code") // (for "mixed declarations and code")
// not supported yet: // not supported yet:
// exceptions
// HexadecimalFloatingPointLiteral // HexadecimalFloatingPointLiteral
// int x()[] { return null; } // int x()[] { return null; }
// annotations // annotations
......
...@@ -25,7 +25,11 @@ int main(int argc, char** argv) { ...@@ -25,7 +25,11 @@ int main(int argc, char** argv) {
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(String... args) { public static void main(String... args) {
System.out.println("Hello " + "World" + 1); for (int i = 0; i < 10; i++) {
String s = "Hello " + i;
System.out.println(s);
s = null;
}
} }
} }
...@@ -11,6 +11,10 @@ package org.h2.java.lang; ...@@ -11,6 +11,10 @@ package org.h2.java.lang;
*/ */
public class Integer { public class Integer {
public static final int MIN_VALUE = 1 << 31;
public static final int MAX_VALUE = (int) ((1L << 31) - 1);
/** /**
* Convert a value to a String. * Convert a value to a String.
* *
...@@ -21,7 +25,32 @@ public class Integer { ...@@ -21,7 +25,32 @@ public class Integer {
// c: char ch[20]; // c: char ch[20];
// c: snprintf(ch, 20, "%d", x); // c: snprintf(ch, 20, "%d", x);
// c: return string(ch); // c: return string(ch);
return null; // c: return;
if (x == MIN_VALUE) {
return String.wrap("-2147483648");
}
char[] ch = new char[20];
int i = 20 - 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);
} }
} }
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
*/ */
package org.h2.java.lang; package org.h2.java.lang;
import org.h2.java.Ignore;
/* c: /* c:
#include <stdlib.h> #include <stdlib.h>
...@@ -38,16 +40,24 @@ package org.h2.java.lang; ...@@ -38,16 +40,24 @@ package org.h2.java.lang;
void* new_array(jint object, jint size, jint length); void* new_array(jint object, jint size, jint length);
void* new_object(jint type, jint size); void* new_object(jint type, jint size);
void* set_object(void** target, void* o); void* reference(void* o);
void release(void* o);
void* set(void* o, void* n);
void* string(char* s); void* string(char* s);
*/ */
/* /*
* Object layout: * Object layout:
* m-3: arrays: length; otherwise not allocated * m-2: data type
* m-2: arrays: 0; otherwise type * m-1: number of references
* m: object data
*
* Array layout:
* m-3: length (number of elements)
* m-2: 0 (array marker)
* m-1: number of references * m-1: number of references
* m: first element
*/ */
/** /**
...@@ -57,25 +67,57 @@ public class String { ...@@ -57,25 +67,57 @@ public class String {
/* c: /* c:
void* new_array(jint object, jint size, jint length) { void* new_array_with_count(jint object, jint size, jint length, jint refCount) {
int count = sizeof(jint) * 3 + size * length; jint count = sizeof(jint) * 3 + size * length;
int* m = (jint*) calloc(1, count); jint* m = (jint*) calloc(1, count);
*m = length; *m = length;
*(m + 2) = 1; *(m + 2) = refCount;
return m + 3; return m + 3;
} }
void* new_object(jint type, jint size) { void* new_array(jint object, jint size, jint length) {
int count = sizeof(jint) * 2 + size; return new_array_with_count(object, size, length, 1);
int* m = (jint*) calloc(1, count); }
void* new_static_array(jint object, jint size, jint length) {
return new_array_with_count(object, size, length, 0);
}
void* new_object_with_count(jint type, jint size, jint refCount) {
jint count = sizeof(jint) * 2 + size;
jint* m = (jint*) calloc(1, count);
*m = type; *m = type;
*(m + 1) = 1; *(m + 1) = refCount;
return m + 2; return m + 2;
} }
void* set_object(void** target, void* o) { void* new_object(jint type, jint size) {
int* m = (jint*) target; return new_object_with_count(type, size, 1);
if (*(m - 1) == 1) { }
void* new_static_object(jint type, jint size) {
return new_object_with_count(type, size, 0);
}
void* reference(void* o) {
if (o != 0) {
jint* m = (jint*) o;
if (*(m - 1) > 0) {
(*(m - 1))++;
}
}
return o;
}
void release(void* o) {
if (o == 0) {
return;
}
jint* m = (jint*) o;
if (*(m - 1) <= 1) {
if (*(m - 1) == 0) {
return;
}
if (*(m - 2) == 0) { if (*(m - 2) == 0) {
free(m - 3); free(m - 3);
} else { } else {
...@@ -84,16 +126,15 @@ void* set_object(void** target, void* o) { ...@@ -84,16 +126,15 @@ void* set_object(void** target, void* o) {
} else { } else {
(*(m - 1))--; (*(m - 1))--;
} }
*target = o; }
m = (jint*) target;
if (o != 0) { void* set(void* o, void* n) {
(*(m - 1))++; release(o);
} return reference(n);
return m;
} }
void* string(char* s) { void* string(char* s) {
int len = strlen(s); jint len = strlen(s);
jchar* chars = NEW_ARRAY(sizeof(jchar), len); jchar* chars = NEW_ARRAY(sizeof(jchar), len);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
chars[i] = s[i]; chars[i] = s[i];
...@@ -144,4 +185,14 @@ void* string(char* s) { ...@@ -144,4 +185,14 @@ void* string(char* s) {
return chars.length; return chars.length;
} }
@Ignore
public java.lang.String asString() {
return new java.lang.String(chars);
}
@Ignore
public static String wrap(java.lang.String x) {
return new String(x.toCharArray());
}
} }
...@@ -33,6 +33,8 @@ public class System { ...@@ -33,6 +33,8 @@ public class System {
memmove(((jchar*)dest) + destPos, memmove(((jchar*)dest) + destPos,
((jchar*)src) + srcPos, sizeof(jchar) * length); ((jchar*)src) + srcPos, sizeof(jchar) * length);
*/ */
// c: return;
java.lang.System.arraycopy(src, srcPos, dest, destPos, length);
} }
/** /**
...@@ -50,7 +52,8 @@ public class System { ...@@ -50,7 +52,8 @@ public class System {
memmove(((jbyte*)dest) + destPos, memmove(((jbyte*)dest) + destPos,
((jbyte*)src) + srcPos, sizeof(jbyte) * length); ((jbyte*)src) + srcPos, sizeof(jbyte) * length);
*/ */
// c: return;
java.lang.System.arraycopy(src, srcPos, dest, destPos, length);
} }
} }
...@@ -18,7 +18,7 @@ public class Arrays { ...@@ -18,7 +18,7 @@ public class Arrays {
* @param x the value * @param x the value
*/ */
public static void fill(char[] array, char x) { public static void fill(char[] array, char x) {
for (int i = 0; i < array.length; i++) { for (int i = 0, size = array.length; i < size; i++) {
array[i] = x; array[i] = x;
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论