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

A Java parser / Java to C converter.

上级 aa8d9681
......@@ -54,7 +54,9 @@ public class ClassObj {
*/
LinkedHashMap<String, MethodObj> methods = new LinkedHashMap<String, MethodObj>();
ArrayList<Statement> nativeInitializers = new ArrayList<Statement>();
ArrayList<Statement> nativeCode = new ArrayList<Statement>();
String id;
/**
* Add a method.
......
......@@ -21,14 +21,33 @@ public interface Expr {
*/
class CallExpr implements Expr {
Expr expr;
String name;
ArrayList<Expr> args = new ArrayList<Expr>();
final JavaParser context;
final Expr expr;
final ArrayList<Expr> args = new ArrayList<Expr>();
final boolean isStatic;
final String className;
final String name;
CallExpr(JavaParser context, Expr expr, String className, String name, boolean isStatic) {
this.context = context;
this.expr = expr;
this.className = className;
this.name = name;
this.isStatic = isStatic;
}
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append(expr.toString() + "_" + JavaParser.toC(name)).append("(");
if (className != null) {
buff.append(JavaParser.toC(className + "." + name)).append("(");
} else {
buff.append(JavaParser.toC(expr.getType().type.name + "." + name)).append("(");
}
int i = 0;
if (expr != null) {
buff.append(expr.toString());
i++;
}
for (Expr a : args) {
if (i > 0) {
buff.append(", ");
......@@ -38,10 +57,12 @@ class CallExpr implements Expr {
}
return buff.append(")").toString();
}
public Type getType() {
// TODO
return null;
}
}
/**
......@@ -136,9 +157,23 @@ class NewExpr implements Expr {
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append("new " + type);
for (Expr e : arrayInitExpr) {
buff.append("[").append(e).append("]");
if (arrayInitExpr.size() > 0) {
if (type.isPrimitive) {
buff.append("NEW_ARRAY(sizeof(" + type + ")");
buff.append(", 1 ");
for (Expr e : arrayInitExpr) {
buff.append("* ").append(e);
}
buff.append(")");
} else {
buff.append("NEW_OBJ_ARRAY(1 ");
for (Expr e : arrayInitExpr) {
buff.append("* ").append(e);
}
buff.append(")");
}
} else {
buff.append("NEW_OBJ(" + type.id + ", " + type + ")");
}
return buff.toString();
}
......@@ -237,13 +272,23 @@ class VariableExpr implements Expr {
public String toString() {
StringBuilder buff = new StringBuilder();
if (base != null) {
buff.append(base.toString()).append("->");
}
if (field != null) {
buff.append(field.name);
if (field != null && "length".equals(field.name) && base != null && base.getType() != null && base.getType().arrayLevel > 0) {
buff.append("LENGTH(");
buff.append(base.toString());
buff.append(")");
} else {
buff.append(JavaParser.toC(name));
if (base != null) {
buff.append(base.toString()).append("->");
}
if (field != null) {
if (field.isStatic) {
buff.append(JavaParser.toC(field.type.type.name + "." + field.name));
} else {
buff.append(field.name);
}
} else {
buff.append(JavaParser.toC(name));
}
}
return buff.toString();
}
......@@ -262,12 +307,12 @@ class VariableExpr implements Expr {
*/
class ArrayExpr implements Expr {
Expr obj;
Expr expr;
ArrayList<Expr> indexes = new ArrayList<Expr>();
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append(obj.toString());
buff.append(expr.toString());
for (Expr e : indexes) {
buff.append('[').append(e.toString()).append(']');
}
......@@ -275,7 +320,7 @@ class ArrayExpr implements Expr {
}
public Type getType() {
return obj.getType();
return expr.getType();
}
}
......@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
......@@ -41,6 +42,8 @@ public class JavaParser {
private HashMap<String, ClassObj> classes = new HashMap<String, ClassObj>();
private LinkedHashMap<String, FieldObj> localFields = new LinkedHashMap<String, FieldObj>();
private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>();
static {
String[] list = new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements",
......@@ -122,6 +125,13 @@ public class JavaParser {
importMap.put(importClass, importPackageName);
read(";");
}
while (true) {
Statement s = readNativeStatementIf();
if (s == null) {
break;
}
nativeHeaders.add(s);
}
while (true) {
classObj = new ClassObj();
classObj.isPublic = readIf("public");
......@@ -192,9 +202,12 @@ public class JavaParser {
break;
}
thisPointer = null;
Statement s = readNativeStatementIf();
if (s != null) {
classObj.nativeInitializers.add(s);
while (true) {
Statement s = readNativeStatementIf();
if (s == null) {
break;
}
classObj.nativeCode.add(s);
}
thisPointer = null;
boolean isStatic = false;
......@@ -354,6 +367,7 @@ public class JavaParser {
}
StatementNative stat = new StatementNative();
stat.code = source.substring(start, current.index).trim();
current.index += 2;
read();
return stat;
}
......@@ -618,9 +632,7 @@ public class JavaParser {
if (readIf(".")) {
String n = readIdentifier();
if (readIf("(")) {
CallExpr e2 = new CallExpr();
e2.expr = expr;
e2.name = n;
CallExpr e2 = new CallExpr(this, expr, null, n, false);
if (!readIf(")")) {
while (true) {
e2.args.add(readExpr());
......@@ -696,11 +708,7 @@ public class JavaParser {
}
String name = readIdentifier();
if (readIf("(")) {
CallExpr expr = new CallExpr();
expr.name = name;
VariableExpr ve = new VariableExpr();
ve.field = thisPointer;
expr.expr = ve;
CallExpr expr = new CallExpr(this, null, classObj.name, name, false);
if (!readIf(")")) {
while (true) {
expr.args.add(readExpr());
......@@ -720,13 +728,41 @@ public class JavaParser {
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
}
} else {
expr.field = f;
}
}
}
expr.field = f;
if (f != null && (!f.isLocal && !f.isStatic)) {
VariableExpr ve = new VariableExpr();
ve.field = thisPointer;
......@@ -1143,16 +1179,17 @@ public class JavaParser {
* @param out the output writer
*/
void writeHeader(PrintWriter out) {
for (Statement s : nativeHeaders) {
out.println(s);
}
out.println();
for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".h */");
for (FieldObj f : c.staticFields.values()) {
if (f.isFinal) {
out.println("#define " + toC(c.name + "." + f.name) + " (" + f.value + ")");
} else {
out.print("extern " + toC(f.type.toString()) + " " + f.name);
if (f.value != null) {
out.print(" = " + f.value);
}
out.print("extern " + toC(f.type.toString()) + " " + toC(c.name + "." + f.name));
out.println(";");
}
}
......@@ -1164,7 +1201,11 @@ public class JavaParser {
}
out.println(";");
}
if (c.instanceFields.size() == 0) {
out.println("int dummy;");
}
out.println("};");
out.println("typedef struct " + toC(c.name) + " " + toC(c.name) + ";");
for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0;
......@@ -1193,9 +1234,18 @@ public class JavaParser {
void writeSource(PrintWriter out) {
for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".c */");
for (Statement s : c.nativeInitializers) {
for (Statement s : c.nativeCode) {
out.println(s);
}
for (FieldObj f : c.staticFields.values()) {
if (!f.isFinal) {
out.print(toC(f.type.toString()) + " " + toC(c.name + "." + f.name));
if (f.value != null) {
out.print(" = " + f.value);
}
out.println(";");
}
}
for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0;
......@@ -1257,6 +1307,10 @@ public class JavaParser {
return identifier.replace('.', '_');
}
ClassObj getClassObj() {
return classObj;
}
}
/**
......
......@@ -12,7 +12,9 @@ import java.util.ArrayList;
* A statement.
*/
public interface Statement {
// toString
}
/**
......@@ -143,9 +145,21 @@ class ForStatement implements Statement {
StringBuffer buff = new StringBuffer();
buff.append("for (");
if (iterableType != null) {
buff.append(iterableType).append(' ');
buff.append(iterableVariable).append(": ");
buff.append(iterable);
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(") {\n");
buff.append(JavaParser.indent(iterableType + " " + iterableVariable + " = " + iterable + "["+ idx +"];\n"));
buff.append(block.toString()).append("}");
} else {
// TODO iterate over a collection
buff.append(iterableType).append(' ');
buff.append(iterableVariable).append(": ");
buff.append(iterable);
buff.append(") {\n");
buff.append(block.toString()).append("}");
}
} else {
buff.append(init.toString());
buff.append(" ").append(condition.toString()).append("; ");
......@@ -155,9 +169,9 @@ class ForStatement implements Statement {
}
buff.append(updates.get(i));
}
buff.append(") {\n");
buff.append(block.toString()).append("}");
}
buff.append(") {\n");
buff.append(block.toString()).append("}");
return buff.toString();
}
}
......
......@@ -34,7 +34,6 @@ public class Test extends TestBase {
// import *
// initializer blocks
// access to static fields with instance variable
// method call with "this": this.toString()
// final variables (within blocks, parameter list)
// Identifier : (labels)
// ClassOrInterfaceDeclaration within blocks (or any other nested classes)
......@@ -56,6 +55,7 @@ public class Test extends TestBase {
assertEquals("6.022137e+23f", JavaParser.readNumber("6.022137e+23f+1"));
JavaParser parser = new JavaParser();
parser.parse("src/tools/org/h2", "java.lang.Object");
parser.parse("src/tools/org/h2", "java.lang.String");
parser.parse("src/tools/org/h2", "java.io.PrintStream");
parser.parse("src/tools/org/h2", "java.lang.System");
......
package org.h2.java.lang;
/* c:
#define boolean int
#define LENGTH(a) (*(((int*)(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 SET(variable, p) set_object(variable, p)
void* new_array(int object, int size, int length);
void* new_object(int type, int size);
void* set_object(void** target, void* o);
*/
/**
* A java.lang.String implementation.
*/
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);
*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);
*m = type;
*(m+1) = 1;
return m + 2;
}
void* set_object(void** target, void* o) {
int* m = (int*) target;
if (*(m - 2) == 1) {
free(m - 1);
} else {
(*(m - 2))--;
}
*target = o;
m = (int*) target;
if (o != 0) {
(*(m - 2))++;
}
}
*/
private char[] chars;
private int hashCode;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论