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

A Java parser / Java to C converter.

上级 4ead520a
......@@ -54,6 +54,8 @@ public class ClassObj {
*/
LinkedHashMap<String, MethodObj> methods = new LinkedHashMap<String, MethodObj>();
ArrayList<Statement> nativeInitializers = new ArrayList<Statement>();
/**
* Add a method.
*
......@@ -134,6 +136,11 @@ class MethodObj {
* Whether this method is public.
*/
boolean isPublic;
/**
* Whether this method is native.
*/
boolean isNative;
}
/**
......@@ -146,6 +153,11 @@ class FieldObj {
*/
Type type;
/**
* Whether this is a local field.
*/
boolean isLocal;
/**
* The field name.
*/
......@@ -194,13 +206,13 @@ class Type {
int arrayLevel;
public String toString() {
if (arrayLevel == 0) {
return type.name;
}
StringBuilder buff = new StringBuilder();
buff.append(JavaParser.toC(type.name));
if (!type.isPrimitive) {
buff.append("*");
}
for (int i = 0; i < arrayLevel; i++) {
buff.append("[]");
buff.append("*");
}
return buff.toString();
}
......
......@@ -13,17 +13,21 @@ import java.util.ArrayList;
*/
public interface Expr {
// toString
Type getType();
}
/**
* A method call.
*/
class CallExpr implements Expr {
String object;
Expr expr;
String name;
ArrayList<Expr> args = new ArrayList<Expr>();
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append(JavaParser.toC(object)).append("(");
buff.append(expr.toString() + "_" + JavaParser.toC(name)).append("(");
int i = 0;
for (Expr a : args) {
if (i > 0) {
......@@ -34,12 +38,17 @@ class CallExpr implements Expr {
}
return buff.append(")").toString();
}
public Type getType() {
// TODO
return null;
}
}
/**
* A assignment expression.
*/
class AssignExpr implements Expr {
Expr left;
String op;
Expr right;
......@@ -47,36 +56,60 @@ class AssignExpr implements Expr {
public String toString() {
return left + " " + op + " " + right;
}
public Type getType() {
// TODO
return null;
}
}
/**
* A conditional expression.
*/
class ConditionalExpr implements Expr {
Expr condition;
Expr ifTrue, ifFalse;
public String toString() {
return condition + " ? " + ifTrue + " : " + ifFalse;
}
public Type getType() {
// TODO
return null;
}
}
/**
* A literal.
*/
class LiteralExpr implements Expr {
String literal;
public String toString() {
return literal;
}
public Type getType() {
// TODO
return null;
}
}
/**
* An operation.
*/
class OpExpr implements Expr {
Expr left;
String op;
Expr right;
public String toString() {
if (left == null) {
return op + right;
......@@ -85,16 +118,38 @@ class OpExpr implements Expr {
}
return left + " " + op + " " + right;
}
public Type getType() {
// TODO
return null;
}
}
/**
* A "new" expression.
*/
class NewExpr implements Expr {
String className;
ClassObj type;
ArrayList<Expr> arrayInitExpr = new ArrayList<Expr>();
public String toString() {
return "new " + className;
StringBuilder buff = new StringBuilder();
buff.append("new " + type);
for (Expr e : arrayInitExpr) {
buff.append("[").append(e).append("]");
}
return buff.toString();
}
public Type getType() {
Type t = new Type();
t.type = type;
t.arrayLevel = arrayInitExpr.size();
return t;
}
}
/**
......@@ -111,6 +166,11 @@ class StringExpr implements Expr {
return "\"" + javaEncode(text) + "\"";
}
public Type getType() {
// TODO
return null;
}
/**
* Encode the String to Java syntax.
*
......@@ -165,3 +225,57 @@ class StringExpr implements Expr {
return buff.toString();
}
}
/**
* A variable.
*/
class VariableExpr implements Expr {
Expr base;
FieldObj field;
String name;
public String toString() {
StringBuilder buff = new StringBuilder();
if (base != null) {
buff.append(base.toString()).append("->");
}
if (field != null) {
buff.append(field.name);
} else {
buff.append(JavaParser.toC(name));
}
return buff.toString();
}
public Type getType() {
if (field == null) {
return null;
}
return field.type;
}
}
/**
* A array access expression.
*/
class ArrayExpr implements Expr {
Expr obj;
ArrayList<Expr> indexes = new ArrayList<Expr>();
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append(obj.toString());
for (Expr e : indexes) {
buff.append('[').append(e.toString()).append(']');
}
return buff.toString();
}
public Type getType() {
return obj.getType();
}
}
......@@ -12,6 +12,7 @@ import java.io.RandomAccessFile;
import java.text.ParseException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
/**
* Converts Java to C.
......@@ -29,15 +30,16 @@ 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 final String fileName;
private String source;
private ParseState current = new ParseState();
private String packageName;
private ClassObj classObj;
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>();
static {
String[] list = new String[] { "abstract", "continue", "for", "new", "switch", "assert", "default", "if",
......@@ -67,10 +69,6 @@ public class JavaParser {
}
}
JavaParser(String baseDir, String className) {
this.fileName = baseDir + "/" + className.replace('.', '/') + ".java";
}
private static void addBuiltInType(boolean primitive, String type) {
ClassObj typeObj = new ClassObj();
typeObj.name = type;
......@@ -80,8 +78,13 @@ public class JavaParser {
/**
* Parse the source code.
*
* @param baseDir the base directory
* @param className the fully qualified name of the class to parse
*/
void parse() {
void parse(String baseDir, String className) {
String fileName = baseDir + "/" + className.replace('.', '/') + ".java";
current = new ParseState();
try {
RandomAccessFile file = new RandomAccessFile(fileName, "r");
byte[] buff = new byte[(int) file.length()];
......@@ -91,6 +94,7 @@ public class JavaParser {
} catch (IOException e) {
throw new RuntimeException(e);
}
source = replaceUnicode(source);
source = removeRemarks(source);
try {
readToken();
......@@ -100,14 +104,21 @@ public class JavaParser {
}
}
private String cleanPackageName(String name) {
if (name.startsWith("org.h2.java.lang") || name.startsWith("org.h2.java.io")) {
return name.substring("org.h2.".length());
}
return name;
}
private void parseCompilationUnit() {
if (readIf("package")) {
packageName = readQualifiedIdentifier();
packageName = cleanPackageName(readQualifiedIdentifier());
read(";");
}
while (readIf("import")) {
String importPackageName = readQualifiedIdentifier();
String importClass = importPackageName.substring(importPackageName.lastIndexOf('.'));
String importPackageName = cleanPackageName(readQualifiedIdentifier());
String importClass = importPackageName.substring(importPackageName.lastIndexOf('.') + 1);
importMap.put(importClass, importPackageName);
read(";");
}
......@@ -132,7 +143,22 @@ public class JavaParser {
}
}
private boolean isTypeOrIdentifier() {
if (BUILT_IN_TYPES.containsKey(current.token)) {
return true;
}
return current.type == TOKEN_IDENTIFIER;
}
private ClassObj getClass(String type) {
ClassObj c = getClassIf(type);
if (c == null) {
throw new RuntimeException("Unknown type: " + type);
}
return c;
}
private ClassObj getClassIf(String type) {
ClassObj c = BUILT_IN_TYPES.get(type);
if (c != null) {
return c;
......@@ -145,7 +171,7 @@ public class JavaParser {
if (mappedType == null) {
mappedType = JAVA_IMPORT_MAP.get(type);
if (mappedType == null) {
throw new RuntimeException("Unknown type: " + type);
return null;
}
}
c = classes.get(mappedType);
......@@ -158,31 +184,31 @@ public class JavaParser {
return c;
}
private boolean isClass() {
if (BUILT_IN_TYPES.containsKey(current.token)) {
return true;
}
if (current.type != TOKEN_IDENTIFIER) {
return false;
}
return Character.isUpperCase(current.token.charAt(0));
}
private void parseClassBody() {
read("{");
localFields.clear();
while (true) {
if (readIf("}")) {
break;
}
thisPointer = null;
Statement s = readNativeStatementIf();
if (s != null) {
classObj.nativeInitializers.add(s);
}
thisPointer = null;
boolean isStatic = false;
boolean isFinal = false;
boolean isPrivate = false;
boolean isPublic = false;
boolean isNative = false;
while (true) {
if (readIf("static")) {
isStatic = true;
} else if (readIf("final")) {
isFinal = true;
} else if (readIf("native")) {
isNative = true;
} else if (readIf("private")) {
isPrivate = true;
} else if (readIf("public")) {
......@@ -193,52 +219,81 @@ public class JavaParser {
}
if (readIf("{")) {
MethodObj method = new MethodObj();
method.name = "init";
method.name = isStatic ? "cl_init_obj" : "init_obj";
method.isStatic = isStatic;
localFields.clear();
if (!isStatic) {
initThisPointer();
}
method.block = readStatement();
classObj.addMethod(method);
} else {
Type type = readType();
String name = readIdentifier();
String typeName = readTypeOrIdentifier();
Type type = readType(typeName);
MethodObj method = new MethodObj();
method.returnType = type;
method.isStatic = isStatic;
method.isFinal = isFinal;
method.isPublic = isPublic;
method.isPrivate = isPrivate;
method.isNative = isNative;
localFields.clear();
if (!isStatic) {
initThisPointer();
}
if (readIf("(")) {
MethodObj method = new MethodObj();
method.name = name;
method.returnType = type;
method.isStatic = isStatic;
method.isFinal = isFinal;
method.isPublic = isPublic;
method.isPrivate = isPrivate;
if (type.type != classObj) {
throw getSyntaxException("Constructor of wrong type: " + type);
}
method.name = "init_obj";
parseFormalParameters(method);
if (!readIf(";")) {
method.block = readStatement();
}
classObj.addMethod(method);
} else {
FieldObj field = new FieldObj();
field.type = type;
field.name = name;
field.isStatic = isStatic;
field.isFinal = isFinal;
field.isPublic = isPublic;
field.isPrivate = isPrivate;
if (isStatic) {
classObj.addStaticField(field);
String name = readIdentifier();
method.name = name;
if (readIf("(")) {
parseFormalParameters(method);
if (!readIf(";")) {
method.block = readStatement();
}
classObj.addMethod(method);
} else {
classObj.addInstanceField(field);
}
if (readIf("=")) {
field.value = readExpr();
FieldObj field = new FieldObj();
field.type = type;
field.name = name;
field.isStatic = isStatic;
field.isFinal = isFinal;
field.isPublic = isPublic;
field.isPrivate = isPrivate;
if (isStatic) {
classObj.addStaticField(field);
} else {
classObj.addInstanceField(field);
}
if (readIf("=")) {
field.value = readExpr();
}
read(";");
}
read(";");
}
}
}
}
private Type readType() {
String typeName = readTypeOrIdentifier();
private void initThisPointer() {
thisPointer = new FieldObj();
thisPointer.isLocal = true;
thisPointer.name = "this";
thisPointer.type = new Type();
thisPointer.type.type = classObj;
}
private Type readType(String name) {
Type type = new Type();
type.type = getClass(typeName);
type.type = getClass(name);
while (readIf("[")) {
read("]");
type.arrayLevel++;
......@@ -255,7 +310,9 @@ public class JavaParser {
}
while (true) {
FieldObj field = new FieldObj();
field.type = readType();
field.isLocal = true;
String typeName = readTypeOrIdentifier();
field.type = readType(typeName);
field.name = readIdentifier();
method.parameters.add(field);
if (readIf(")")) {
......@@ -271,14 +328,46 @@ public class JavaParser {
return read();
}
}
return readIdentifier();
String s = readIdentifier();
while (readIf(".")) {
s += "." + readIdentifier();
}
return s;
}
private Statement readNativeStatementIf() {
if (readIf("//")) {
read();
int start = current.index;
while (source.charAt(current.index) != '\n') {
current.index++;
}
StatementNative stat = new StatementNative();
stat.code = source.substring(start, current.index).trim();
read();
return stat;
} else if (readIf("/*")) {
read();
int start = current.index;
while (source.charAt(current.index) != '*' || source.charAt(current.index + 1) != '/') {
current.index++;
}
StatementNative stat = new StatementNative();
stat.code = source.substring(start, current.index).trim();
read();
return stat;
}
return null;
}
private Statement readStatement() {
Statement s = readNativeStatementIf();
if (s != null) {
return s;
}
if (readIf(";")) {
return new EmptyStatement();
}
if (readIf("{")) {
} else if (readIf("{")) {
StatementBlock stat = new StatementBlock();
while (true) {
stat.instructions.add(readStatement());
......@@ -346,12 +435,24 @@ public class JavaParser {
} else if (readIf("for")) {
ForStatement forStat = new ForStatement();
read("(");
forStat.init = readStatement();
forStat.condition = readExpr();
read(";");
do {
forStat.updates.add(readExpr());
} while (readIf(","));
ParseState back = copyParseState();
try {
String typeName = readTypeOrIdentifier();
Type type = readType(typeName);
String name = readIdentifier();
read(":");
forStat.iterableType = type;
forStat.iterableVariable = name;
forStat.iterable = readExpr();
} catch (Exception e) {
current = back;
forStat.init = readStatement();
forStat.condition = readExpr();
read(";");
do {
forStat.updates.add(readExpr());
} while (readIf(","));
}
read(")");
forStat.block = readStatement();
return forStat;
......@@ -372,22 +473,25 @@ public class JavaParser {
}
return returnStat;
} else {
if (isClass()) {
if (isTypeOrIdentifier()) {
ParseState start = copyParseState();
Type type = readType();
if (readIf(".")) {
current = start;
// ExprStatement
} else {
String name = readTypeOrIdentifier();
ClassObj c = getClassIf(name);
if (c != null) {
VarDecStatement dec = new VarDecStatement();
dec.type = type;
dec.type = readType(name);
while (true) {
String name = readIdentifier();
String varName = readIdentifier();
Expr value = null;
if (readIf("=")) {
value = readExpr();
}
dec.variables.add(name);
FieldObj f = new FieldObj();
f.isLocal = true;
f.type = dec.type;
f.name = varName;
localFields.put(varName, f);
dec.variables.add(varName);
dec.values.add(value);
if (readIf(";")) {
break;
......@@ -396,6 +500,8 @@ public class JavaParser {
}
return dec;
}
current = start;
// ExprStatement
}
ExprStatement stat = new ExprStatement();
stat.expr = readExpr();
......@@ -442,15 +548,19 @@ public class JavaParser {
private Expr readExpr2() {
Expr expr = readExpr3();
String infixOp = current.token;
if (readIf("||") || readIf("&&") || readIf("|") || readIf("^") || readIf("&") || readIf("==") || readIf("!=")
|| readIf("<") || readIf(">") || readIf("<=") || readIf(">=") || readIf("<<") || readIf(">>")
|| readIf(">>>") || readIf("+") || readIf("-") || readIf("*") || readIf("/") || readIf("%")) {
OpExpr opExpr = new OpExpr();
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr3();
expr = opExpr;
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("%")) {
OpExpr opExpr = new OpExpr();
opExpr.left = expr;
opExpr.op = infixOp;
opExpr.right = readExpr3();
expr = opExpr;
} else {
break;
}
}
return expr;
}
......@@ -480,13 +590,6 @@ public class JavaParser {
}
private Expr readExpr4() {
if (readIf("new")) {
NewExpr expr = new NewExpr();
expr.className = readQualifiedIdentifier();
read("(");
read(")");
return expr;
}
if (readIf("false")) {
LiteralExpr expr = new LiteralExpr();
expr.literal = "false";
......@@ -508,16 +611,96 @@ public class JavaParser {
readToken();
return expr;
}
Expr expr;
expr = readExpr5();
Type t = expr.getType();
while (true) {
if (readIf(".")) {
String n = readIdentifier();
if (readIf("(")) {
CallExpr e2 = new CallExpr();
e2.expr = expr;
e2.name = n;
if (!readIf(")")) {
while (true) {
e2.args.add(readExpr());
if (!readIf(",")) {
read(")");
break;
}
}
}
expr = e2;
} else {
VariableExpr e2 = new VariableExpr();
e2.base = expr;
expr = e2;
if (n.equals("length") && t.arrayLevel > 0) {
e2.field = new FieldObj();
e2.field.name = "length";
} else {
if (t == null || t.type == null) {
e2.name = n;
} else {
FieldObj f = t.type.instanceFields.get(n);
if (f == null) {
throw getSyntaxException("Unknown field: " + expr + "." + n);
}
e2.field = f;
}
}
}
} else if (readIf("[")) {
if (t.arrayLevel == 0) {
throw getSyntaxException("Not an array: " + expr);
}
Expr arrayIndex = readExpr();
read("]");
// TODO arrayGet or arraySet
return arrayIndex;
} else {
break;
}
}
return expr;
}
private Expr readExpr5() {
if (readIf("new")) {
NewExpr expr = new NewExpr();
String typeName = readTypeOrIdentifier();
expr.type = getClass(typeName);
if (readIf("(")) {
read(")");
} else {
while (readIf("[")) {
expr.arrayInitExpr.add(readExpr());
read("]");
}
}
return expr;
}
if (current.type == TOKEN_LITERAL_STRING) {
StringExpr expr = new StringExpr();
expr.text = current.token.substring(1);
readToken();
return expr;
}
String name = readQualifiedIdentifier();
if (readIf("this")) {
VariableExpr expr = new VariableExpr();
expr.field = thisPointer;
if (thisPointer == null) {
throw getSyntaxException("this usage in static context");
}
return expr;
}
String name = readIdentifier();
if (readIf("(")) {
CallExpr expr = new CallExpr();
expr.object = name;
expr.name = name;
VariableExpr ve = new VariableExpr();
ve.field = thisPointer;
expr.expr = ve;
if (!readIf(")")) {
while (true) {
expr.args.add(readExpr());
......@@ -530,6 +713,28 @@ public class JavaParser {
return expr;
}
VariableExpr expr = new VariableExpr();
FieldObj f = localFields.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) {
name = imp;
}
}
}
}
expr.field = f;
if (f != null && (!f.isLocal && !f.isStatic)) {
VariableExpr ve = new VariableExpr();
ve.field = thisPointer;
expr.base = ve;
if (thisPointer == null) {
throw getSyntaxException("this usage in static context");
}
}
expr.name = name;
return expr;
}
......@@ -542,6 +747,21 @@ public class JavaParser {
private String readQualifiedIdentifier() {
String id = readIdentifier();
if (localFields.containsKey(id)) {
return id;
}
if (classObj != null) {
if (classObj.staticFields.containsKey(id)) {
return id;
}
if (classObj.instanceFields.containsKey(id)) {
return id;
}
}
String fullName = importMap.get(id);
if (fullName != null) {
return fullName;
}
while (readIf(".")) {
id += "." + readIdentifier();
}
......@@ -582,6 +802,9 @@ public class JavaParser {
* @return the cleaned text
*/
static String replaceUnicode(String s) {
if (s.indexOf("\\u") < 0) {
return s;
}
StringBuilder buff = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
if (s.substring(i).startsWith("\\\\")) {
......@@ -609,10 +832,6 @@ public class JavaParser {
* @return the cleaned source code
*/
static String removeRemarks(String s) {
int idx = s.indexOf("\\u");
if (idx > 0) {
s = replaceUnicode(s);
}
char[] chars = s.toCharArray();
for (int i = 0; i >= 0 && i < s.length(); i++) {
if (s.charAt(i) == '\'') {
......@@ -639,7 +858,7 @@ public class JavaParser {
continue;
}
String sub = s.substring(i);
if (sub.startsWith("/*")) {
if (sub.startsWith("/*") && !sub.startsWith("/* c:")) {
int j = i;
i = s.indexOf("*/", i + 2) + 2;
for (; j < i; j++) {
......@@ -647,7 +866,7 @@ public class JavaParser {
chars[j] = ' ';
}
}
} else if (sub.startsWith("//")) {
} else if (sub.startsWith("//") && !sub.startsWith("// c:")) {
int j = i;
i = s.indexOf('\n', i);
while (j < i) {
......@@ -769,8 +988,12 @@ public class JavaParser {
current.index++;
}
break;
case '*':
case '/':
if (source.charAt(current.index) == '*' || source.charAt(current.index) == '/') {
current.index++;
}
break;
case '*':
case '~':
case '!':
case '=':
......@@ -915,11 +1138,11 @@ public class JavaParser {
}
/**
* Write the C representation.
* Write the C header.
*
* @param out the output writer
*/
void writeC(PrintWriter out) {
void writeHeader(PrintWriter out) {
for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".h */");
for (FieldObj f : c.staticFields.values()) {
......@@ -945,6 +1168,10 @@ public class JavaParser {
for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0;
if (!m.isStatic) {
out.print(toC(c.name) + "* this");
i++;
}
for (FieldObj p : m.parameters) {
if (i > 0) {
out.print(", ");
......@@ -954,13 +1181,28 @@ public class JavaParser {
}
out.println(");");
}
out.println();
}
out.println();
}
/**
* Write the C source code.
*
* @param out the output writer
*/
void writeSource(PrintWriter out) {
for (ClassObj c : classes.values()) {
out.println("/* " + c.name + ".c */");
for (Statement s : c.nativeInitializers) {
out.println(s);
}
for (MethodObj m : c.methods.values()) {
out.print(m.returnType + " " + toC(c.name) + "_" + m.name + "(");
int i = 0;
if (!m.isStatic) {
out.print(toC(c.name) + "* this");
i++;
}
for (FieldObj p : m.parameters) {
if (i > 0) {
out.print(", ");
......@@ -969,8 +1211,11 @@ public class JavaParser {
i++;
}
out.println(") {");
out.print(m.block.toString());
if (m.block != null) {
out.print(m.block.toString());
}
out.println("}");
out.println();
}
}
}
......@@ -1018,8 +1263,24 @@ public class JavaParser {
* The parse state.
*/
class ParseState {
/**
* The parse index.
*/
int index;
/**
* The token type
*/
int type;
/**
* The token text.
*/
String token;
/**
* The line number.
*/
int line;
}
\ No newline at end of file
......@@ -136,15 +136,25 @@ class ForStatement implements Statement {
Expr update;
Statement block;
ArrayList<Expr> updates = new ArrayList<Expr>();
Type iterableType;
String iterableVariable;
Expr iterable;
public String toString() {
StringBuffer buff = new StringBuffer();
buff.append("for (").append(init.toString());
buff.append(" ").append(condition.toString()).append("; ");
for (int i = 0; i < updates.size(); i++) {
if (i > 0) {
buff.append(", ");
buff.append("for (");
if (iterableType != null) {
buff.append(iterableType).append(' ');
buff.append(iterableVariable).append(": ");
buff.append(iterable);
} else {
buff.append(init.toString());
buff.append(" ").append(condition.toString()).append("; ");
for (int i = 0; i < updates.size(); i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(updates.get(i));
}
buff.append(updates.get(i));
}
buff.append(") {\n");
buff.append(block.toString()).append("}");
......@@ -192,11 +202,12 @@ class VarDecStatement implements Statement {
}
/**
* A variable.
* A native statement.
*/
class VariableExpr implements Expr {
public String name;
class StatementNative implements Statement {
String code;
public String toString() {
return name;
return code;
}
}
......@@ -27,17 +27,18 @@ public class Test extends TestBase {
public void test() throws IOException {
// not supported yet:
// annotations
// HexadecimalFloatingPointLiteral
// int x()[] { return null; }
// annotations
// import static
// import *
// only public or default level classes
// 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)
// assert
// array declaration at weird places: int x() [] { return null; }
assertEquals("\\\\" + "u0000", JavaParser.replaceUnicode("\\\\" + "u0000"));
assertEquals("\u0000", JavaParser.replaceUnicode("\\" + "u0000"));
......@@ -54,14 +55,19 @@ public class Test extends TestBase {
assertEquals(".3d", JavaParser.readNumber(".3dx"));
assertEquals("6.022137e+23f", JavaParser.readNumber("6.022137e+23f+1"));
JavaParser parser = new JavaParser("src/tools", "org.h2.java.TestApp");
parser.parse();
JavaParser parser = new JavaParser();
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");
parser.parse("src/tools", "org.h2.java.TestApp");
PrintWriter w = new PrintWriter(System.out);
parser.writeC(w);
parser.writeHeader(w);
parser.writeSource(w);
w.flush();
w = new PrintWriter(new FileWriter("bin/test.c"));
parser.writeC(w);
parser.writeHeader(w);
parser.writeSource(w);
w.close();
}
......
......@@ -9,11 +9,18 @@ package org.h2.java;
/**
* A test application.
*/
/// #include <stdio.h>
public class TestApp {
private static final int FINAL_VALUE = 10;
// private static final int FINAL_VALUE = 10;
/**
* Run this application.
*
* @param args the command line arguments
*/
public static void main(String... args) {
// c:printf("Hello\n");
System.out.println("Hello World");
}
......@@ -27,7 +34,7 @@ public class TestApp {
public int getName(int name, int x) {
System.out.println("Hello");
int m = x;
m = FINAL_VALUE;
// m = FINAL_VALUE;
switch (x) {
case 1:
m = 3;
......
package org.h2.java.io;
import org.h2.java.lang.System;
/**
* A print stream.
*/
public class PrintStream {
/**
* Print the given string.
*
* @param s the string
*/
public void println(String s) {
System.arraycopy(null, 0, null, 0, 1);
// c: printf("%s\n");
}
}
package org.h2.java.lang;
/**
* A java.lang.Object implementation.
*/
public class Object {
public int hashCode() {
return 0;
}
public boolean equals(Object other) {
return this == other;
}
}
package org.h2.java.lang;
/**
* A java.lang.String implementation.
*/
public class String {
private char[] chars;
private int hashCode;
public String(char[] chars) {
this.chars = new char[chars.length];
System.arraycopy(chars, 0, this.chars, 0, chars.length);
}
public int hashCode() {
if (hashCode == 0) {
if (chars.length == 0) {
return 0;
}
int h = 0;
for (char c : chars) {
h = h * 31 + c;
}
hashCode = h;
return h;
}
return hashCode;
}
/**
* Get the length of the string.
*
* @return the length
*/
public int length() {
return chars.length;
}
}
package org.h2.java.lang;
import java.io.PrintStream;
/**
* A simple java.lang.System implementation.
*/
public class System {
// c: #include <stdio>
/**
* The stdout stream.
*/
public static PrintStream out;
/**
* Copy data from the source to the target.
* Source and target may overlap.
*
* @param src the source array
* @param srcPos the first element in the source array
* @param dest the destination
* @param destPos the first element in the destination
* @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) {
// c: memmove(src + srcPos, dest + destPos, length);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论