Overloading funktioniert. Erzeugt Bytecode für Postincrement (für Integers).

This commit is contained in:
Fayez Abu Alia 2018-03-18 16:08:52 +01:00
parent dafcd2f125
commit 3233ccd845
7 changed files with 256 additions and 25 deletions

View File

@ -15,6 +15,7 @@ import java.util.Iterator;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator;
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Handle;
@ -180,9 +181,6 @@ public class BytecodeGenMethod implements StatementVisitor {
*/
@Override
public void visit(BinaryExpr binary) {
// if(!areTypesValid(binary)) {
// return;
// }
String lexpType = getResolvedType(binary.lexpr.getType());
String rexpType = getResolvedType(binary.rexpr.getType());
@ -190,10 +188,6 @@ public class BytecodeGenMethod implements StatementVisitor {
String largerType = getLargerType(lexpType,rexpType);
String typeOfBinary = getResolvedType(binary.getType());
// if(!(largerType.equals(typeOfBinary)&&typeOfBinary.equals(Type.getInternalName(Number.class))&&typeOfBinary.equals(Type.getInternalName(Object.class)))) {
// return;
// }
if (typeOfBinary.equals(Type.getInternalName(String.class))) {
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
mv.visitInsn(Opcodes.DUP);
@ -688,7 +682,43 @@ public class BytecodeGenMethod implements StatementVisitor {
@Override
public void visit(UnaryExpr unaryExpr) {
System.out.println(unaryExpr.operation.toString());
unaryExpr.expr.accept(this);
Operation op = unaryExpr.operation;
String typeOfUnary = getResolvedType(unaryExpr.getType());
switch (op) {
case POSTDECREMENT:
case POSTINCREMENT:
genBCForPostUnary(op, typeOfUnary);
break;
default:
break;
}
getValueOfIns(typeOfUnary);
if(unaryExpr.expr instanceof LocalVar) {
LocalVar local = (LocalVar) unaryExpr.expr;
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
}
}
private void genBCForPostUnary(Operation op, String typeOfUnary) {
if(isAssignStmt)
mv.visitInsn(Opcodes.DUP);
getVlaueIns(typeOfUnary);
doAssign(typeOfUnary, 1.0, true);
switch (op) {
case POSTDECREMENT:
throw new NotImplementedException();
case POSTINCREMENT:
doVisitAddOpInsn(typeOfUnary);
break;
default:
break;
}
}
@Override
@ -741,8 +771,8 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(Literal literal) {
Object value = literal.value;
String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
doAssign(typeOfLiteral, value);
// Name der Methode muss geändert werden
doAssign(typeOfLiteral, value, false);
}
@ -780,7 +810,7 @@ public class BytecodeGenMethod implements StatementVisitor {
}
}
private void doAssign(String type, Object value) {
private void doAssign(String type, Object value, boolean isOperator) {
switch (type) {
case "java/lang/String":
mv.visitLdcInsn(String.valueOf(value));
@ -790,24 +820,16 @@ public class BytecodeGenMethod implements StatementVisitor {
break;
case "java/lang/Byte":
visitByteLiteral(((Double) value).byteValue(), false);
if (!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Short":
visitShortLiteral(((Double) value).shortValue(), false);
if (!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Integer":
// zweite Argument isLong
visitIntegerLiteral(((Double) value).intValue(), false);
if (!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Long":
visitLongLiteral(((Double) value).longValue(), true);
if (!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Float":
visitFloatLiteral(((Double) value).floatValue());
@ -821,6 +843,12 @@ public class BytecodeGenMethod implements StatementVisitor {
default:
break;
}
if(!type.equals("java/lang/String")&&!type.equals("java/lang/Boolean")) {
if (!this.isBinaryExp && !isOperator)
getValueOfIns(type);
}
}
private void getValueOfIns(String type) {
@ -861,8 +889,7 @@ public class BytecodeGenMethod implements StatementVisitor {
private void visitCharLiteral(Character value) {
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
if (!this.isBinaryExp)
getValueOfIns(Type.getInternalName(Character.class));
}
private void visitDoubleLiteral(Double value) {
@ -873,8 +900,6 @@ public class BytecodeGenMethod implements StatementVisitor {
} else {
mv.visitLdcInsn(value);
}
if (!this.isBinaryExp)
getValueOfIns(Type.getInternalName(Double.class));
}
private void visitFloatLiteral(Float value) {
@ -884,8 +909,6 @@ public class BytecodeGenMethod implements StatementVisitor {
} else {
mv.visitLdcInsn(value);
}
if (!this.isBinaryExp)
getValueOfIns(Type.getInternalName(Float.class));
}
private void visitLongLiteral(Long value, boolean isLong) {

View File

@ -0,0 +1,40 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class MatrixTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Matrix.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("Matrix");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() {
fail("Not yet implemented");
}
}

View File

@ -0,0 +1,57 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class OverloadingTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
private static Class<?> classOL2;
private static Object instanceOfClassOL2;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Overloading.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("Overloading");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
classOL2 = loader.loadClass("Overloading2");
instanceOfClassOL2 = classOL2.getDeclaredConstructor().newInstance();
}
@Test
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method meth = classToTest.getDeclaredMethod("test", classToTest);
String res = (String) meth.invoke(instanceOfClass, instanceOfClass);
assertEquals("\"Overloading\"", res);
}
@Test
public void test2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method meth = classToTest.getDeclaredMethod("test", classOL2);
String res = (String) meth.invoke(instanceOfClass, instanceOfClassOL2);
assertEquals("\"Overloading2\"", res);
}
}

View File

@ -0,0 +1,51 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class PostIncTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PostInc.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode();
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("PostInc");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void testM1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m");
Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(1, res);
}
@Test
public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m2");
Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(0, res);
}
}

View File

@ -0,0 +1,27 @@
import java.util.Vector;
import java.lang.Integer;
import java.lang.Boolean;
class Matrix extends Vector<Vector<Integer>> {
mul(m) {
var ret = new Matrix();
var i = 0;
while(i < size()) {
var v1 = this.elementAt(i);
var v2 = new Vector<Integer>();
var j = 0;
while(j < v1.size()) {
var erg = 0;
var k = 0;
while(k < v1.size()) {
erg = erg + v1.elementAt(k)
* m.elementAt(k).elementAt(j);
k++; }
v2.addElement(new Integer(erg));
j++; }
ret.addElement(v2);
i++;
}
return ret;
}
}

View File

@ -0,0 +1,18 @@
import java.lang.String;
public class Overloading{
test(x){
return x.methode();
}
methode(){
return "Overloading";
}
}
public class Overloading2{
methode(){
return "Overloading2";
}
}

View File

@ -0,0 +1,15 @@
import java.lang.Integer;
public class PostInc {
m() {
var i = 0;
i++;
return i;
}
m2() {
var i = 0;
var j = i++;
return j;
}
}