forked from JavaTX/JavaCompilerCore
Merge branch 'parser' into bigRefactoring
This commit is contained in:
commit
b66d06a165
@ -55,6 +55,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(SourceFile sourceFile) {
|
public void visit(SourceFile sourceFile) {
|
||||||
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
||||||
|
System.out.println("in Class: " + cl.getClassName().toString());
|
||||||
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
|
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
|
||||||
cl.accept(classGen);
|
cl.accept(classGen);
|
||||||
classGen.writeClass(cl.getClassName().toString());
|
classGen.writeClass(cl.getClassName().toString());
|
||||||
@ -183,7 +184,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
System.out.println(sig);
|
System.out.println(sig);
|
||||||
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
||||||
methDesc = meth.accept(new DescriptorToString(resultSet));
|
methDesc = meth.accept(new DescriptorToString(resultSet));
|
||||||
MethodVisitor mv = cw.visitMethod(acc, method.getName(), methDesc, sig, null);
|
System.out.println(methDesc);
|
||||||
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
|
@ -43,30 +43,28 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
private MethodVisitor mv;
|
private MethodVisitor mv;
|
||||||
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||||
private String className;
|
private String className;
|
||||||
private int lamCounter;
|
private int lamCounter = -1;
|
||||||
private ClassWriter cw;
|
private ClassWriter cw;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
HashMap<String, String> genericsAndBoundsMethod;
|
HashMap<String, String> genericsAndBoundsMethod;
|
||||||
private HashMap<String,String> genericsAndBounds;
|
private HashMap<String,String> genericsAndBounds;
|
||||||
|
private boolean isBinaryExp = false;
|
||||||
|
|
||||||
//for tests **
|
//for tests **
|
||||||
private String fieldName;
|
private String fieldName;
|
||||||
private String fieldDesc;
|
private String fieldDesc;
|
||||||
private Expression rightSideTemp;
|
private Expression rightSideTemp;
|
||||||
// private String where;
|
|
||||||
private boolean isRightSideALambda = false;
|
private boolean isRightSideALambda = false;
|
||||||
private KindOfLambda kindOfLambda;
|
private KindOfLambda kindOfLambda;
|
||||||
private HashMap<String, byte[]> classFiles;
|
private HashMap<String, byte[]> classFiles;
|
||||||
|
|
||||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface;
|
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||||
|
|
||||||
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
|
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
||||||
HashMap<String,String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
HashMap<String,String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||||
|
|
||||||
// this.where = "<<<<<< NORMAL METHOD >>>>>>";
|
|
||||||
|
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.m = m;
|
this.m = m;
|
||||||
@ -77,9 +75,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.lamCounter = -1;
|
|
||||||
|
|
||||||
this.varsFunInterface = new ArrayList<>();
|
|
||||||
|
|
||||||
if(!isInterface)
|
if(!isInterface)
|
||||||
this.m.block.accept(this);
|
this.m.block.accept(this);
|
||||||
@ -89,13 +84,10 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
|
public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
|
||||||
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||||
|
|
||||||
// this.where = "<<<<<< LAMBDA METHOD >>>>>>";
|
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.lamCounter = -1;
|
|
||||||
this.varsFunInterface = new ArrayList<>();
|
|
||||||
|
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
int i = indexOfFirstParamLam;
|
int i = indexOfFirstParamLam;
|
||||||
@ -124,50 +116,61 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
superCall.receiver.accept(this);
|
superCall.receiver.accept(this);
|
||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false);
|
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface);
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
// System.out.println("in Local Var: " + localVar.name);
|
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
||||||
|
if(isBinaryExp) {
|
||||||
|
getVlaue(getResolvedType(localVar.getType()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
// Integer i;
|
|
||||||
// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1);
|
|
||||||
// System.out.println("In localVarDecl :: "+localVarDecl.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
// System.out.println("Assign : \nright = "+assign.rightSide + "\nLeft = " + assign.lefSide);
|
|
||||||
|
|
||||||
// if the right side is a lambda => the left side must be a functional interface
|
// if the right side is a lambda => the left side must be a functional interface
|
||||||
if(assign.rightSide.getClass().equals(LambdaExpression.class)) {
|
if(assign.rightSide instanceof LambdaExpression) {
|
||||||
isRightSideALambda = true;
|
isRightSideALambda = true;
|
||||||
}else {
|
}else {
|
||||||
isRightSideALambda = false;
|
isRightSideALambda = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(assign.lefSide.getClass().equals(AssignToField.class)) {
|
if(assign.rightSide instanceof BinaryExpr)
|
||||||
|
isBinaryExp = true;
|
||||||
|
|
||||||
|
if(assign.lefSide instanceof AssignToField) {
|
||||||
// load_0, ldc or .. then putfield
|
// load_0, ldc or .. then putfield
|
||||||
this.rightSideTemp = assign.rightSide;
|
this.rightSideTemp = assign.rightSide;
|
||||||
assign.lefSide.accept(this);
|
|
||||||
}else {
|
}else {
|
||||||
assign.rightSide.accept(this);
|
assign.rightSide.accept(this);
|
||||||
assign.lefSide.accept(this);
|
|
||||||
}
|
}
|
||||||
|
if(isBinaryExp) {
|
||||||
|
doAssign(getResolvedType(assign.lefSide.getType()));
|
||||||
|
isBinaryExp = false;
|
||||||
|
}
|
||||||
|
assign.lefSide.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
System.out.println("\t++ In Binary: ");
|
binary.lexpr.accept(this);
|
||||||
|
binary.rexpr.accept(this);
|
||||||
|
switch (binary.operation.toString()) {
|
||||||
|
case "ADD":
|
||||||
|
mv.visitInsn(Opcodes.IADD);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -236,7 +239,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||||
|
|
||||||
generateBCForFunN(lambdaExpression,typeErasure);
|
// generateBCForFunN(lambdaExpression,typeErasure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
||||||
@ -318,7 +321,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfStmt ifStmt) {
|
public void visit(IfStmt ifStmt) {
|
||||||
|
System.out.println("If");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -329,12 +332,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
// if(methodCall.receiver instanceof ExpressionReceiver){
|
|
||||||
// System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n");
|
|
||||||
// }else{
|
|
||||||
// System.out.print(((StaticClassName) methodCall.receiver).getType().toString() + "\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
|
|
||||||
@ -342,8 +339,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
genericsAndBoundsMethod,genericsAndBounds);
|
genericsAndBoundsMethod,genericsAndBounds);
|
||||||
String mDesc = method.accept(new DescriptorToString(resultSet));
|
String mDesc = method.accept(new DescriptorToString(resultSet));
|
||||||
|
|
||||||
// System.out.println("is Vars empty: "+varsFunInterface.isEmpty());
|
|
||||||
|
|
||||||
// is methodCall.receiver functional Interface)?
|
// is methodCall.receiver functional Interface)?
|
||||||
if(varsFunInterface.contains(methodCall.receiver.getType())) {
|
if(varsFunInterface.contains(methodCall.receiver.getType())) {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
||||||
@ -360,8 +355,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass methodCall) {
|
public void visit(NewClass methodCall) {
|
||||||
// System.out.println("In NewClass: ");
|
|
||||||
// System.out.println("\t\tname: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver);
|
|
||||||
|
|
||||||
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
|
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn(Opcodes.DUP);
|
||||||
@ -389,7 +382,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnaryExpr unaryExpr) {
|
public void visit(UnaryExpr unaryExpr) {
|
||||||
throw new NotImplementedException();
|
System.out.println(unaryExpr.operation.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -435,7 +428,202 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Literal literal) {
|
public void visit(Literal literal) {
|
||||||
mv.visitLdcInsn(getResolvedType(literal.getType()));
|
Object value = literal.value;
|
||||||
|
String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
if(this.isBinaryExp) {
|
||||||
|
getVlaue(typeOfLiteral);
|
||||||
|
}else {
|
||||||
|
doAssign(typeOfLiteral, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getVlaue(String typeOfLiteral) {
|
||||||
|
switch (typeOfLiteral) {
|
||||||
|
case "java/lang/String":
|
||||||
|
break;
|
||||||
|
case "java/lang/Boolean":
|
||||||
|
break;
|
||||||
|
case "java/lang/Byte":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
||||||
|
"(B)Ljava/lang/Byte;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Short":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
||||||
|
"(S)Ljava/lang/Short;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Integer":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
|
||||||
|
"()I", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
||||||
|
"(J)Ljava/lang/Long;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
break;
|
||||||
|
case "java/lang/Character":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAssign(String type, Object value) {
|
||||||
|
switch (type) {
|
||||||
|
case "java/lang/String":
|
||||||
|
mv.visitLdcInsn(String.valueOf(value));
|
||||||
|
break;
|
||||||
|
case "java/lang/Boolean":
|
||||||
|
visitBooleanLiteral((Boolean) value);
|
||||||
|
break;
|
||||||
|
case "java/lang/Byte":
|
||||||
|
visitByteLiteral(((Double) value).byteValue(),false);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
||||||
|
"(B)Ljava/lang/Byte;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Short":
|
||||||
|
visitShortLiteral(((Double) value).shortValue(),false);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
||||||
|
"(S)Ljava/lang/Short;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Integer":
|
||||||
|
//zweite Argument isLong
|
||||||
|
visitIntegerLiteral(((Double) value).intValue(), false);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
||||||
|
"(I)Ljava/lang/Integer;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Long":
|
||||||
|
visitLongLiteral(((Double) value).longValue(), true);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
||||||
|
"(J)Ljava/lang/Long;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
visitFloatLiteral(((Double) value).floatValue());
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
visitDoubleLiteral((Double) value);
|
||||||
|
break;
|
||||||
|
case "java/lang/Character":
|
||||||
|
visitCharLiteral((Character) value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAssign(String type) {
|
||||||
|
switch (type) {
|
||||||
|
case "java/lang/String":
|
||||||
|
break;
|
||||||
|
case "java/lang/Boolean":
|
||||||
|
break;
|
||||||
|
case "java/lang/Byte":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
||||||
|
"(B)Ljava/lang/Byte;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Short":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
||||||
|
"(S)Ljava/lang/Short;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Integer":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
||||||
|
"(I)Ljava/lang/Integer;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
||||||
|
"(J)Ljava/lang/Long;", false);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
break;
|
||||||
|
case "java/lang/Character":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitCharLiteral(Character value) {
|
||||||
|
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
|
||||||
|
"(C)Ljava/lang/Character;", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitDoubleLiteral(Double value) {
|
||||||
|
if(value == 0) {
|
||||||
|
mv.visitInsn(Opcodes.DCONST_0);
|
||||||
|
}else if(value == 1) {
|
||||||
|
mv.visitInsn(Opcodes.DCONST_1);
|
||||||
|
}else {
|
||||||
|
mv.visitLdcInsn(value);
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
|
||||||
|
"(D)Ljava/lang/Double;", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitFloatLiteral(Float value) {
|
||||||
|
if(value.intValue()>-1 && value.intValue() < 3) {
|
||||||
|
//Opcodes.FCONST_0 = 11, Opcodes.FCONST_1 = 12, usw
|
||||||
|
mv.visitInsn(value.intValue()+11);
|
||||||
|
}else {
|
||||||
|
mv.visitLdcInsn(value);
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
|
||||||
|
"(F)Ljava/lang/Float;", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitLongLiteral(Long value, boolean isLong) {
|
||||||
|
if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
||||||
|
visitShortLiteral(value.shortValue(),isLong);
|
||||||
|
}else {
|
||||||
|
mv.visitLdcInsn(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitShortLiteral(Short value,boolean isLong) {
|
||||||
|
if(value< 128 || (value>-129 && value<-1)) {
|
||||||
|
visitByteLiteral(value.byteValue(), isLong);
|
||||||
|
}else if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
||||||
|
mv.visitIntInsn(Opcodes.SIPUSH, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitByteLiteral(Byte value, boolean isLong) {
|
||||||
|
|
||||||
|
if(!isLong && value<6 && value>-1) {
|
||||||
|
//Opcodes.ICONST_0 = 3, Opcodes.ICONST_1 = 4, usw
|
||||||
|
mv.visitInsn(value+3);
|
||||||
|
}else if(isLong && value>-1 && value<2){
|
||||||
|
//Opcodes.LCONST_0 = 9, Opcodes.LCONST_1 = 10
|
||||||
|
mv.visitInsn(value+9);
|
||||||
|
}else {
|
||||||
|
mv.visitIntInsn(Opcodes.BIPUSH, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitIntegerLiteral(Integer value, boolean isLong) {
|
||||||
|
|
||||||
|
if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
||||||
|
visitShortLiteral(value.shortValue(),isLong);
|
||||||
|
}else {
|
||||||
|
mv.visitLdcInsn(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitBooleanLiteral(Boolean b) {
|
||||||
|
if(b) {
|
||||||
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
|
}else {
|
||||||
|
mv.visitInsn(Opcodes.ICONST_0);
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
|
||||||
|
"(Z)Ljava/lang/Boolean;", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -132,9 +132,10 @@ public class Signature {
|
|||||||
break;
|
break;
|
||||||
case "TPH":
|
case "TPH":
|
||||||
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
||||||
sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
|
if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH "))
|
||||||
|
sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
|
||||||
// sv.visitClassType(r.acceptTV(new TypeToSignature()));
|
// sv.visitClassType(r.acceptTV(new TypeToSignature()));
|
||||||
// System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(!isParameterType)
|
if(!isParameterType)
|
||||||
|
@ -7,6 +7,7 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
|||||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
@ -278,13 +279,14 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) {
|
private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) {
|
||||||
//TODO
|
Expression argument = convert(stmt.unaryExpression());
|
||||||
throw new NotImplementedException();
|
Token offset = stmt.getStart();
|
||||||
|
return new UnaryExpr(UnaryExpr.Operation.PREINCREMENT, argument, TypePlaceholder.fresh(offset), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java8Parser.PreDecrementExpressionContext stmt) {
|
private Statement convert(Java8Parser.PreDecrementExpressionContext stmt) {
|
||||||
//TODO
|
return new UnaryExpr(UnaryExpr.Operation.PREDECREMENT, convert(stmt.unaryExpression()),
|
||||||
throw new NotImplementedException();
|
TypePlaceholder.fresh(stmt.getStart()), stmt.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java8Parser.PostIncrementExpressionContext stmt) {
|
private Statement convert(Java8Parser.PostIncrementExpressionContext stmt) {
|
||||||
@ -293,8 +295,8 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java8Parser.PostDecrementExpressionContext stmt) {
|
private Statement convert(Java8Parser.PostDecrementExpressionContext stmt) {
|
||||||
//TODO
|
return new UnaryExpr(UnaryExpr.Operation.POSTDECREMENT, convert(stmt.postfixExpression()),
|
||||||
throw new NotImplementedException();
|
TypePlaceholder.fresh(stmt.getStart()), stmt.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java8Parser.AssignmentContext stmt) {
|
private Statement convert(Java8Parser.AssignmentContext stmt) {
|
||||||
@ -599,8 +601,31 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BinaryExpr.Operator convertBinaryOperator(String operator) {
|
private BinaryExpr.Operator convertBinaryOperator(String operator) {
|
||||||
|
//return BinaryExpr.Operator.ADD;
|
||||||
return null;
|
if(operator.equals("+")) {
|
||||||
|
return BinaryExpr.Operator.ADD;
|
||||||
|
}else if(operator.equals("-")) {
|
||||||
|
return BinaryExpr.Operator.SUB;
|
||||||
|
}else if(operator.equals("*")) {
|
||||||
|
return BinaryExpr.Operator.MUL;
|
||||||
|
}else if(operator.equals("&")) {
|
||||||
|
return BinaryExpr.Operator.AND;
|
||||||
|
}else if(operator.equals("|")) {
|
||||||
|
return BinaryExpr.Operator.OR;
|
||||||
|
}else if(operator.equals("/")) {
|
||||||
|
return BinaryExpr.Operator.DIV;
|
||||||
|
}else if(operator.equals("<")) {
|
||||||
|
return BinaryExpr.Operator.LESSTHAN;
|
||||||
|
}else if(operator.equals(">")) {
|
||||||
|
return BinaryExpr.Operator.BIGGERTHAN;
|
||||||
|
}else if(operator.equals(">=")) {
|
||||||
|
return BinaryExpr.Operator.BIGGEREQUAL;
|
||||||
|
} else if(operator.equals("<=")) {
|
||||||
|
return BinaryExpr.Operator.LESSEQUAL;
|
||||||
|
} else {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
// throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression convert(Java8Parser.ShiftExpressionContext expression) {
|
private Expression convert(Java8Parser.ShiftExpressionContext expression) {
|
||||||
@ -612,12 +637,15 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Expression convert(Java8Parser.AdditiveExpressionContext expression) {
|
private Expression convert(Java8Parser.AdditiveExpressionContext expression) {
|
||||||
if(expression.additiveExpression() != null){
|
|
||||||
return convert(expression.additiveExpression());
|
if(expression.additiveExpression() == null){
|
||||||
}else if(expression.multiplicativeExpression() != null){
|
|
||||||
return convert(expression.multiplicativeExpression());
|
return convert(expression.multiplicativeExpression());
|
||||||
}else{
|
}else {
|
||||||
throw new NotImplementedException();
|
Expression leftSide = convert(expression.additiveExpression());
|
||||||
|
Expression rightSide = convert(expression.multiplicativeExpression());
|
||||||
|
BinaryExpr.Operator op = convertBinaryOperator(expression.getChild(1).getText());
|
||||||
|
Token offset = expression.getStart();
|
||||||
|
return new BinaryExpr(op, TypePlaceholder.fresh(expression.getStart()), leftSide, rightSide, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -625,7 +653,11 @@ public class StatementGenerator {
|
|||||||
if(expression.multiplicativeExpression() == null){
|
if(expression.multiplicativeExpression() == null){
|
||||||
return convert(expression.unaryExpression());
|
return convert(expression.unaryExpression());
|
||||||
}else{
|
}else{
|
||||||
throw new NotImplementedException();
|
Expression leftSide = convert(expression.multiplicativeExpression());
|
||||||
|
Expression rightSide = convert(expression.unaryExpression());
|
||||||
|
BinaryExpr.Operator op = convertBinaryOperator(expression.getChild(1).getText());
|
||||||
|
Token offset = expression.getStart();
|
||||||
|
return new BinaryExpr(op, TypePlaceholder.fresh(offset), leftSide, rightSide, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,7 +825,9 @@ public class StatementGenerator {
|
|||||||
}else if(literal.CharacterLiteral() != null){
|
}else if(literal.CharacterLiteral() != null){
|
||||||
RefType type = new RefType(reg.getName("java.lang.Character"),literal.getStart());
|
RefType type = new RefType(reg.getName("java.lang.Character"),literal.getStart());
|
||||||
return new Literal(type,
|
return new Literal(type,
|
||||||
literal.CharacterLiteral().getText().charAt(0),
|
// das gibt immer ' zurück, der Char befindet sich in Position 1
|
||||||
|
//literal.CharacterLiteral().getText().charAt(0),
|
||||||
|
literal.CharacterLiteral().getText().charAt(1),
|
||||||
literal.getStart());
|
literal.getStart());
|
||||||
}else if(literal.StringLiteral()!=null){
|
}else if(literal.StringLiteral()!=null){
|
||||||
RefType type = new RefType(reg.getName("java.lang.String"),literal.getStart());
|
RefType type = new RefType(reg.getName("java.lang.String"),literal.getStart());
|
||||||
|
30
test/bytecode/AssignToLit.jav
Normal file
30
test/bytecode/AssignToLit.jav
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Byte;
|
||||||
|
import java.lang.Short;
|
||||||
|
import java.lang.Long;
|
||||||
|
import java.lang.Float;
|
||||||
|
import java.lang.Double;
|
||||||
|
import java.lang.Character;
|
||||||
|
|
||||||
|
class AssignToLit {
|
||||||
|
void m(){
|
||||||
|
// String s = "Test";
|
||||||
|
// Boolean b = false;
|
||||||
|
// Byte byte1 = 5;
|
||||||
|
// Byte byte2 = 55;
|
||||||
|
// Short short1 = 5;
|
||||||
|
// Short short2 = 55;
|
||||||
|
// Integer int1 = 5;
|
||||||
|
// Integer int2 = 8888888;
|
||||||
|
// Long long1 = 1;
|
||||||
|
// Long long2 = 5;
|
||||||
|
// Long long3 = 89989898;
|
||||||
|
// Float float1 = 1;
|
||||||
|
// Float float2 = 55;
|
||||||
|
// Double d1 = 1;
|
||||||
|
// Double d2 = 55;
|
||||||
|
Character c = 'A';
|
||||||
|
}
|
||||||
|
}
|
7
test/bytecode/AssignToLitTest.java
Normal file
7
test/bytecode/AssignToLitTest.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
public class AssignToLitTest extends JavaTXCompilerTest {
|
||||||
|
public AssignToLitTest() {
|
||||||
|
this.fileName = "AssignToLit";
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
|
import java.lang.String;
|
||||||
|
|
||||||
public class Example {
|
public class Example {
|
||||||
|
|
||||||
public m(Integer x) {
|
public m() {
|
||||||
// String x = "X";
|
String x = "X";
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,30 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
class For{
|
class For{
|
||||||
m(Integer x){
|
Integer m(Integer x){
|
||||||
Boolean b = true;
|
var c = x + 2;
|
||||||
while(x<2){
|
// Boolean b = true;
|
||||||
x = x +1;
|
// c = 5;
|
||||||
b = false;
|
// c++;
|
||||||
}
|
// ++c;
|
||||||
return x;
|
// c--;
|
||||||
|
// --c;
|
||||||
|
// while(x<2){
|
||||||
|
// x = x +1;
|
||||||
|
// b = false;
|
||||||
|
// }
|
||||||
|
return c;
|
||||||
// for(int i = 0;i<10;i++) {
|
// for(int i = 0;i<10;i++) {
|
||||||
// x = x + 5;
|
// x = x + 5;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m2(Integer x){
|
||||||
|
// if(x<2) {
|
||||||
|
// return 1;
|
||||||
|
// }else {
|
||||||
|
// return 2;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package bytecode;
|
package bytecode;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
public class ForTest extends JavaTXCompilerTest {
|
public class ForTest extends JavaTXCompilerTest {
|
||||||
|
|
||||||
public ForTest() {
|
public ForTest() {
|
||||||
|
@ -67,7 +67,7 @@ public class JavaTXCompilerTest {
|
|||||||
byte[] bytecode = classFiles.get(name);
|
byte[] bytecode = classFiles.get(name);
|
||||||
try {
|
try {
|
||||||
System.out.println("generating "+name+ ".class file ...");
|
System.out.println("generating "+name+ ".class file ...");
|
||||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class"));
|
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
||||||
output.write(bytecode);
|
output.write(bytecode);
|
||||||
output.close();
|
output.close();
|
||||||
System.out.println(name+".class file generated");
|
System.out.println(name+".class file generated");
|
||||||
|
@ -9,3 +9,7 @@ class LamAssign {
|
|||||||
return lam1;
|
return lam1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Fun1<A,B>{
|
||||||
|
public A apply(B b);
|
||||||
|
}
|
14
test/bytecode/Methods.jav
Normal file
14
test/bytecode/Methods.jav
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
class Methods {
|
||||||
|
|
||||||
|
m(a,b){
|
||||||
|
var c=a+b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
method2(x){
|
||||||
|
Integer i = this.m(x,2);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
7
test/bytecode/MethodsTest.java
Normal file
7
test/bytecode/MethodsTest.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
public class MethodsTest extends JavaTXCompilerTest {
|
||||||
|
public MethodsTest() {
|
||||||
|
this.fileName = "Methods";
|
||||||
|
}
|
||||||
|
}
|
12
test/bytecode/Op.jav
Normal file
12
test/bytecode/Op.jav
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
class Op {
|
||||||
|
m(Integer a, Integer b) {
|
||||||
|
Integer c = a+b;
|
||||||
|
// d = a-b;
|
||||||
|
// e = a*b;
|
||||||
|
// f = a/b;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
7
test/bytecode/OpTest.java
Normal file
7
test/bytecode/OpTest.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
public class OpTest extends JavaTXCompilerTest {
|
||||||
|
public OpTest() {
|
||||||
|
this.fileName = "Op";
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,8 @@ public class GeneralParserTest{
|
|||||||
filenames.add("FieldVarTest.jav");
|
filenames.add("FieldVarTest.jav");
|
||||||
filenames.add("StructuralTypes.jav");
|
filenames.add("StructuralTypes.jav");
|
||||||
*/
|
*/
|
||||||
filenames.add("ExtendsTest.jav");
|
// filenames.add("ExtendsTest.jav");
|
||||||
|
filenames.add("OpratorTest.jav");
|
||||||
try{
|
try{
|
||||||
new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList()));
|
new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList()));
|
||||||
}catch(Exception exc){
|
}catch(Exception exc){
|
||||||
|
12
test/parser/OpratorTest.jav
Normal file
12
test/parser/OpratorTest.jav
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
class OpratorTest {
|
||||||
|
m(Integer a, Integer b) {
|
||||||
|
c = a+b;
|
||||||
|
// d = a-b;
|
||||||
|
// e = a*b;
|
||||||
|
// f = a/b;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user