From b3e13d09b924d169491d1f7cf2f6ac505a2187c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Wed, 27 Apr 2016 15:08:17 +0200 Subject: [PATCH] =?UTF-8?q?-=20Alle=20Operatoren=20implementiert=20-=20Tes?= =?UTF-8?q?ts=20f=C3=BCr=20Sub,=20Mul,=20Div?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../syntaxtree/operator/AddOp.java | 52 +++++++++++++++++- .../syntaxtree/operator/DivideOp.java | 10 ++-- .../syntaxtree/operator/EqualOp.java | 32 +---------- .../syntaxtree/operator/GreaterEquOp.java | 8 +++ .../syntaxtree/operator/GreaterOp.java | 8 +++ .../syntaxtree/operator/LessEquOp.java | 8 +++ .../syntaxtree/operator/LessOp.java | 7 +++ .../syntaxtree/operator/MinusOp.java | 8 ++- .../syntaxtree/operator/ModuloOp.java | 8 +++ .../syntaxtree/operator/MulOp.java | 53 ++++++++++++++++++- .../syntaxtree/operator/NotEqualOp.java | 17 +++--- .../syntaxtree/operator/Operator.java | 9 ++++ .../syntaxtree/operator/PlusOp.java | 49 +---------------- .../syntaxtree/operator/RelOp.java | 51 +++++++++++++++++- .../syntaxtree/operator/TimesOp.java | 8 +++ test/bytecode/operators/DivOperator.jav | 5 ++ test/bytecode/operators/DivOperatorTest.java | 53 +++++++++++++++++++ test/bytecode/operators/MulOperator.jav | 5 ++ test/bytecode/operators/MulOperatorTest.java | 53 +++++++++++++++++++ test/bytecode/operators/SubOperator.jav | 5 ++ test/bytecode/operators/SubOperatorTest.java | 53 +++++++++++++++++++ 21 files changed, 408 insertions(+), 94 deletions(-) create mode 100644 test/bytecode/operators/DivOperator.jav create mode 100644 test/bytecode/operators/DivOperatorTest.java create mode 100644 test/bytecode/operators/MulOperator.jav create mode 100644 test/bytecode/operators/MulOperatorTest.java create mode 100644 test/bytecode/operators/SubOperator.jav create mode 100644 test/bytecode/operators/SubOperatorTest.java diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/AddOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/AddOp.java index c9e95ee3..ac4ac40a 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/AddOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/AddOp.java @@ -5,8 +5,17 @@ package de.dhbwstuttgart.syntaxtree.operator; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.IADD; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.InvokeInstruction; +import org.apache.commons.bcel6.generic.ObjectType; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; @@ -16,8 +25,10 @@ import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.SingleConstraint; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.DebugException; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.Unify; @@ -62,5 +73,44 @@ public abstract class AddOp extends Operator return ret; } + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + // TODO Plus Operator ist bis jetzt nur für Integer implementiert + /* + 0: aload_1 + 1: invokevirtual #2 // Method java/lang/Integer.intValue:()I + 4: aload_1 + 5: invokevirtual #2 // Method java/lang/Integer.intValue:()I + 8: iadd + 9: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; + 12: areturn + */ + DHBWInstructionFactory _factory = _cg.getInstructionFactory(); + + String returnType = getReturnType(operator.get_Expr1(), operator.get_Expr2()); + + InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), returnType); + + il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), returnType)); + + il.append(getOperator(returnType)); + + il.append(convertValueToObject(_factory, returnType)); + return il; + } + + private String getReturnType(Expr expr1, Expr expr2) { + return "java.lang.Integer"; + } + + abstract ArithmeticInstruction getOperator(String returnType); + + private InvokeInstruction convertValueToObject(DHBWInstructionFactory _factory, String returnType) { + if(returnType.equals("java.lang.Integer")){ + return _factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.INT}, Constants.INVOKESTATIC); + }else{ + throw new NotImplementedException(); + } + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/DivideOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/DivideOp.java index 4442e7a9..850d2ba0 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/DivideOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/DivideOp.java @@ -4,6 +4,9 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.DivideOp.8596.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.IDIV; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.statement.Binary; @@ -26,8 +29,9 @@ public class DivideOp extends MulOp } // ino.end - - - + @Override + ArithmeticInstruction getOperator(String returnType) { + return new IDIV(); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java index 89285c6b..063be628 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java @@ -47,36 +47,8 @@ public class EqualOp extends RelOp // ino.end @Override - public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { - DHBWInstructionFactory _factory = _cg.getInstructionFactory(); - - InstructionList linkeSeite = operator.expr1.genByteCode(_cg, rs); - linkeSeite.append(_factory.createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); - - InstructionList rechteSeite = operator.expr2.genByteCode(_cg, rs); - rechteSeite.append(_factory.createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); - - - if(operator.getReturnType().getName().equals(new JavaClassName("String"))){ - throw new TypeinferenceException("Zeichenketten zusammenfügen ist noch nicht unterstützt",this); - } - - linkeSeite.append(rechteSeite); - - //TODO: bytecode (Bis jetzt wird jeder Condition als EQUALS behandelt) - //TODO: bytecode autoboxing - - BranchInstruction if_icmpneInstruction = new IF_ICMPNE(null); - linkeSeite.append(if_icmpneInstruction); - linkeSeite.append(InstructionConstants.ICONST_1); - - BranchInstruction gotoInstruction = new GOTO(null); - - linkeSeite.append(gotoInstruction); - if_icmpneInstruction.setTarget(linkeSeite.append(InstructionConstants.ICONST_0)); - gotoInstruction.setTarget(linkeSeite.append(_factory.createInvoke("java.lang.Boolean", "valueOf", new ObjectType("java.lang.Boolean"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.BOOLEAN}, Constants.INVOKESTATIC))); - - return linkeSeite; + BranchInstruction getOperator() { + return new IF_ICMPNE(null); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/GreaterEquOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/GreaterEquOp.java index a01e1285..588c2271 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/GreaterEquOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/GreaterEquOp.java @@ -4,6 +4,9 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.GreaterEquOp.8598.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.IF_ICMPLT; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.statement.Binary; @@ -25,6 +28,11 @@ public class GreaterEquOp extends RelOp super(offset,variableLength); } // ino.end + + @Override + BranchInstruction getOperator() { + return new IF_ICMPLT(null); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/GreaterOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/GreaterOp.java index 97a66824..f6b037db 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/GreaterOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/GreaterOp.java @@ -4,6 +4,9 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.GreaterOp.8599.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.IF_ICMPLE; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; @@ -25,5 +28,10 @@ public class GreaterOp extends RelOp } // ino.end + @Override + BranchInstruction getOperator() { + return new IF_ICMPLE(null); + } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/LessEquOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/LessEquOp.java index cff4e504..7a60fa49 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/LessEquOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/LessEquOp.java @@ -4,6 +4,9 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.LessEquOp.8600.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.IF_ICMPGT; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; @@ -25,5 +28,10 @@ public class LessEquOp extends RelOp } // ino.end + @Override + BranchInstruction getOperator() { + return new IF_ICMPGT(null); + } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/LessOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/LessOp.java index 2fcc7f11..5b6722b3 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/LessOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/LessOp.java @@ -3,6 +3,8 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.end // ino.module.LessOp.8601.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.IF_ICMPGE; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; @@ -25,5 +27,10 @@ public class LessOp extends RelOp } // ino.end + @Override + BranchInstruction getOperator() { + return new IF_ICMPGE(null); + } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/MinusOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/MinusOp.java index 3cd233ad..72313dd6 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/MinusOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/MinusOp.java @@ -4,6 +4,10 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.MinusOp.8603.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.IADD; +import org.apache.commons.bcel6.generic.ISUB; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; @@ -25,6 +29,8 @@ public class MinusOp extends AddOp } // ino.end - + ArithmeticInstruction getOperator(String returnType) { + return new ISUB(); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/ModuloOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/ModuloOp.java index 57465f01..d387958e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/ModuloOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/ModuloOp.java @@ -4,6 +4,9 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.ModuloOp.8604.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.IREM; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; @@ -25,5 +28,10 @@ public class ModuloOp extends MulOp } // ino.end + @Override + ArithmeticInstruction getOperator(String returnType) { + return new IREM(); + } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/MulOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/MulOp.java index d031b647..aa1c3b4e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/MulOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/MulOp.java @@ -6,15 +6,26 @@ package de.dhbwstuttgart.syntaxtree.operator; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.InvokeInstruction; +import org.apache.commons.bcel6.generic.ObjectType; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.syntaxtree.statement.Binary; +import de.dhbwstuttgart.syntaxtree.statement.Expr; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.typeinference.Pair; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.DebugException; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.unify.Unify; // ino.class.MulOp.24231.declaration @@ -50,6 +61,44 @@ public abstract class MulOp extends Operator return ret; } - + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + // TODO Plus Operator ist bis jetzt nur für Integer implementiert + /* + 0: aload_1 + 1: invokevirtual #2 // Method java/lang/Integer.intValue:()I + 4: aload_1 + 5: invokevirtual #2 // Method java/lang/Integer.intValue:()I + 8: imul + 9: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; + 12: areturn + */ + DHBWInstructionFactory _factory = _cg.getInstructionFactory(); + + String returnType = getReturnType(operator.get_Expr1(), operator.get_Expr2()); + + InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), returnType); + + il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), returnType)); + + il.append(getOperator(returnType)); + + il.append(convertValueToObject(_factory, returnType)); + return il; + } + + private String getReturnType(Expr expr1, Expr expr2) { + return "java.lang.Integer"; + } + + abstract ArithmeticInstruction getOperator(String returnType); + + private InvokeInstruction convertValueToObject(DHBWInstructionFactory _factory, String returnType) { + if(returnType.equals("java.lang.Integer")){ + return _factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.INT}, Constants.INVOKESTATIC); + }else{ + throw new NotImplementedException(); + } + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/NotEqualOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/NotEqualOp.java index 7cbe3936..0087c9ed 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/NotEqualOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/NotEqualOp.java @@ -3,16 +3,10 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.end // ino.module.NotEqualOp.8606.import import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; -import de.dhbwstuttgart.myexception.CTypeReconstructionException; -import de.dhbwstuttgart.myexception.JVMCodeException; -import de.dhbwstuttgart.syntaxtree.statement.Binary; -import de.dhbwstuttgart.syntaxtree.statement.Expr; -import de.dhbwstuttgart.syntaxtree.statement.Null; -import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.typeinference.Pair; -import de.dhbwstuttgart.typeinference.unify.Unify; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.IF_ACMPEQ; + // ino.class.NotEqualOp.24241.declaration public class NotEqualOp extends RelOp @@ -28,5 +22,10 @@ public class NotEqualOp extends RelOp } // ino.end + @Override + BranchInstruction getOperator() { + return new IF_ACMPEQ(null); + } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java b/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java index 4a2573ba..25267dc1 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; +import org.apache.commons.bcel6.Constants; import org.apache.commons.bcel6.generic.InstructionList; import de.dhbwstuttgart.typeinference.Menge; @@ -97,5 +98,13 @@ public abstract class Operator extends SyntaxTreeNode public Menge getChildren() { return new Menge<>(); } + + + protected InstructionList getInstructionListForOperand(ClassGenerator _cg, TypeinferenceResultSet rs, Expr operand, String returnType){ + InstructionList il = new InstructionList(); + il.append(operand.genByteCode(_cg, rs)); + il.append(_cg.getInstructionFactory().createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); + return il; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java index 2c2c44aa..cff0e150 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java @@ -41,54 +41,9 @@ public class PlusOp extends AddOp super(offset,variableLength); } // ino.end - - @Override - public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { - // TODO Plus Operator ist bis jetzt nur für Integer implementiert - /* - 0: aload_1 - 1: invokevirtual #2 // Method java/lang/Integer.intValue:()I - 4: aload_1 - 5: invokevirtual #2 // Method java/lang/Integer.intValue:()I - 8: iadd - 9: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; - 12: areturn - */ - DHBWInstructionFactory _factory = _cg.getInstructionFactory(); - - String returnType = getReturnType(operator.get_Expr1(), operator.get_Expr2()); - - InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), returnType); - - il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), returnType)); - - il.append(getOperator(returnType)); - - il.append(convertValueToObject(_factory, returnType)); - return il; - } - - private String getReturnType(Expr expr1, Expr expr2) { - return "java.lang.Integer"; - } - - private ArithmeticInstruction getOperator(String returnType) { + + ArithmeticInstruction getOperator(String returnType) { return new IADD(); } - private InvokeInstruction convertValueToObject(DHBWInstructionFactory _factory, String returnType) { - if(returnType.equals("java.lang.Integer")){ - return _factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.INT}, Constants.INVOKESTATIC); - }else{ - throw new NotImplementedException(); - } - } - - private InstructionList getInstructionListForOperand(ClassGenerator _cg, TypeinferenceResultSet rs, Expr operand, String returnType){ - InstructionList il = new InstructionList(); - il.append(operand.genByteCode(_cg, rs)); - il.append(_cg.getInstructionFactory().createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); - return il; - } - } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/RelOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/RelOp.java index eb9178d7..3080ddf2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/RelOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/RelOp.java @@ -6,14 +6,24 @@ package de.dhbwstuttgart.syntaxtree.operator; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.GOTO; +import org.apache.commons.bcel6.generic.InstructionConstants; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.ObjectType; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.typeinference.Pair; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.DebugException; import de.dhbwstuttgart.typeinference.unify.Unify; @@ -54,6 +64,45 @@ public abstract class RelOp extends Operator return ret; } + + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + /* + 0: aload_1 + 1: invokevirtual #3 // Method java/lang/Integer.intValue:()I + 4: aload_2 + 5: invokevirtual #3 // Method java/lang/Integer.intValue:()I + 8: if_icmplt 15 + 11: iconst_1 + 12: goto 16 + 15: iconst_0 + 16: invokestatic #2 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean; + 19: areturn + */ + + DHBWInstructionFactory _factory = _cg.getInstructionFactory(); + + InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), "java.lang.Boolean"); + + il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), "java.lang.Boolean")); + + BranchInstruction operatorBranchInstruction = getOperator(); + + il.append(operatorBranchInstruction); + + il.append(InstructionConstants.ICONST_1); + + BranchInstruction gotoInstruction = new GOTO(null); + + il.append(gotoInstruction); + + operatorBranchInstruction.setTarget(il.append(InstructionConstants.ICONST_0)); + gotoInstruction.setTarget(il.append(_factory.createInvoke("java.lang.Boolean", "valueOf", new ObjectType("java.lang.Boolean"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.BOOLEAN}, Constants.INVOKESTATIC))); + + return il; + } + + abstract BranchInstruction getOperator(); } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/TimesOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/TimesOp.java index 6f47068d..c43ff29c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/TimesOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/TimesOp.java @@ -5,6 +5,9 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.module.TimesOp.8611.import import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.IMUL; + import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; @@ -23,5 +26,10 @@ public class TimesOp extends MulOp } // ino.end + @Override + ArithmeticInstruction getOperator(String returnType) { + return new IMUL(); + } + } // ino.end diff --git a/test/bytecode/operators/DivOperator.jav b/test/bytecode/operators/DivOperator.jav new file mode 100644 index 00000000..6ba3d4fe --- /dev/null +++ b/test/bytecode/operators/DivOperator.jav @@ -0,0 +1,5 @@ +class DivOperator{ + Integer method(Integer x, Integer y){ + return x / y; + } +} \ No newline at end of file diff --git a/test/bytecode/operators/DivOperatorTest.java b/test/bytecode/operators/DivOperatorTest.java new file mode 100644 index 00000000..6b7db4e0 --- /dev/null +++ b/test/bytecode/operators/DivOperatorTest.java @@ -0,0 +1,53 @@ +package bytecode.operators; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Ignore; +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class DivOperatorTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "DivOperator"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/operators/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } + + @Test + public void testTwoIntegers() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer x = new Integer(1); + Integer y = new Integer(2); + + Class[] params = new Class[]{ + x.getClass(), + y.getClass(), + }; + + Method method = cls.getDeclaredMethod("method", params); + Integer returnValue = (Integer) method.invoke(obj, x, y); + assertEquals(new Integer(0), returnValue); + } +} diff --git a/test/bytecode/operators/MulOperator.jav b/test/bytecode/operators/MulOperator.jav new file mode 100644 index 00000000..dd08e82e --- /dev/null +++ b/test/bytecode/operators/MulOperator.jav @@ -0,0 +1,5 @@ +class MulOperator{ + Integer method(Integer x, Integer y){ + return x * y; + } +} \ No newline at end of file diff --git a/test/bytecode/operators/MulOperatorTest.java b/test/bytecode/operators/MulOperatorTest.java new file mode 100644 index 00000000..2c663021 --- /dev/null +++ b/test/bytecode/operators/MulOperatorTest.java @@ -0,0 +1,53 @@ +package bytecode.operators; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Ignore; +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class MulOperatorTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "MulOperator"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/operators/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } + + @Test + public void testTwoIntegers() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer x = new Integer(1); + Integer y = new Integer(2); + + Class[] params = new Class[]{ + x.getClass(), + y.getClass(), + }; + + Method method = cls.getDeclaredMethod("method", params); + Integer returnValue = (Integer) method.invoke(obj, x, y); + assertEquals(new Integer(2), returnValue); + } +} diff --git a/test/bytecode/operators/SubOperator.jav b/test/bytecode/operators/SubOperator.jav new file mode 100644 index 00000000..1c591522 --- /dev/null +++ b/test/bytecode/operators/SubOperator.jav @@ -0,0 +1,5 @@ +class SubOperator{ + Integer method(Integer x, Integer y){ + return x - y; + } +} \ No newline at end of file diff --git a/test/bytecode/operators/SubOperatorTest.java b/test/bytecode/operators/SubOperatorTest.java new file mode 100644 index 00000000..a9b3294f --- /dev/null +++ b/test/bytecode/operators/SubOperatorTest.java @@ -0,0 +1,53 @@ +package bytecode.operators; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Ignore; +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class SubOperatorTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "SubOperator"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/operators/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } + + @Test + public void testTwoIntegers() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer x = new Integer(1); + Integer y = new Integer(2); + + Class[] params = new Class[]{ + x.getClass(), + y.getClass(), + }; + + Method method = cls.getDeclaredMethod("method", params); + Integer returnValue = (Integer) method.invoke(obj, x, y); + assertEquals(new Integer(-1), returnValue); + } +}