And, Or, Plus Operator implementiert

This commit is contained in:
Enrico Schrödter 2016-04-14 12:00:15 +02:00
parent dfe79a8030
commit 9a07201498
6 changed files with 169 additions and 6 deletions

View File

@ -3,11 +3,16 @@ package de.dhbwstuttgart.syntaxtree.operator;
import de.dhbwstuttgart.typeinference.Menge;
import org.apache.commons.bcel6.generic.InstructionList;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.SingleConstraint;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
// ino.class.AndOp.24101.declaration
@ -25,6 +30,12 @@ public class AndOp extends LogOp
}
// ino.end
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
// TODO Auto-generated method stub
return null;
}
}
// ino.end

View File

@ -2,6 +2,19 @@
package de.dhbwstuttgart.syntaxtree.operator;
// ino.end
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.IFEQ;
import org.apache.commons.bcel6.generic.IFNE;
import org.apache.commons.bcel6.generic.InstructionConstants;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.ObjectType;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
// ino.class.OrOp.24282.declaration
public class OrOp extends LogOp
@ -17,6 +30,47 @@ public class OrOp extends LogOp
super(offset,variableLength);
}
// ino.end
@Override
public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) {
/*
0: aload_1
1: invokevirtual #2 // Method java/lang/Boolean.booleanValue:()Z
4: ifne 14
7: aload_2
8: invokevirtual #2 // Method java/lang/Boolean.booleanValue:()Z
11: ifeq 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokestatic #3 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
22: areturn
*/
DHBWInstructionFactory _factory = _cg.getInstructionFactory();
InstructionList il = operator.get_Expr1().genByteCode(_cg, rs);
il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.commons.bcel6.generic.Type.BOOLEAN, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL));
BranchInstruction firstTest = new IFNE(null);
il.append(firstTest);
il.append(operator.get_Expr2().genByteCode(_cg, rs));
il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.commons.bcel6.generic.Type.BOOLEAN, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL));
BranchInstruction secondTest = new IFEQ(null);
il.append(secondTest);
firstTest.setTarget(il.append(InstructionConstants.ICONST_1));
BranchInstruction gotoInstruction = new GOTO(null);
il.append(gotoInstruction);
secondTest.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;
}
}
// ino.end

View File

@ -3,10 +3,27 @@ package de.dhbwstuttgart.syntaxtree.operator;
// ino.end
// ino.module.PlusOp.8609.import
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import org.apache.commons.bcel6.Constants;
import org.apache.commons.bcel6.generic.ArithmeticInstruction;
import org.apache.commons.bcel6.generic.BranchInstruction;
import org.apache.commons.bcel6.generic.GOTO;
import org.apache.commons.bcel6.generic.IADD;
import org.apache.commons.bcel6.generic.IFEQ;
import org.apache.commons.bcel6.generic.IFNE;
import org.apache.commons.bcel6.generic.InstructionConstants;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.InvokeInstruction;
import org.apache.commons.bcel6.generic.ObjectType;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.syntaxtree.statement.Binary;
import de.dhbwstuttgart.syntaxtree.statement.Expr;
import de.dhbwstuttgart.syntaxtree.type.Type;
@ -25,5 +42,53 @@ public class PlusOp extends AddOp
}
// 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) {
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

View File

@ -1,9 +1,5 @@
class AddOperator{
Integer method(Integer x){
return x + x;
}
Double method(Double x){
return x + x;
Integer method(Integer x, Integer y){
return x + y;
}
}

View File

@ -0,0 +1,32 @@
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 OROperatorTest extends SourceFileBytecodeTest{
@Override
protected void init() {
testName = "OrOperator";
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);
}
}

View File

@ -0,0 +1,5 @@
class OrOperator{
Boolean method(Boolean x, Boolean y){
return x || y;
}
}