From 52487f3389431512294c244a1982a1a9400ce75a Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 31 Jan 2018 16:47:08 +0100 Subject: [PATCH 1/7] test LamAssign --- test/bytecode/LamAssign.jav | 1 - 1 file changed, 1 deletion(-) diff --git a/test/bytecode/LamAssign.jav b/test/bytecode/LamAssign.jav index 7fd5bc64..e522bd3b 100644 --- a/test/bytecode/LamAssign.jav +++ b/test/bytecode/LamAssign.jav @@ -1,4 +1,3 @@ - class LamAssign { m () { From a45aa5057452d8e888dbeb0adaa692a694084741 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 14 Feb 2018 14:37:36 +0100 Subject: [PATCH 2/7] =?UTF-8?q?erzeugt=20bytecode=20f=C3=BCr=20Zuweisung?= =?UTF-8?q?=20von=20Literale?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 4 +- .../bytecode/BytecodeGenMethod.java | 123 +++++++++++++++++- .../bytecode/signature/Signature.java | 2 +- test/bytecode/AssignToLit.jav | 30 +++++ test/bytecode/AssignToLitTest.java | 7 + test/bytecode/Example.jav | 6 +- test/bytecode/For.jav | 3 + test/bytecode/ForTest.java | 2 + test/bytecode/JavaTXCompilerTest.java | 2 +- test/bytecode/LamAssign.jav | 4 + 10 files changed, 176 insertions(+), 7 deletions(-) create mode 100644 test/bytecode/AssignToLit.jav create mode 100644 test/bytecode/AssignToLitTest.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 57aeecc3..f24bb3fd 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -55,6 +55,7 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(SourceFile sourceFile) { for(ClassOrInterface cl : sourceFile.getClasses()) { + System.out.println("in Class: " + cl.getClassName().toString()); BytecodeGen classGen = new BytecodeGen(classFiles, resultSet); cl.accept(classGen); classGen.writeClass(cl.getClassName().toString()); @@ -183,7 +184,8 @@ public class BytecodeGen implements ASTVisitor { System.out.println(sig); NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen); 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(); diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index c5480ac0..f04711e8 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -236,7 +236,7 @@ public class BytecodeGenMethod implements StatementVisitor{ cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL); - generateBCForFunN(lambdaExpression,typeErasure); +// generateBCForFunN(lambdaExpression,typeErasure); } private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) { @@ -435,7 +435,126 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Literal literal) { - mv.visitLdcInsn(getResolvedType(literal.getType())); + System.out.println(resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor())); + Object value = literal.value; + switch (resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor())) { + case "java/lang/String": + mv.visitLdcInsn((String) 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 visitCharLiteral(Character value) { + mv.visitIntInsn(Opcodes.BIPUSH, Character.getNumericValue(value.charValue())); + 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<-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<-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<-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 diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index fc9e2191..cc4a6a13 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -134,7 +134,7 @@ public class Signature { RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType; sv.visitInterface().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; default: if(!isParameterType) diff --git a/test/bytecode/AssignToLit.jav b/test/bytecode/AssignToLit.jav new file mode 100644 index 00000000..4691a5da --- /dev/null +++ b/test/bytecode/AssignToLit.jav @@ -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 = "String"; + 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'; + } +} \ No newline at end of file diff --git a/test/bytecode/AssignToLitTest.java b/test/bytecode/AssignToLitTest.java new file mode 100644 index 00000000..dc5d397b --- /dev/null +++ b/test/bytecode/AssignToLitTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class AssignToLitTest extends JavaTXCompilerTest { + public AssignToLitTest() { + this.fileName = "AssignToLit"; + } +} diff --git a/test/bytecode/Example.jav b/test/bytecode/Example.jav index 8fc7a0a7..b7455a3f 100644 --- a/test/bytecode/Example.jav +++ b/test/bytecode/Example.jav @@ -1,7 +1,9 @@ +import java.lang.String; + public class Example { - public m(Integer x) { -// String x = "X"; + public m() { + String x = "X"; return x; } } \ No newline at end of file diff --git a/test/bytecode/For.jav b/test/bytecode/For.jav index c93b34c4..e14c62f8 100644 --- a/test/bytecode/For.jav +++ b/test/bytecode/For.jav @@ -1,3 +1,6 @@ +import java.lang.Integer; +import java.lang.Boolean; + class For{ m(Integer x){ Boolean b = true; diff --git a/test/bytecode/ForTest.java b/test/bytecode/ForTest.java index 7df68665..c95138d3 100644 --- a/test/bytecode/ForTest.java +++ b/test/bytecode/ForTest.java @@ -1,5 +1,7 @@ package bytecode; +import org.objectweb.asm.Opcodes; + public class ForTest extends JavaTXCompilerTest { public ForTest() { diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 2f832962..623fc96e 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -67,7 +67,7 @@ public class JavaTXCompilerTest { byte[] bytecode = classFiles.get(name); try { 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.close(); System.out.println(name+".class file generated"); diff --git a/test/bytecode/LamAssign.jav b/test/bytecode/LamAssign.jav index 4a4f4f73..82bb31b1 100644 --- a/test/bytecode/LamAssign.jav +++ b/test/bytecode/LamAssign.jav @@ -9,3 +9,7 @@ class LamAssign { return lam1; } } + +interface Fun1{ + public A apply(B b); +} \ No newline at end of file From c747ab08850989bc52048df8ea78a820be7dd92f Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 21 Feb 2018 11:40:54 +0100 Subject: [PATCH 3/7] Additive Expression implementieren --- .../SyntaxTreeGenerator/StatementGenerator.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 1586ba3f..679b23df 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -599,8 +599,8 @@ public class StatementGenerator { } private BinaryExpr.Operator convertBinaryOperator(String operator) { - - return null; + //return BinaryExpr.Operator.ADD; + throw new NotImplementedException(); } private Expression convert(Java8Parser.ShiftExpressionContext expression) { @@ -612,12 +612,15 @@ public class StatementGenerator { } private Expression convert(Java8Parser.AdditiveExpressionContext expression) { - if(expression.additiveExpression() != null){ - return convert(expression.additiveExpression()); - }else if(expression.multiplicativeExpression() != null){ + + if(expression.additiveExpression() == null){ return convert(expression.multiplicativeExpression()); - }else{ - throw new NotImplementedException(); + }else { + 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); } } From 7c2f7c54ddfaaf23c6895551a43aba99129df63c Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 21 Feb 2018 11:44:03 +0100 Subject: [PATCH 4/7] =?UTF-8?q?Kleine=20=C3=84nderung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dhbwstuttgart/bytecode/BytecodeGenMethod.java | 3 +-- .../bytecode/signature/Signature.java | 3 ++- test/bytecode/AssignToLit.jav | 2 +- test/bytecode/Methods.jav | 14 ++++++++++++++ test/bytecode/MethodsTest.java | 7 +++++++ 5 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 test/bytecode/Methods.jav create mode 100644 test/bytecode/MethodsTest.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index f04711e8..402f578d 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -435,11 +435,10 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Literal literal) { - System.out.println(resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor())); Object value = literal.value; switch (resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor())) { case "java/lang/String": - mv.visitLdcInsn((String) value); + mv.visitLdcInsn(value); break; case "java/lang/Boolean": visitBooleanLiteral((Boolean) value); diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index cc4a6a13..f9bcb369 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -132,7 +132,8 @@ public class Signature { break; case "TPH": 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())); System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature())); break; diff --git a/test/bytecode/AssignToLit.jav b/test/bytecode/AssignToLit.jav index 4691a5da..46ec2b91 100644 --- a/test/bytecode/AssignToLit.jav +++ b/test/bytecode/AssignToLit.jav @@ -10,7 +10,7 @@ import java.lang.Character; class AssignToLit { void m(){ - String s = "String"; + String s = "Test"; Boolean b = false; Byte byte1 = 5; Byte byte2 = 55; diff --git a/test/bytecode/Methods.jav b/test/bytecode/Methods.jav new file mode 100644 index 00000000..3c46739d --- /dev/null +++ b/test/bytecode/Methods.jav @@ -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; + } +} \ No newline at end of file diff --git a/test/bytecode/MethodsTest.java b/test/bytecode/MethodsTest.java new file mode 100644 index 00000000..11195b71 --- /dev/null +++ b/test/bytecode/MethodsTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class MethodsTest extends JavaTXCompilerTest { + public MethodsTest() { + this.fileName = "Methods"; + } +} From ac4a79f0e76f22a73334538d3a328cd1767ee40e Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 21 Feb 2018 15:43:28 +0100 Subject: [PATCH 5/7] Additive/multiplicativeExpression und UnaryExpression implementiert --- .../bytecode/BytecodeGenMethod.java | 5 +- .../StatementGenerator.java | 47 +++++++++++++++---- test/bytecode/For.jav | 17 +++++++ test/parser/GeneralParserTest.java | 3 +- test/parser/OpratorTest.jav | 12 +++++ 5 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 test/parser/OpratorTest.jav diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index c5480ac0..b13a1fb6 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -167,6 +167,7 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(BinaryExpr binary) { System.out.println("\t++ In Binary: "); + System.out.println(binary.operation.toString()); } @@ -318,7 +319,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(IfStmt ifStmt) { - + System.out.println("If"); } @Override @@ -389,7 +390,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(UnaryExpr unaryExpr) { - throw new NotImplementedException(); + System.out.println(unaryExpr.operation.toString()); } @Override diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 679b23df..2b0b1a4f 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -7,6 +7,7 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; +import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; @@ -278,13 +279,14 @@ public class StatementGenerator { } private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) { - //TODO - throw new NotImplementedException(); + Expression argument = convert(stmt.unaryExpression()); + Token offset = stmt.getStart(); + return new UnaryExpr(UnaryExpr.Operation.PREINCREMENT, argument, TypePlaceholder.fresh(offset), offset); } - private Statement convert(Java8Parser.PreDecrementExpressionContext stmt) { - //TODO - throw new NotImplementedException(); + private Statement convert(Java8Parser.PreDecrementExpressionContext stmt) { + return new UnaryExpr(UnaryExpr.Operation.PREDECREMENT, convert(stmt.unaryExpression()), + TypePlaceholder.fresh(stmt.getStart()), stmt.getStart()); } private Statement convert(Java8Parser.PostIncrementExpressionContext stmt) { @@ -293,8 +295,8 @@ public class StatementGenerator { } private Statement convert(Java8Parser.PostDecrementExpressionContext stmt) { - //TODO - throw new NotImplementedException(); + return new UnaryExpr(UnaryExpr.Operation.POSTDECREMENT, convert(stmt.postfixExpression()), + TypePlaceholder.fresh(stmt.getStart()), stmt.getStart()); } private Statement convert(Java8Parser.AssignmentContext stmt) { @@ -600,7 +602,30 @@ public class StatementGenerator { private BinaryExpr.Operator convertBinaryOperator(String operator) { //return BinaryExpr.Operator.ADD; - throw new NotImplementedException(); + 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) { @@ -628,7 +653,11 @@ public class StatementGenerator { if(expression.multiplicativeExpression() == null){ return convert(expression.unaryExpression()); }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); } } diff --git a/test/bytecode/For.jav b/test/bytecode/For.jav index c93b34c4..04cb6a53 100644 --- a/test/bytecode/For.jav +++ b/test/bytecode/For.jav @@ -1,6 +1,15 @@ +import java.lang.Integer; +import java.lang.Boolean; + class For{ m(Integer x){ + Boolean b = true; + c = 5; + c++; + ++c; + c--; + --c; while(x<2){ x = x +1; b = false; @@ -10,4 +19,12 @@ class For{ // x = x + 5; // } } + +// m2(Integer x){ +// if(x<2) { +// return 1; +// }else { +// return 2; +// } +// } } \ No newline at end of file diff --git a/test/parser/GeneralParserTest.java b/test/parser/GeneralParserTest.java index c48e1320..b218347f 100644 --- a/test/parser/GeneralParserTest.java +++ b/test/parser/GeneralParserTest.java @@ -41,7 +41,8 @@ public class GeneralParserTest{ filenames.add("FieldVarTest.jav"); filenames.add("StructuralTypes.jav"); */ - filenames.add("ExtendsTest.jav"); +// filenames.add("ExtendsTest.jav"); + filenames.add("OpratorTest.jav"); try{ new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList())); }catch(Exception exc){ diff --git a/test/parser/OpratorTest.jav b/test/parser/OpratorTest.jav new file mode 100644 index 00000000..f99734f6 --- /dev/null +++ b/test/parser/OpratorTest.jav @@ -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; + } +} \ No newline at end of file From 4fbcf87e0c23888c4e9ea9dd5a2701ac608d1241 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Fri, 23 Feb 2018 20:10:11 +0100 Subject: [PATCH 6/7] =?UTF-8?q?Methoden=20visit(assign)/visit(literal)=20a?= =?UTF-8?q?ngepasst=20und=20generiert=20bytecode=20f=C3=BCr=20Binaryexpres?= =?UTF-8?q?sions.=20noch=20nicht=20fertig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/BytecodeGenMethod.java | 145 +++++++++++++----- test/bytecode/AssignToLit.jav | 30 ++-- test/bytecode/For.jav | 26 ++-- test/bytecode/Op.jav | 12 ++ test/bytecode/OpTest.java | 7 + test/parser/OpratorTest.jav | 6 +- 6 files changed, 157 insertions(+), 69 deletions(-) create mode 100644 test/bytecode/Op.jav create mode 100644 test/bytecode/OpTest.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index b6a45bb1..df714015 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -43,30 +43,28 @@ public class BytecodeGenMethod implements StatementVisitor{ private MethodVisitor mv; private HashMap paramsAndLocals = new HashMap<>(); private String className; - private int lamCounter; + private int lamCounter = -1; private ClassWriter cw; private ResultSet resultSet; private boolean isInterface; HashMap genericsAndBoundsMethod; private HashMap genericsAndBounds; + private boolean isBinaryExp = false; //for tests ** private String fieldName; private String fieldDesc; private Expression rightSideTemp; -// private String where; private boolean isRightSideALambda = false; private KindOfLambda kindOfLambda; private HashMap classFiles; - private ArrayList varsFunInterface; + private ArrayList varsFunInterface = new ArrayList<>();; public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, HashMap genericsAndBounds, boolean isInterface, HashMap classFiles) { -// this.where = "<<<<<< NORMAL METHOD >>>>>>"; - this.className = className; this.resultSet = resultSet; this.m = m; @@ -77,9 +75,6 @@ public class BytecodeGenMethod implements StatementVisitor{ this.genericsAndBounds = genericsAndBounds; this.isInterface = isInterface; this.classFiles = classFiles; - this.lamCounter = -1; - - this.varsFunInterface = new ArrayList<>(); if(!isInterface) this.m.block.accept(this); @@ -89,13 +84,10 @@ public class BytecodeGenMethod implements StatementVisitor{ public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv, int indexOfFirstParamLam, boolean isInterface, HashMap classFiles) { -// this.where = "<<<<<< LAMBDA METHOD >>>>>>"; this.resultSet = resultSet; this.mv = mv; this.isInterface = isInterface; this.classFiles = classFiles; - this.lamCounter = -1; - this.varsFunInterface = new ArrayList<>(); Iterator itr = lambdaExpression.params.iterator(); int i = indexOfFirstParamLam; @@ -124,51 +116,61 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(SuperCall superCall) { superCall.receiver.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); } // ?? @Override public void visit(LocalVar localVar) { -// System.out.println("in Local Var: " + localVar.name); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); + if(isBinaryExp) { + getVlaue(getResolvedType(localVar.getType())); + } } // ?? @Override public void visit(LocalVarDecl localVarDecl) { -// Integer i; -// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1); -// System.out.println("In localVarDecl :: "+localVarDecl.getName()); + } @Override 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(assign.rightSide.getClass().equals(LambdaExpression.class)) { + if(assign.rightSide instanceof LambdaExpression) { isRightSideALambda = true; }else { 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 this.rightSideTemp = assign.rightSide; - assign.lefSide.accept(this); }else { assign.rightSide.accept(this); - assign.lefSide.accept(this); } + if(isBinaryExp) { + doAssign(getResolvedType(assign.lefSide.getType())); + isBinaryExp = false; + } + assign.lefSide.accept(this); } @Override - public void visit(BinaryExpr binary) { - System.out.println("\t++ In Binary: "); - System.out.println(binary.operation.toString()); + binary.lexpr.accept(this); + binary.rexpr.accept(this); + switch (binary.operation.toString()) { + case "ADD": + mv.visitInsn(Opcodes.IADD); + break; + default: + break; + } + } @Override @@ -330,12 +332,6 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override 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.arglist.accept(this); @@ -343,8 +339,6 @@ public class BytecodeGenMethod implements StatementVisitor{ genericsAndBoundsMethod,genericsAndBounds); String mDesc = method.accept(new DescriptorToString(resultSet)); -// System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); - // is methodCall.receiver functional Interface)? if(varsFunInterface.contains(methodCall.receiver.getType())) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), @@ -361,8 +355,6 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override 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.visitInsn(Opcodes.DUP); @@ -437,9 +429,53 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Literal literal) { Object value = literal.value; - switch (resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor())) { + 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": - mv.visitLdcInsn(value); + 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); @@ -479,8 +515,41 @@ public class BytecodeGenMethod implements StatementVisitor{ } } + 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, Character.getNumericValue(value.charValue())); + mv.visitIntInsn(Opcodes.BIPUSH, (int) value); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); } diff --git a/test/bytecode/AssignToLit.jav b/test/bytecode/AssignToLit.jav index 46ec2b91..873828ed 100644 --- a/test/bytecode/AssignToLit.jav +++ b/test/bytecode/AssignToLit.jav @@ -10,21 +10,21 @@ 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; +// 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'; } } \ No newline at end of file diff --git a/test/bytecode/For.jav b/test/bytecode/For.jav index 04cb6a53..c4bd6677 100644 --- a/test/bytecode/For.jav +++ b/test/bytecode/For.jav @@ -2,19 +2,19 @@ import java.lang.Integer; import java.lang.Boolean; class For{ - m(Integer x){ - - Boolean b = true; - c = 5; - c++; - ++c; - c--; - --c; - while(x<2){ - x = x +1; - b = false; - } - return x; + Integer m(Integer x){ + var c = x + 2; +// Boolean b = true; +// c = 5; +// c++; +// ++c; +// c--; +// --c; +// while(x<2){ +// x = x +1; +// b = false; +// } + return c; // for(int i = 0;i<10;i++) { // x = x + 5; // } diff --git a/test/bytecode/Op.jav b/test/bytecode/Op.jav new file mode 100644 index 00000000..9c05b0a2 --- /dev/null +++ b/test/bytecode/Op.jav @@ -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; + } +} \ No newline at end of file diff --git a/test/bytecode/OpTest.java b/test/bytecode/OpTest.java new file mode 100644 index 00000000..cd8fee06 --- /dev/null +++ b/test/bytecode/OpTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class OpTest extends JavaTXCompilerTest { + public OpTest() { + this.fileName = "Op"; + } +} diff --git a/test/parser/OpratorTest.jav b/test/parser/OpratorTest.jav index f99734f6..2764adf4 100644 --- a/test/parser/OpratorTest.jav +++ b/test/parser/OpratorTest.jav @@ -3,9 +3,9 @@ import java.lang.Integer; class OpratorTest { m(Integer a, Integer b) { c = a+b; - d = a-b; - e = a*b; - f = a/b; +// d = a-b; +// e = a*b; +// f = a/b; return c; } From 59569380ed60d0f5ea5da2363a4e417c3ac57455 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Fri, 23 Feb 2018 20:17:32 +0100 Subject: [PATCH 7/7] Kleiner Bug beseitigt --- .../parser/SyntaxTreeGenerator/StatementGenerator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 2b0b1a4f..5310d13b 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -825,7 +825,9 @@ public class StatementGenerator { }else if(literal.CharacterLiteral() != null){ RefType type = new RefType(reg.getName("java.lang.Character"),literal.getStart()); 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()); }else if(literal.StringLiteral()!=null){ RefType type = new RefType(reg.getName("java.lang.String"),literal.getStart());