提交 0d2befdf authored 作者: Thomas Mueller's avatar Thomas Mueller

A Java parser / Java to C converter.

上级 67b5f248
...@@ -54,8 +54,14 @@ public class ClassObj { ...@@ -54,8 +54,14 @@ public class ClassObj {
*/ */
LinkedHashMap<String, MethodObj> methods = new LinkedHashMap<String, MethodObj>(); LinkedHashMap<String, MethodObj> methods = new LinkedHashMap<String, MethodObj>();
/**
* The list of native statements.
*/
ArrayList<Statement> nativeCode = new ArrayList<Statement>(); ArrayList<Statement> nativeCode = new ArrayList<Statement>();
/**
* The class number.
*/
int id; int id;
/** /**
...@@ -64,6 +70,9 @@ public class ClassObj { ...@@ -64,6 +70,9 @@ public class ClassObj {
* @param method the method * @param method the method
*/ */
void addMethod(MethodObj method) { void addMethod(MethodObj method) {
if (methods.containsKey(method.name)) {
throw new RuntimeException("Method overloading is not supported: " + method.name);
}
methods.put(method.name, method); methods.put(method.name, method);
} }
...@@ -195,6 +204,11 @@ class FieldObj { ...@@ -195,6 +204,11 @@ class FieldObj {
*/ */
Expr value; Expr value;
/**
* The class where this field is declared.
*/
ClassObj declaredClass;
} }
/** /**
......
...@@ -137,7 +137,11 @@ class OpExpr implements Expr { ...@@ -137,7 +137,11 @@ class OpExpr implements Expr {
} else if (right == null) { } else if (right == null) {
return left + op; return left + op;
} }
return left + " " + op + " " + right; if (op.equals(">>>")) {
// ujint / ujlong
return "(((u" + left.getType() + ") " + left + ") >> " + right + ")";
}
return "(" + left + " " + op + " " + right + ")";
} }
public Type getType() { public Type getType() {
...@@ -282,8 +286,7 @@ class VariableExpr implements Expr { ...@@ -282,8 +286,7 @@ class VariableExpr implements Expr {
} }
if (field != null) { if (field != null) {
if (field.isStatic) { if (field.isStatic) {
// buff.append(JavaParser.toC(field.type.type.name + "." + field.name)); buff.append(JavaParser.toC(field.declaredClass + "." + field.name));
buff.append(JavaParser.toC(name));
} else { } else {
buff.append(field.name); buff.append(field.name);
} }
...@@ -325,3 +328,69 @@ class ArrayExpr implements Expr { ...@@ -325,3 +328,69 @@ class ArrayExpr implements Expr {
} }
} }
/**
* An array initializer expression.
*/
class ArrayInitExpr implements Expr {
Type type;
ArrayList<Expr> list = new ArrayList<Expr>();
public Type getType() {
return type;
}
public String toString() {
StringBuilder buff = new StringBuilder("{ ");
int i = 0;
for (Expr e : list) {
if (i++ > 0) {
buff.append(", ");
}
buff.append(e.toString());
}
buff.append(" }");
return buff.toString();
}
}
/**
* A type cast expression.
*/
class CastExpr implements Expr {
Type type;
Expr expr;
public Type getType() {
return type;
}
public String toString() {
return "(" + type + ") " + expr;
}
}
/**
* An array access expression (get or set).
*/
class ArrayAccessExpr implements Expr {
Expr base;
Expr index;
public Type getType() {
Type t = new Type();
t.type = base.getType().type;
t.arrayLevel = base.getType().arrayLevel - 1;
return t;
}
public String toString() {
return base + "[" + index + "]";
}
}
...@@ -49,7 +49,7 @@ public class JavaParser { ...@@ -49,7 +49,7 @@ public class JavaParser {
private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>(); private ArrayList<Statement> nativeHeaders = new ArrayList<Statement>();
static { static {
String[] list = new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "if", String[] list = { "abstract", "continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements", "package", "synchronized", "boolean", "do", "goto", "private", "this", "break", "double", "implements",
"protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof",
"return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", "return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface",
...@@ -68,7 +68,7 @@ public class JavaParser { ...@@ -68,7 +68,7 @@ public class JavaParser {
addBuiltInType(id++, true, "float"); addBuiltInType(id++, true, "float");
addBuiltInType(id++, true, "boolean"); addBuiltInType(id++, true, "boolean");
addBuiltInType(id++, true, "short"); addBuiltInType(id++, true, "short");
String[] java = new String[] { "Boolean", "Byte", "Character", "Class", "ClassLoader", "Double", "Float", String[] java = { "Boolean", "Byte", "Character", "Class", "ClassLoader", "Double", "Float",
"Integer", "Long", "Math", "Number", "Object", "Runtime", "Short", "String", "StringBuffer", "Integer", "Long", "Math", "Number", "Object", "Runtime", "Short", "String", "StringBuffer",
"StringBuilder", "System", "Thread", "ThreadGroup", "ThreadLocal", "Throwable", "Void" }; "StringBuilder", "System", "Thread", "ThreadGroup", "ThreadLocal", "Throwable", "Void" };
for (String s : java) { for (String s : java) {
...@@ -290,14 +290,19 @@ public class JavaParser { ...@@ -290,14 +290,19 @@ public class JavaParser {
field.isFinal = isFinal; field.isFinal = isFinal;
field.isPublic = isPublic; field.isPublic = isPublic;
field.isPrivate = isPrivate; field.isPrivate = isPrivate;
field.declaredClass = classObj;
if (isStatic) { if (isStatic) {
classObj.addStaticField(field); classObj.addStaticField(field);
} else { } else {
classObj.addInstanceField(field); classObj.addInstanceField(field);
} }
if (readIf("=")) { if (readIf("=")) {
if (field.type.arrayLevel > 0 && readIf("{")) {
field.value = readArrayInit(field.type);
} else {
field.value = readExpr(); field.value = readExpr();
} }
}
read(";"); read(";");
} }
} }
...@@ -305,6 +310,24 @@ public class JavaParser { ...@@ -305,6 +310,24 @@ public class JavaParser {
} }
} }
private Expr readArrayInit(Type type) {
ArrayInitExpr expr = new ArrayInitExpr();
expr.type = new Type();
expr.type.type = type.type;
expr.type.arrayLevel = type.arrayLevel - 1;
while (true) {
expr.list.add(readExpr());
if (readIf("}")) {
break;
}
read(",");
if (readIf("}")) {
break;
}
}
return expr;
}
private void initThisPointer() { private void initThisPointer() {
thisPointer = new FieldObj(); thisPointer = new FieldObj();
thisPointer.isLocal = true; thisPointer.isLocal = true;
...@@ -507,8 +530,12 @@ public class JavaParser { ...@@ -507,8 +530,12 @@ public class JavaParser {
String varName = readIdentifier(); String varName = readIdentifier();
Expr value = null; Expr value = null;
if (readIf("=")) { if (readIf("=")) {
if (dec.type.arrayLevel > 0 && readIf("{")) {
value = readArrayInit(dec.type);
} else {
value = readExpr(); value = readExpr();
} }
}
FieldObj f = new FieldObj(); FieldObj f = new FieldObj();
f.isLocal = true; f.isLocal = true;
f.type = dec.type; f.type = dec.type;
...@@ -590,6 +617,20 @@ public class JavaParser { ...@@ -590,6 +617,20 @@ public class JavaParser {
private Expr readExpr3() { private Expr readExpr3() {
if (readIf("(")) { if (readIf("(")) {
if (isTypeOrIdentifier()) {
ParseState start = copyParseState();
String name = readTypeOrIdentifier();
ClassObj c = getClassIf(name);
if (c != null) {
read(")");
CastExpr expr = new CastExpr();
expr.type = new Type();
expr.type.type = c;
expr.expr = readExpr();
return expr;
}
current = start;
}
Expr expr = readExpr(); Expr expr = readExpr();
read(")"); read(")");
return expr; return expr;
...@@ -675,10 +716,11 @@ public class JavaParser { ...@@ -675,10 +716,11 @@ public class JavaParser {
if (t.arrayLevel == 0) { if (t.arrayLevel == 0) {
throw getSyntaxException("Not an array: " + expr); throw getSyntaxException("Not an array: " + expr);
} }
Expr arrayIndex = readExpr(); ArrayAccessExpr arrayExpr = new ArrayAccessExpr();
arrayExpr.base = expr;
arrayExpr.index = readExpr();
read("]"); read("]");
// TODO arrayGet or arraySet return arrayExpr;
return arrayIndex;
} else { } else {
break; break;
} }
...@@ -1199,12 +1241,21 @@ public class JavaParser { ...@@ -1199,12 +1241,21 @@ public class JavaParser {
for (ClassObj c : classes.values()) { for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".h */"); out.println("/* " + c.name + ".h */");
for (FieldObj f : c.staticFields.values()) { for (FieldObj f : c.staticFields.values()) {
StringBuilder buff = new StringBuilder();
buff.append("extern ");
if (f.isFinal) { if (f.isFinal) {
out.println("#define " + toC(c.name + "." + f.name) + " (" + f.value + ")"); buff.append("const ");
} else {
out.print("extern " + toC(f.type.toString()) + " " + toC(c.name + "." + f.name));
out.println(";");
} }
buff.append(toC(f.type.type.toString()));
if (!f.type.type.isPrimitive) {
buff.append("*");
}
buff.append(" ").append(toC(c.name + "." + f.name));
for (int i = 0; i < f.type.arrayLevel; i++) {
buff.append("[]");
}
buff.append(";");
out.println(buff.toString());
} }
out.println("struct " + toC(c.name) + " {"); out.println("struct " + toC(c.name) + " {");
for (FieldObj f : c.instanceFields.values()) { for (FieldObj f : c.instanceFields.values()) {
...@@ -1251,13 +1302,23 @@ public class JavaParser { ...@@ -1251,13 +1302,23 @@ public class JavaParser {
out.println(s); out.println(s);
} }
for (FieldObj f : c.staticFields.values()) { for (FieldObj f : c.staticFields.values()) {
if (!f.isFinal) { StringBuilder buff = new StringBuilder();
out.print(toC(f.type.toString()) + " " + toC(c.name + "." + f.name)); if (f.isFinal) {
if (f.value != null) { buff.append("const ");
out.print(" = " + f.value);
} }
out.println(";"); buff.append(toC(f.type.type.toString()));
if (!f.type.type.isPrimitive) {
buff.append("*");
}
buff.append(" ").append(toC(c.name + "." + f.name));
for (int i = 0; i < f.type.arrayLevel; i++) {
buff.append("[]");
}
if (f.value != null) {
buff.append(" = " + f.value);
} }
buff.append(";");
out.println(buff.toString());
} }
for (MethodObj m : c.methods.values()) { for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "("); out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
......
...@@ -62,6 +62,7 @@ public class Test extends TestBase { ...@@ -62,6 +62,7 @@ public class Test extends TestBase {
parser.parse("src/tools/org/h2", "java.lang.String"); 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.io.PrintStream");
parser.parse("src/tools/org/h2", "java.lang.System"); parser.parse("src/tools/org/h2", "java.lang.System");
parser.parse("src/tools/org/h2", "java.util.Arrays");
parser.parse("src/tools", "org.h2.java.TestApp"); parser.parse("src/tools", "org.h2.java.TestApp");
PrintWriter w = new PrintWriter(System.out); PrintWriter w = new PrintWriter(System.out);
......
/*
* Copyright 2004-2010 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.io; package org.h2.java.io;
/** /**
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2010 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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
A simple implementation of the java.lang.* package for the Java parser.
</body></html>
\ No newline at end of file
/*
* Copyright 2004-2010 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; package org.h2.java.lang;
/** /**
...@@ -5,8 +11,10 @@ package org.h2.java.lang; ...@@ -5,8 +11,10 @@ package org.h2.java.lang;
*/ */
public class Object { public class Object {
private static final int[] K = { 1 };
public int hashCode() { public int hashCode() {
return 0; return K[0];
} }
public boolean equals(Object other) { public boolean equals(Object other) {
......
/*
* Copyright 2004-2010 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; package org.h2.java.lang;
/* c: /* c:
...@@ -6,6 +12,7 @@ package org.h2.java.lang; ...@@ -6,6 +12,7 @@ package org.h2.java.lang;
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#include <stdint.h>
#define jvoid void #define jvoid void
#define jboolean int8_t #define jboolean int8_t
...@@ -15,6 +22,8 @@ package org.h2.java.lang; ...@@ -15,6 +22,8 @@ package org.h2.java.lang;
#define jlong int64_t #define jlong int64_t
#define jfloat float #define jfloat float
#define jdouble double #define jdouble double
#define ujint uint32_t
#define ujlong uint64_t
#define true 1 #define true 1
#define false 0 #define false 0
#define null 0 #define null 0
......
/*
* Copyright 2004-2010 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; package org.h2.java.lang;
import java.io.PrintStream; import java.io.PrintStream;
...@@ -22,9 +28,11 @@ public class System { ...@@ -22,9 +28,11 @@ public class System {
* @param destPos the first element in the destination * @param destPos the first element in the destination
* @param length the number of element to copy * @param length the number of element to copy
*/ */
public static void arraycopy(java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length) { public static void arraycopyChars(char[] src, int srcPos, char[] dest, int destPos, int length) {
// TODO /* c:
// c: memmove(dest + destPos, src + srcPos, length); memmove(((jchar*)dest) + destPos,
((jchar*)src) + srcPos, sizeof(jchar) * length);
*/
} }
/** /**
...@@ -37,8 +45,12 @@ public class System { ...@@ -37,8 +45,12 @@ public class System {
* @param destPos the first element in the destination * @param destPos the first element in the destination
* @param length the number of element to copy * @param length the number of element to copy
*/ */
public static void arraycopyChars(char[] src, int srcPos, char[] dest, int destPos, int length) { public static void arraycopyByte(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
// c: memmove(((jchar*)dest) + destPos, ((jchar*)src) + srcPos, sizeof(jchar) * length); /* c:
memmove(((jbyte*)dest) + destPos,
((jbyte*)src) + srcPos, sizeof(jbyte) * length);
*/
} }
} }
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2010 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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
A simple implementation of the java.lang.* package for the Java parser.
</body></html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2010 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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
A Java parser implementation.
</body></html>
\ No newline at end of file
/*
* Copyright 2004-2010 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.util;
/**
* An simple implementation of java.util.Arrays
*/
public class Arrays {
/**
* Fill an array with the given value.
*
* @param array the array
* @param x the value
*/
public static void fill(char[] array, char x) {
for (int i = 0; i < array.length; i++) {
array[i] = x;
}
}
/**
* Fill an array with the given value.
*
* @param array the array
* @param x the value
*/
public static void fillByte(byte[] array, byte x) {
for (int i = 0; i < array.length; i++) {
array[i] = x;
}
}
/**
* Fill an array with the given value.
*
* @param array the array
* @param x the value
*/
public static void fillInt(int[] array, int x) {
for (int i = 0; i < array.length; i++) {
array[i] = x;
}
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2010 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
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;">
A simple implementation of the java.lang.* package for the Java parser.
</body></html>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论