提交 3f377668 authored 作者: Thomas Mueller's avatar Thomas Mueller

A Java parser / Java to C converter.

上级 cf69bd38
......@@ -56,7 +56,7 @@ public class ClassObj {
ArrayList<Statement> nativeCode = new ArrayList<Statement>();
String id;
int id;
/**
* Add a method.
......@@ -87,9 +87,9 @@ public class ClassObj {
public String toString() {
if (isPrimitive) {
return name;
return "j" + name;
}
return "struct " + name;
return name;
}
}
......@@ -127,7 +127,7 @@ class MethodObj {
/**
* The parameter list.
*/
ArrayList<FieldObj> parameters = new ArrayList<FieldObj>();
LinkedHashMap<String, FieldObj> parameters = new LinkedHashMap<String, FieldObj>();
/**
* Whether this method is final.
......@@ -143,6 +143,11 @@ class MethodObj {
* Whether this method is native.
*/
boolean isNative;
/**
* Whether this is a constructor.
*/
boolean isConstructor;
}
/**
......@@ -209,7 +214,7 @@ class Type {
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append(JavaParser.toC(type.name));
buff.append(JavaParser.toC(type.toString()));
if (!type.isPrimitive) {
buff.append("*");
}
......
......@@ -41,7 +41,7 @@ class CallExpr implements Expr {
if (className != null) {
buff.append(JavaParser.toC(className + "." + name)).append("(");
} else {
buff.append(JavaParser.toC(expr.getType().type.name + "." + name)).append("(");
buff.append(JavaParser.toC(expr.getType().type + "." + name)).append("(");
}
int i = 0;
if (expr != null) {
......@@ -198,7 +198,7 @@ class StringExpr implements Expr {
String text;
public String toString() {
return "\"" + javaEncode(text) + "\"";
return "STRING(\"" + javaEncode(text) + "\")";
}
public Type getType() {
......@@ -282,7 +282,8 @@ class VariableExpr implements Expr {
}
if (field != null) {
if (field.isStatic) {
buff.append(JavaParser.toC(field.type.type.name + "." + field.name));
// buff.append(JavaParser.toC(field.type.type.name + "." + field.name));
buff.append(JavaParser.toC(name));
} else {
buff.append(field.name);
}
......
......@@ -31,16 +31,20 @@ public class JavaParser {
private static final HashMap<String, ClassObj> BUILT_IN_TYPES = new HashMap<String, ClassObj>();
private static final HashMap<String, String> JAVA_IMPORT_MAP = new HashMap<String, String>();
private static int firstClassId;
private String source;
private ParseState current = new ParseState();
private String packageName;
private ClassObj classObj;
private int classId = firstClassId;
private MethodObj method;
private FieldObj thisPointer;
private HashMap<String, String> importMap = new HashMap<String, String>();
private HashMap<String, ClassObj> classes = new HashMap<String, ClassObj>();
private LinkedHashMap<String, FieldObj> localFields = new LinkedHashMap<String, FieldObj>();
private LinkedHashMap<String, FieldObj> localVars = new LinkedHashMap<String, FieldObj>();
private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>();
......@@ -54,26 +58,29 @@ public class JavaParser {
for (String s : list) {
RESERVED.add(s);
}
addBuiltInType(true, "void");
addBuiltInType(true, "int");
addBuiltInType(true, "char");
addBuiltInType(true, "byte");
addBuiltInType(true, "long");
addBuiltInType(true, "double");
addBuiltInType(true, "float");
addBuiltInType(true, "boolean");
addBuiltInType(true, "short");
int id = 0;
addBuiltInType(id++, true, "void");
addBuiltInType(id++, true, "int");
addBuiltInType(id++, true, "char");
addBuiltInType(id++, true, "byte");
addBuiltInType(id++, true, "long");
addBuiltInType(id++, true, "double");
addBuiltInType(id++, true, "float");
addBuiltInType(id++, true, "boolean");
addBuiltInType(id++, true, "short");
String[] java = new String[] { "Boolean", "Byte", "Character", "Class", "ClassLoader", "Double", "Float",
"Integer", "Long", "Math", "Number", "Object", "Runtime", "Short", "String", "StringBuffer",
"StringBuilder", "System", "Thread", "ThreadGroup", "ThreadLocal", "Throwable", "Void" };
for (String s : java) {
JAVA_IMPORT_MAP.put(s, "java.lang." + s);
addBuiltInType(false, "java.lang." + s);
addBuiltInType(id++, false, "java.lang." + s);
}
firstClassId = id;
}
private static void addBuiltInType(boolean primitive, String type) {
private static void addBuiltInType(int id, boolean primitive, String type) {
ClassObj typeObj = new ClassObj();
typeObj.id = id;
typeObj.name = type;
typeObj.isPrimitive = primitive;
BUILT_IN_TYPES.put(type, typeObj);
......@@ -134,6 +141,7 @@ public class JavaParser {
}
while (true) {
classObj = new ClassObj();
classObj.id = classId++;
classObj.isPublic = readIf("public");
if (readIf("class")) {
classObj.isInterface = false;
......@@ -196,7 +204,7 @@ public class JavaParser {
private void parseClassBody() {
read("{");
localFields.clear();
localVars.clear();
while (true) {
if (readIf("}")) {
break;
......@@ -231,10 +239,10 @@ public class JavaParser {
}
}
if (readIf("{")) {
MethodObj method = new MethodObj();
method = new MethodObj();
method.name = isStatic ? "cl_init_obj" : "init_obj";
method.isStatic = isStatic;
localFields.clear();
localVars.clear();
if (!isStatic) {
initThisPointer();
}
......@@ -243,14 +251,14 @@ public class JavaParser {
} else {
String typeName = readTypeOrIdentifier();
Type type = readType(typeName);
MethodObj method = new MethodObj();
method = new MethodObj();
method.returnType = type;
method.isStatic = isStatic;
method.isFinal = isFinal;
method.isPublic = isPublic;
method.isPrivate = isPrivate;
method.isNative = isNative;
localFields.clear();
localVars.clear();
if (!isStatic) {
initThisPointer();
}
......@@ -259,7 +267,8 @@ public class JavaParser {
throw getSyntaxException("Constructor of wrong type: " + type);
}
method.name = "init_obj";
parseFormalParameters(method);
method.isConstructor = true;
parseFormalParameters();
if (!readIf(";")) {
method.block = readStatement();
}
......@@ -268,7 +277,7 @@ public class JavaParser {
String name = readIdentifier();
method.name = name;
if (readIf("(")) {
parseFormalParameters(method);
parseFormalParameters();
if (!readIf(";")) {
method.block = readStatement();
}
......@@ -317,7 +326,7 @@ public class JavaParser {
return type;
}
private void parseFormalParameters(MethodObj method) {
private void parseFormalParameters() {
if (readIf(")")) {
return;
}
......@@ -327,7 +336,7 @@ public class JavaParser {
String typeName = readTypeOrIdentifier();
field.type = readType(typeName);
field.name = readIdentifier();
method.parameters.add(field);
method.parameters.put(field.name, field);
if (readIf(")")) {
break;
}
......@@ -504,7 +513,7 @@ public class JavaParser {
f.isLocal = true;
f.type = dec.type;
f.name = varName;
localFields.put(varName, f);
localVars.put(varName, f);
dec.variables.add(varName);
dec.values.add(value);
if (readIf(";")) {
......@@ -708,7 +717,9 @@ public class JavaParser {
}
String name = readIdentifier();
if (readIf("(")) {
CallExpr expr = new CallExpr(this, null, classObj.name, name, false);
VariableExpr t = new VariableExpr();
t.field = thisPointer;
CallExpr expr = new CallExpr(this, t, classObj.name, name, false);
if (!readIf(")")) {
while (true) {
expr.args.add(readExpr());
......@@ -721,48 +732,50 @@ public class JavaParser {
return expr;
}
VariableExpr expr = new VariableExpr();
FieldObj f = localFields.get(name);
FieldObj f = localVars.get(name);
if (f == null) {
f = method.parameters.get(name);
}
if (f == null) {
f = classObj.staticFields.get(name);
if (f == null) {
f = classObj.instanceFields.get(name);
if (f == null) {
String imp = importMap.get(name);
if (imp == null) {
imp = JAVA_IMPORT_MAP.get(name);
}
if (imp != null) {
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;
}
}
}
if (f == null) {
f = classObj.instanceFields.get(name);
}
if (f == null) {
String imp = importMap.get(name);
if (imp == null) {
imp = JAVA_IMPORT_MAP.get(name);
}
if (imp != null) {
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
return e2;
}
} else {
expr.field = f;
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
}
}
expr.field = f;
if (f != null && (!f.isLocal && !f.isStatic)) {
VariableExpr ve = new VariableExpr();
ve.field = thisPointer;
......@@ -783,7 +796,7 @@ public class JavaParser {
private String readQualifiedIdentifier() {
String id = readIdentifier();
if (localFields.containsKey(id)) {
if (localVars.containsKey(id)) {
return id;
}
if (classObj != null) {
......@@ -1209,11 +1222,11 @@ public class JavaParser {
for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0;
if (!m.isStatic) {
if (!m.isStatic && !m.isConstructor) {
out.print(toC(c.name) + "* this");
i++;
}
for (FieldObj p : m.parameters) {
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
......@@ -1249,11 +1262,11 @@ public class JavaParser {
for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0;
if (!m.isStatic) {
if (!m.isStatic && !m.isConstructor) {
out.print(toC(c.name) + "* this");
i++;
}
for (FieldObj p : m.parameters) {
for (FieldObj p : m.parameters.values()) {
if (i > 0) {
out.print(", ");
}
......@@ -1261,6 +1274,9 @@ public class JavaParser {
i++;
}
out.println(") {");
if (m.isConstructor) {
out.println(indent(toC(c.name) + "* this = NEW_OBJ(" + c.id + ", " + toC(c.name) +");"));
}
if (m.block != null) {
out.print(m.block.toString());
}
......
......@@ -77,7 +77,7 @@ class SwitchStatement implements Statement {
StringBuilder buff = new StringBuilder();
buff.append("switch (").append(expr).append(") {\n");
for (int i = 0; i < cases.size(); i++) {
buff.append("case: " + cases.get(i) + ":\n");
buff.append("case " + cases.get(i) + ":\n");
buff.append(blocks.get(i).toString());
}
if (defaultBlock != null) {
......@@ -148,7 +148,7 @@ class ForStatement implements Statement {
Type it = iterable.getType();
if (it != null && it.arrayLevel > 0) {
String idx = "i_" + iterableVariable;
buff.append("int " + idx + " = 0; " + idx + " < LEN(" + iterable + "); " + idx + "++");
buff.append("int " + idx + " = 0; " + idx + " < LENGTH(" + iterable + "); " + idx + "++");
buff.append(") {\n");
buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable + "["+ idx +"];\n"));
buff.append(block.toString()).append("}");
......
......@@ -26,6 +26,9 @@ public class Test extends TestBase {
}
public void test() throws IOException {
// gcc --std=c99 test.c
// (for "mixed declarations and code")
// not supported yet:
// HexadecimalFloatingPointLiteral
// int x()[] { return null; }
......
......@@ -9,10 +9,15 @@ package org.h2.java;
/**
* A test application.
*/
/// #include <stdio.h>
public class TestApp {
// private static final int FINAL_VALUE = 10;
/* c:
int main(char** args) {
org_h2_java_TestApp_main(null);
}
*/
/**
* Run this application.
......
......@@ -2,17 +2,33 @@ package org.h2.java.lang;
/* c:
#define boolean int
#define LENGTH(a) (*(((int*)(a))-1))
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define jvoid void
#define jboolean int8_t
#define jbyte int8_t
#define jchar int16_t
#define jint int32_t
#define jlong int64_t
#define jfloat float
#define jdouble double
#define true 1
#define false 0
#define null 0
#define LENGTH(a) (*(((jint*)(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 NEW_OBJ(typeId, typeName) new_object(typeId, sizeof(struct typeName))
#define SET(variable, p) set_object(variable, p)
#define STRING(s) ((java_lang_String*) string(s))
void* new_array(int object, int size, int length);
void* new_object(int type, int size);
void* new_array(jint object, jint size, jint length);
void* new_object(jint type, jint size);
void* set_object(void** target, void* o);
void* string(char* s);
*/
......@@ -23,38 +39,45 @@ 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);
void* new_array(jint object, jint size, jint length) {
int count = sizeof(jint) * 2 + size * length;
int* m = (jint*) 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);
void* new_object(jint type, jint size) {
int count = sizeof(jint) * 2 + size;
int* m = (jint*) calloc(1, count);
*m = type;
*(m+1) = 1;
return m + 2;
}
void* set_object(void** target, void* o) {
int* m = (int*) target;
int* m = (jint*) target;
if (*(m - 2) == 1) {
free(m - 1);
} else {
(*(m - 2))--;
}
*target = o;
m = (int*) target;
m = (jint*) target;
if (o != 0) {
(*(m - 2))++;
}
}
void* string(char* s) {
int len = strlen(s);
jchar* chars = NEW_ARRAY(sizeof(char), 1 * LENGTH(chars));
for (int i = 0; i < len; i++) {
chars[i] = s[i];
}
return java_lang_String_init_obj(chars);
}
*/
private char[] chars;
......
......@@ -7,8 +7,6 @@ import java.io.PrintStream;
*/
public class System {
// c: #include <stdio>
/**
* The stdout stream.
*/
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论