diff --git a/README.md b/README.md index 687a9c0..7ae61eb 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,6 @@ - Zugriff auf Felder nur über `this`-Referenz möglich - `print()`statt `System.out.println()` - keine Accessmodifier/alles ist public +- logische Statements MÜSSEN geklammert werden, ansonsten wird ununterbrochen von links nach rechts berechnet + (so würde z.B. (true || false == false) false zurückgeben) +- i++ und i-- sind nicht erlaubt, stattdessen i = i + 1 und i = i - 1 bzw i += 1 und i -= 1 diff --git a/src/test/java/testResources/CodeGen/BytecodeTestUtil.java b/src/test/java/testResources/CodeGen/BytecodeTestUtil.java index 7a63e81..987f5b2 100644 --- a/src/test/java/testResources/CodeGen/BytecodeTestUtil.java +++ b/src/test/java/testResources/CodeGen/BytecodeTestUtil.java @@ -81,7 +81,12 @@ public class BytecodeTestUtil { } public String getMethodReturnType(String methodName, Class... params) throws Exception { - return clazz.getMethod(methodName, params).getReturnType().getSimpleName(); + try { + return clazz.getMethod(methodName, params).getReturnType().getSimpleName(); + } catch (NoSuchMethodException | SecurityException e) { + LOGGER.log(Level.SEVERE, "Exception occur", e); + throw new RuntimeException(e); + } } public int getMethodParameterCount(String methodName, Class... params) throws Exception { diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_LogicExpr.java b/src/test/java/testResources/CodeGen/Features/ByteCode_LogicExpr.java index 26aae59..aa62e80 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_LogicExpr.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_LogicExpr.java @@ -60,21 +60,13 @@ public class ByteCode_LogicExpr { @Test public void testMethodReturnType() { try { - Assertions.assertEquals(1, util.getMethodParameterCount("testSmaller", new Class[]{int.class, int.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testSmaller", new Class[]{int.class, int.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testLarger", new Class[]{int.class, int.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testLarger", new Class[]{int.class, int.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testEqual", new Class[]{int.class, int.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testEqual", new Class[]{int.class, int.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testNotEqual", new Class[]{int.class, int.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testNotEqual", new Class[]{int.class, int.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testSmallerEqual", new Class[]{int.class, int.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testSmallerEqual", new Class[]{int.class, int.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testLargerEqual", new Class[]{int.class, int.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testLargerEqual", new Class[]{int.class, int.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testAND", new Class[]{boolean.class, boolean.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testAND", new Class[]{boolean.class, boolean.class})); - Assertions.assertEquals(1, util.getMethodParameterCount("testOR", new Class[]{boolean.class, boolean.class})); Assertions.assertEquals("boolean", util.getMethodReturnType("testOR", new Class[]{boolean.class, boolean.class})); } catch (Exception e) { Assertions.fail(); diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_Main.java b/src/test/java/testResources/CodeGen/Features/ByteCode_Main.java index 0951d47..d57651f 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_Main.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_Main.java @@ -1,7 +1,5 @@ package testResources.CodeGen.Features; -import de.maishai.typedast.Type; -import de.maishai.typedast.typedclass.*; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -10,9 +8,6 @@ import testResources.CodeGen.BytecodeTestUtil; import java.util.List; public class ByteCode_Main { - - //TODO: fix this test - private BytecodeTestUtil util; @BeforeEach diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_Overloaded.java b/src/test/java/testResources/CodeGen/Features/ByteCode_Overloaded.java index a679cdc..8b4a45d 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_Overloaded.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_Overloaded.java @@ -1,125 +1,127 @@ package testResources.CodeGen.Features; -import de.maishai.ast.Operator; -import de.maishai.typedast.Type; -import de.maishai.typedast.typedclass.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import testResources.CodeGen.BytecodeTestUtil; import java.util.List; public class ByteCode_Overloaded { - public static TypedProgram get() { - return new TypedProgram( - List.of( - new TypedClass( - "Overloaded", - List.of(), - List.of( - new TypedMethod( - "overloadedMethod", - Type.INT, - List.of(), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedIntLiteral( - 0, - Type.INT - ), - Type.INT - ) - ), - Type.INT - ) - ), - new TypedMethod( - "overloadedMethod", - Type.INT, - List.of( - new TypedParameter( - "x", - Type.INT - ) - ), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedFieldVarAccess( - false, - null, - "x", - Type.INT - ), - Type.INT - ) - ), - Type.INT - ) - ), - new TypedMethod( - "overloadedMethod", - Type.INT, - List.of( - new TypedParameter( - "x", - Type.INT - ), - new TypedParameter( - "y", - Type.INT - ) - ), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedBinary( - new TypedFieldVarAccess( - false, - null, - "x", - Type.INT - ), - Operator.ADD, - new TypedFieldVarAccess( - false, - null, - "y", - Type.INT - ), - Type.INT - ), - Type.INT - ) - ), - Type.INT - ) - ) - ), - List.of( - new TypedConstructor( - "Overloaded", - List.of(), - new TypedBlock( - List.of(), - List.of(), - Type.VOID - ), - Type.VOID, - List.of() - ) - ), - null, - null, - null, - Type.REFERENCE("Overloaded") - ) - ), - null - ); + + private BytecodeTestUtil util; + + @BeforeEach + public void setUp() { + try { + util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Overloaded.java"), "Overloaded"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testConstructorCount() { + Assertions.assertEquals(1, util.getConstructorCount()); + // default constructor + } + + @Test + public void testDefaultConstructor() { + Assertions.assertEquals("Overloaded", util.getConstructorNames().get(0)); + Assertions.assertEquals(0, util.getConstructorParameterCount(0)); + try { + Assertions.assertEquals("Overloaded", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testMethodCount() { + Assertions.assertEquals(3, util.getMethodCount()); + } + + @Test + public void testMethodNames() { + Assertions.assertTrue(util.getMethodNames().contains("overloadedMethod")); + } + + @Test + public void testMethodReturnType() { + try { + Assertions.assertEquals("int", util.getMethodReturnType("overloadedMethod", new Class[]{})); + Assertions.assertEquals("int", util.getMethodReturnType("overloadedMethod", new Class[]{int.class})); + Assertions.assertEquals("int", util.getMethodReturnType("overloadedMethod", new Class[]{int.class, int.class})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodParameters() { + try { + Assertions.assertEquals(0, util.getMethodParameterCount("overloadedMethod", new Class[]{})); + Assertions.assertEquals(1, util.getMethodParameterCount("overloadedMethod", new Class[]{int.class})); + Assertions.assertEquals(2, util.getMethodParameterCount("overloadedMethod", new Class[]{int.class, int.class})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodParameterTypes() { + try { + Assertions.assertEquals("int", util.getMethodParameterTypes("overloadedMethod", new Class[]{int.class}).get(0)); + Assertions.assertEquals("int", util.getMethodParameterTypes("overloadedMethod", new Class[]{int.class, int.class}).get(0)); + Assertions.assertEquals("int", util.getMethodParameterTypes("overloadedMethod", new Class[]{int.class, int.class}).get(1)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testFieldCount() { + Assertions.assertEquals(0, util.getFieldCount()); + } + + @Test + public void testInvokeDefaultConstructor() { + try { + Object instance = util.invokeConstructor(new Class[]{}, null); + Assertions.assertEquals(instance.getClass().getName(), "Overloaded"); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeOverloadedMethod1() { + try { + Object returnValue = util.invokeMethod("overloadedMethod", new Class[]{}, null); + Assertions.assertEquals(0, returnValue); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeOverloadedMethod2() { + try { + Object returnValue = util.invokeMethod("overloadedMethod", new Class[]{int.class}, new Object[]{1}); + Assertions.assertEquals(1, returnValue); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeOverloadedMethod3() { + try { + Object returnValue = util.invokeMethod("overloadedMethod", new Class[]{int.class, int.class}, new Object[]{1, 2}); + Assertions.assertEquals(3, returnValue); + } catch (Exception e) { + Assertions.fail(); + } } } \ No newline at end of file diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_Print.java b/src/test/java/testResources/CodeGen/Features/ByteCode_Print.java index 14557ff..60f251a 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_Print.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_Print.java @@ -1,106 +1,125 @@ package testResources.CodeGen.Features; -import de.maishai.ast.Operator; -import de.maishai.typedast.Type; -import de.maishai.typedast.typedclass.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import testResources.CodeGen.BytecodeTestUtil; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.util.List; public class ByteCode_Print { - public static TypedProgram get() { - return new TypedProgram( - List.of( - new TypedClass( - "Print", - List.of(), - List.of( - new TypedMethod( - "printIt", - Type.VOID, - List.of( - new TypedParameter( - "c", - Type.CHAR - ) - ), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedPrint( - new TypedFieldVarAccess( - false, - null, - "c", - Type.CHAR - ), - Type.VOID - ) - ), - Type.VOID - ) - ), - new TypedMethod( - "printMoreComplex", - Type.VOID, - List.of( - new TypedParameter( - "x", - Type.INT - ), - new TypedParameter( - "y", - Type.INT - ) - ), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedPrint( - new TypedBinary( - new TypedFieldVarAccess( - false, - null, - "x", - Type.INT - ), - Operator.LT, - new TypedFieldVarAccess( - false, - null, - "y", - Type.INT - ), - Type.BOOL - ), - Type.VOID - ) - ), - Type.VOID - ) - ) - ), - List.of( - new TypedConstructor( - "Print", - List.of(), - new TypedBlock( - List.of(), - List.of(), - Type.VOID - ), - Type.VOID, - List.of() - ) - ), - null, - null, - null, - Type.REFERENCE("Print") - ) - ), - null - ); + + private BytecodeTestUtil util; + + @BeforeEach + public void setUp() { + try { + util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Print.java"), "Print"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testConstructorCount() { + Assertions.assertEquals(1, util.getConstructorCount()); + // default constructor + } + + @Test + public void testDefaultConstructor() { + Assertions.assertEquals("Print", util.getConstructorNames().get(0)); + Assertions.assertEquals(0, util.getConstructorParameterCount(0)); + try { + Assertions.assertEquals("Print", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testMethodCount() { + Assertions.assertEquals(2, util.getMethodCount()); + } + + @Test + public void testMethodNames() { + Assertions.assertTrue(util.getMethodNames().contains("printIt")); + Assertions.assertTrue(util.getMethodNames().contains("printMoreComplex")); + } + + @Test + public void testMethodReturnType() { + try { + Assertions.assertEquals("void", util.getMethodReturnType("printIt", new Class[]{char.class})); + Assertions.assertEquals("void", util.getMethodReturnType("printMoreComplex", new Class[]{int.class, int.class})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodParameters() { + try { + Assertions.assertEquals(1, util.getMethodParameterCount("printIt", new Class[]{char.class})); + Assertions.assertEquals(2, util.getMethodParameterCount("printMoreComplex", new Class[]{int.class, int.class})); + Assertions.assertEquals("int", util.getMethodParameterTypes("printMoreComplex", new Class[]{int.class, int.class}).get(0)); + Assertions.assertEquals("int", util.getMethodParameterTypes("printMoreComplex", new Class[]{int.class, int.class}).get(1)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testFieldCount() { + Assertions.assertEquals(0, util.getFieldCount()); + } + + @Test + public void testInvokeDefaultConstructor() { + try { + Object instance = util.invokeConstructor(new Class[]{}, null); + Assertions.assertEquals(instance.getClass().getName(), "Print"); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokePrintIt() { + try { + PrintStream originalOut = System.out; + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + PrintStream newOut = new PrintStream(byteArrayOutputStream); + System.setOut(newOut); + Object returnValue = util.invokeMethod("printIt", new Class[]{char.class}, new Object[]{'a'}); + Assertions.assertNull(returnValue); + Assertions.assertEquals(3, byteArrayOutputStream.toString().length()); + // durch die newline wird die Ausgabe um 2 Zeichen länger + Assertions.assertEquals("a", byteArrayOutputStream.toString().substring(0, byteArrayOutputStream.toString().length() - 2)); + System.setOut(originalOut); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokePrintMoreComplex() { + try { + PrintStream originalOut = System.out; + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + PrintStream newOut = new PrintStream(byteArrayOutputStream); + System.setOut(newOut); + Object returnValue = util.invokeMethod("printMoreComplex", new Class[]{int.class, int.class}, new Object[]{5, 10}); + Assertions.assertNull(returnValue); + Assertions.assertEquals(6, byteArrayOutputStream.toString().length()); + // durch die newline wird die Ausgabe um 2 Zeichen länger + Assertions.assertEquals("true", byteArrayOutputStream.toString().substring(0, byteArrayOutputStream.toString().length() - 2)); + System.setOut(originalOut); + } catch (Exception e) { + Assertions.fail(); + } } } \ No newline at end of file diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_Return.java b/src/test/java/testResources/CodeGen/Features/ByteCode_Return.java index d6fd43f..6278b29 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_Return.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_Return.java @@ -1,131 +1,156 @@ package testResources.CodeGen.Features; -import de.maishai.typedast.Type; -import de.maishai.typedast.typedclass.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import testResources.CodeGen.BytecodeTestUtil; import java.util.List; public class ByteCode_Return { - public static TypedProgram get() { - return new TypedProgram( - List.of( - new TypedClass( - "Return", - List.of(), - List.of( - new TypedMethod( - "returnInt", - Type.INT, - List.of(), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedIntLiteral( - 10, - Type.INT - ), - Type.INT - ) - ), - Type.INT - ) - ), - new TypedMethod( - "returnVoid", - Type.VOID, - List.of(), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - null, - Type.VOID - ) - ), - Type.VOID - ) - ), - new TypedMethod( - "returnBoolean", - Type.BOOL, - List.of(), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedBoolLiteral( - true, - Type.BOOL - ), - Type.BOOL - ) - ), - Type.BOOL - ) - ), - new TypedMethod( - "returnChar", - Type.CHAR, - List.of(), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedCharLiteral( - 'a', - Type.CHAR - ), - Type.CHAR - ) - ), - Type.CHAR - ) - ), - new TypedMethod( - "returnClass", - Type.REFERENCE("Return"), - List.of(), - List.of(), - new TypedBlock( - List.of(), - List.of( - new TypedReturn( - new TypedNew( - Type.REFERENCE("Return"), - List.of() - ), - Type.REFERENCE("Return") - ) - ), - Type.REFERENCE("Return") - ) - ) - ), - List.of( - new TypedConstructor( - "Return", - List.of(), - new TypedBlock( - List.of(), - List.of(), - Type.VOID - ), - Type.VOID, - List.of() - ) - ), - null, - null, - null, - Type.REFERENCE("Return") - ) - ), - null - ); + + private BytecodeTestUtil util; + + @BeforeEach + public void setUp() { + try { + util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Return.java"), "Return"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testConstructorCount() { + Assertions.assertEquals(1, util.getConstructorCount()); + // default constructor + } + + @Test + public void testDefaultConstructor() { + Assertions.assertEquals("Return", util.getConstructorNames().get(0)); + Assertions.assertEquals(0, util.getConstructorParameterCount(0)); + try { + Assertions.assertEquals("Return", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodCount() { + Assertions.assertEquals(6, util.getMethodCount()); + } + + @Test + public void testMethodNames() { + Assertions.assertTrue(util.getMethodNames().contains("returnInt")); + Assertions.assertTrue(util.getMethodNames().contains("returnVoid")); + Assertions.assertTrue(util.getMethodNames().contains("returnBoolean")); + Assertions.assertTrue(util.getMethodNames().contains("returnChar")); + Assertions.assertTrue(util.getMethodNames().contains("returnObject")); + Assertions.assertTrue(util.getMethodNames().contains("returnAndInterruptFor")); + } + + @Test + public void testMethodReturnType() { + try { + Assertions.assertEquals("int", util.getMethodReturnType("returnInt", new Class[]{})); + Assertions.assertEquals("void", util.getMethodReturnType("returnVoid", new Class[]{})); + Assertions.assertEquals("boolean", util.getMethodReturnType("returnBoolean", new Class[]{})); + Assertions.assertEquals("char", util.getMethodReturnType("returnChar", new Class[]{})); + Assertions.assertEquals("Return", util.getMethodReturnType("returnObject", new Class[]{})); + Assertions.assertEquals("int", util.getMethodReturnType("returnAndInterruptFor", new Class[]{})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodParameters() { + try { + Assertions.assertEquals(0, util.getMethodParameterCount("returnInt", new Class[]{})); + Assertions.assertEquals(0, util.getMethodParameterCount("returnVoid", new Class[]{})); + Assertions.assertEquals(0, util.getMethodParameterCount("returnBoolean", new Class[]{})); + Assertions.assertEquals(0, util.getMethodParameterCount("returnChar", new Class[]{})); + Assertions.assertEquals(0, util.getMethodParameterCount("returnObject", new Class[]{})); + Assertions.assertEquals(0, util.getMethodParameterCount("returnAndInterruptFor", new Class[]{})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testFieldCount() { + Assertions.assertEquals(0, util.getFieldCount()); + } + + @Test + public void testInvokeDefaultConstructor() { + try { + Assertions.assertEquals("Return", + util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testReturnInt() { + try { + Assertions.assertEquals(10, + util.invokeMethod("returnInt", new Class[]{}, null)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testReturnVoid() { + try { + Assertions.assertNull(util.invokeMethod("returnVoid", new Class[]{}, null)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testReturnBoolean() { + try { + Assertions.assertTrue((boolean) + util.invokeMethod("returnBoolean", new Class[]{}, null)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testReturnChar() { + try { + Assertions.assertEquals('a', + util.invokeMethod("returnChar", new Class[]{}, null)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testReturnObject() { + try { + Assertions.assertEquals("Return", + util.invokeMethod("returnObject", new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testReturnAndInterruptFor() { + try { + Assertions.assertEquals(5, + util.invokeMethod("returnAndInterruptFor", new Class[]{}, new Object[]{})); + } catch (Exception e) { + Assertions.fail(); + } } } \ No newline at end of file diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_Unary.java b/src/test/java/testResources/CodeGen/Features/ByteCode_Unary.java index 255356e..d1aba2f 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_Unary.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_Unary.java @@ -3,100 +3,113 @@ package testResources.CodeGen.Features; import de.maishai.ast.UnaryOperator; import de.maishai.typedast.Type; import de.maishai.typedast.typedclass.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import testResources.CodeGen.BytecodeTestUtil; import java.util.List; public class ByteCode_Unary { - public static TypedProgram get() { - return new TypedProgram( - List.of( - new TypedClass( - "Unary", - List.of(), - List.of(), - List.of( - new TypedConstructor( - "Unary", - List.of(), - new TypedBlock( - List.of( - new TypedLocalVariable( - "a", - Type.INT - ), - new TypedLocalVariable( - "b", - Type.INT - ), - new TypedLocalVariable( - "c", - Type.BOOL - ) - ), - List.of( - new TypedAssignment( - new TypedIntLiteral( - 5, - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "a", - Type.INT - ), - Type.INT - ), - new TypedAssignment( - new TypedUnary( - UnaryOperator.SUB, - new TypedFieldVarAccess( - false, - null, - "a", - Type.INT - ), - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "b", - Type.INT - ), - Type.INT - ), - new TypedAssignment( - new TypedUnary( - UnaryOperator.NOT, - new TypedBoolLiteral( - true, - Type.BOOL - ), - Type.BOOL - ), - new TypedFieldVarAccess( - false, - null, - "c", - Type.BOOL - ), - Type.BOOL - ) - ), - Type.VOID - ), - Type.VOID, - List.of() - ) - ), - null, - null, - null, - Type.REFERENCE("Unary") - ) - ), - null - ); + + private BytecodeTestUtil util; + + @BeforeEach + public void setUp() { + try { + util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/Unary.java"), "Unary"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testConstructorCount() { + Assertions.assertEquals(1, util.getConstructorCount()); + // default constructor + } + + @Test + public void testDefaultConstructor() { + Assertions.assertEquals("Unary", util.getConstructorNames().get(0)); + Assertions.assertEquals(0, util.getConstructorParameterCount(0)); + try { + Assertions.assertEquals("Unary", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodCount() { + Assertions.assertEquals(2, util.getMethodCount()); + } + + @Test + public void testMethodNames() { + Assertions.assertTrue(util.getMethodNames().contains("testMinus")); + Assertions.assertTrue(util.getMethodNames().contains("testNot")); + } + + @Test + public void testMethodReturnType() { + try { + Assertions.assertEquals("int", + util.getMethodReturnType("testMinus", new Class[]{int.class})); + Assertions.assertEquals("boolean", + util.getMethodReturnType("testNot", new Class[]{boolean.class})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodParameters() { + try { + Assertions.assertEquals(1, + util.getMethodParameterCount("testMinus", new Class[]{int.class})); + Assertions.assertEquals("int", + util.getMethodParameterTypes("testMinus", new Class[]{int.class}).get(0)); + Assertions.assertEquals(1, + util.getMethodParameterCount("testNot", new Class[]{boolean.class})); + Assertions.assertEquals("boolean", + util.getMethodParameterTypes("testNot", new Class[]{boolean.class}).get(0)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testFieldCount() { + Assertions.assertEquals(0, util.getFieldCount()); + } + + @Test + public void testInvokeDefaultConstructor() { + try { + Assertions.assertEquals("Unary", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeTestMinus() { + try { + Assertions.assertEquals(-5, + util.invokeMethod("testMinus", new Class[]{int.class}, 5)); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeTestNot() { + try { + Assertions.assertEquals(true, + util.invokeMethod("testNot", new Class[]{boolean.class}, false)); + } catch (Exception e) { + Assertions.fail(); + } } } diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_VariableDefWithDecl.java b/src/test/java/testResources/CodeGen/Features/ByteCode_VariableDefWithDecl.java index f33ed3f..21a3b99 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_VariableDefWithDecl.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_VariableDefWithDecl.java @@ -1,74 +1,108 @@ package testResources.CodeGen.Features; -import de.maishai.typedast.Type; -import de.maishai.typedast.typedclass.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import testResources.CodeGen.BytecodeTestUtil; import java.util.List; public class ByteCode_VariableDefWithDecl { - public static TypedProgram get() { - return new TypedProgram( - List.of( - new TypedClass( - "VariableDefWithDecl", - List.of(), - List.of(), - List.of( - new TypedConstructor( - "VariableDefWithDecl", - List.of(), - new TypedBlock( - List.of( - new TypedLocalVariable( - "a", - Type.INT - ), - new TypedLocalVariable( - "b", - Type.INT - ) - ), - List.of( - new TypedAssignment( - new TypedIntLiteral( - 10, - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "a", - Type.INT - ), - Type.INT - ), - new TypedAssignment( - new TypedIntLiteral( - 20, - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "b", - Type.INT - ), - Type.INT - ) - ), - Type.VOID - ), - Type.VOID, - List.of() - ) - ), - null, - null, - null, - Type.REFERENCE("VariableDefWithDecl") - ) - ), - null - ); + + private BytecodeTestUtil util; + + @BeforeEach + public void setUp() { + try { + util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/VariableDefWithDecl.java"), + "VariableDefWithDecl"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testConstructorCount() { + Assertions.assertEquals(1, util.getConstructorCount()); + // default constructor + } + + @Test + public void testDefaultConstructor() { + Assertions.assertEquals("VariableDefWithDecl", util.getConstructorNames().get(0)); + Assertions.assertEquals(0, util.getConstructorParameterCount(0)); + try { + Assertions.assertEquals("VariableDefWithDecl", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testMethodCount() { + Assertions.assertEquals(2, util.getMethodCount()); + } + + @Test + public void testMethodNames() { + Assertions.assertTrue(util.getMethodNames().contains("testDefWithDeclInOne")); + Assertions.assertTrue(util.getMethodNames().contains("testDefWithDeclSeparate")); + } + + @Test + public void testMethodReturnType() { + try { + Assertions.assertEquals("int", util.getMethodReturnType("testDefWithDeclInOne", new Class[]{})); + Assertions.assertEquals("int", util.getMethodReturnType("testDefWithDeclSeparate", new Class[]{})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testMethodParameters() { + try { + Assertions.assertEquals(0, + util.getMethodParameterCount("testDefWithDeclInOne", new Class[]{})); + Assertions.assertEquals(0, + util.getMethodParameterCount("testDefWithDeclSeparate", new Class[]{})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testFieldCount() { + Assertions.assertEquals(0, util.getFieldCount()); + } + + @Test + public void testInvokeDefaultConstructor() { + try { + Assertions.assertEquals("VariableDefWithDecl", + util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testDefWithDeclInOne() { + try { + Assertions.assertEquals(10, + util.invokeMethod("testDefWithDeclInOne", new Class[]{}, null)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testDefWithDeclSeparate() { + try { + Assertions.assertEquals(10, + util.invokeMethod("testDefWithDeclSeparate", new Class[]{}, null)); + } catch (Exception e) { + throw new RuntimeException(e); + } } } \ No newline at end of file diff --git a/src/test/java/testResources/CodeGen/Features/ByteCode_While.java b/src/test/java/testResources/CodeGen/Features/ByteCode_While.java index 9fbde62..7970aa8 100644 --- a/src/test/java/testResources/CodeGen/Features/ByteCode_While.java +++ b/src/test/java/testResources/CodeGen/Features/ByteCode_While.java @@ -1,190 +1,135 @@ package testResources.CodeGen.Features; -import de.maishai.ast.Operator; -import de.maishai.typedast.Type; -import de.maishai.typedast.typedclass.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import testResources.CodeGen.BytecodeTestUtil; import java.util.List; public class ByteCode_While { - public static TypedProgram get() { - return new TypedProgram( - List.of( - new TypedClass( - "While", - List.of(), - List.of( - new TypedMethod( - "whileLoop", - Type.VOID, - List.of(), - List.of(), - new TypedBlock( - List.of( - new TypedLocalVariable( - "i", - Type.INT - ) - ), - List.of( - new TypedAssignment( - new TypedIntLiteral( - 0, - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Type.INT - ), - new TypedWhile( - new TypedBinary( - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Operator.LT, - new TypedIntLiteral( - 5, - Type.INT - ), - Type.BOOL - ), - new TypedBlock( - List.of(), - List.of( - new TypedAssignment( - new TypedBinary( - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Operator.ADD, - new TypedIntLiteral( - 1, - Type.INT - ), - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Type.INT - ) - ), - Type.VOID - ), - Type.VOID - ) - ) - ) - ), - new TypedMethod( - "doWhileLoop", - Type.VOID, - List.of(), - List.of(), - new TypedBlock( - List.of( - new TypedLocalVariable( - "i", - Type.INT - ) - ), - List.of( - new TypedAssignment( - new TypedIntLiteral( - 0, - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Type.INT - ), - new TypedDoWhile( - new TypedBlock( - List.of(), - List.of( - new TypedAssignment( - new TypedBinary( - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Operator.ADD, - new TypedIntLiteral( - 1, - Type.INT - ), - Type.INT - ), - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Type.INT - ) - ), - Type.VOID - ), - new TypedBinary( - new TypedFieldVarAccess( - false, - null, - "i", - Type.INT - ), - Operator.LT, - new TypedIntLiteral( - 5, - Type.INT - ), - Type.BOOL - ), - Type.VOID - ) - ) - ) - ) - ), - List.of( - new TypedConstructor( - "While", - List.of(), - new TypedBlock( - List.of(), - List.of(), - Type.VOID - ), - Type.VOID, - List.of() - ) - ), - null, - null, - null, - Type.REFERENCE("While") - ) - ), - null - ); + + private BytecodeTestUtil util; + + @BeforeEach + public void setUp() { + try { + util = new BytecodeTestUtil(List.of("src/test/testFiles/CodeGenFeatures/While.java"), "While"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testConstructorCount() { + Assertions.assertEquals(1, util.getConstructorCount()); + } + + @Test + public void testConstructor() { + Assertions.assertEquals("While", util.getConstructorNames().get(0)); + Assertions.assertEquals(0, util.getConstructorParameterCount(0)); + try { + Assertions.assertEquals("While", util.invokeConstructor(new Class[]{}, null).getClass().getName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + public void testMethodCount() { + Assertions.assertEquals(2, util.getMethodCount()); + } + + @Test + public void testMethodNames() { + Assertions.assertTrue(util.getMethodNames().contains("whileLoop")); + Assertions.assertTrue(util.getMethodNames().contains("doWhileLoop")); + } + + @Test + public void testMethodReturnType() { + try { + Assertions.assertEquals("void", util.getMethodReturnType("whileLoop", new Class[]{})); + Assertions.assertEquals("void", util.getMethodReturnType("doWhileLoop", new Class[]{})); + } catch (Exception e) { + Assertions.fail(); + } + } + + + @Test + public void testMethodParameters() { + try { + Assertions.assertEquals(0, util.getMethodParameterCount("whileLoop", new Class[]{})); + Assertions.assertEquals(0, util.getMethodParameterCount("doWhileLoop", new Class[]{})); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testFieldCount() { + Assertions.assertEquals(2, util.getFieldCount()); + } + + @Test + public void testFieldNames() { + Assertions.assertTrue(util.getFieldNames().contains("whileRepetitions")); + Assertions.assertTrue(util.getFieldNames().contains("doWhileRepetitions")); + } + + @Test + public void testFieldTypes() { + Assertions.assertEquals("int", util.getFieldTypes().get(0)); + Assertions.assertEquals("int", util.getFieldTypes().get(1)); + } + + @Test + public void testFieldValues() { + try { + Assertions.assertEquals(1, util.getFieldValue("whileRepetitions")); + Assertions.assertEquals(1, util.getFieldValue("doWhileRepetitions")); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeConstructor() { + try { + Object instance = util.invokeConstructor(new Class[]{}, null); + Assertions.assertEquals("While", instance.getClass().getName()); + Assertions.assertEquals(1, util.getFieldValueOfObject(instance, "whileRepetitions")); + Assertions.assertEquals(1, util.getFieldValueOfObject(instance, "doWhileRepetitions")); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeWhileLoop() { + try { + Assertions.assertEquals(1, util.getFieldValue("whileRepetitions")); + Assertions.assertEquals(1, util.getFieldValue("doWhileRepetitions")); + util.invokeMethod("whileLoop", new Class[]{}); + Assertions.assertEquals(5, util.getFieldValue("whileRepetitions")); + Assertions.assertEquals(1, util.getFieldValue("doWhileRepetitions")); + } catch (Exception e) { + Assertions.fail(); + } + } + + @Test + public void testInvokeDoWhileLoop() { + try { + Assertions.assertEquals(1, util.getFieldValue("whileRepetitions")); + Assertions.assertEquals(1, util.getFieldValue("doWhileRepetitions")); + util.invokeMethod("doWhileLoop", new Class[]{}); + Assertions.assertEquals(1, util.getFieldValue("whileRepetitions")); + Assertions.assertEquals(6, util.getFieldValue("doWhileRepetitions")); + } catch (Exception e) { + Assertions.fail(); + } } } \ No newline at end of file diff --git a/src/test/testFiles/CodeGenFeatures/Main.java b/src/test/testFiles/CodeGenFeatures/Main.java index e243729..faa2439 100644 --- a/src/test/testFiles/CodeGenFeatures/Main.java +++ b/src/test/testFiles/CodeGenFeatures/Main.java @@ -2,6 +2,9 @@ public class Main { int i; public static void main(String[] args) { - this.i = 10; + Main mainObject; + mainObject = new Main(); + mainObject.i = 3; + print(mainObject.i); } } \ No newline at end of file diff --git a/src/test/testFiles/CodeGenFeatures/Return.java b/src/test/testFiles/CodeGenFeatures/Return.java index 491c22a..a95e5b2 100644 --- a/src/test/testFiles/CodeGenFeatures/Return.java +++ b/src/test/testFiles/CodeGenFeatures/Return.java @@ -15,7 +15,16 @@ public class Return { return 'a'; } - public Return returnClass() { + public Return returnObject() { return new Return(); } + + public int returnAndInterruptFor() { + for (int i = 10; i > 0; i -= 1) { + if (i == 5) { + return i; + } + } + return 0; + } } \ No newline at end of file diff --git a/src/test/testFiles/CodeGenFeatures/Unary.java b/src/test/testFiles/CodeGenFeatures/Unary.java index d0ca0e1..ef168aa 100644 --- a/src/test/testFiles/CodeGenFeatures/Unary.java +++ b/src/test/testFiles/CodeGenFeatures/Unary.java @@ -4,7 +4,7 @@ public class Unary { return -a; } - public boolean testNot(boolean a) { - return !a; + public boolean testNot(boolean b) { + return !b; } } \ No newline at end of file diff --git a/src/test/testFiles/CodeGenFeatures/While.java b/src/test/testFiles/CodeGenFeatures/While.java index 93d88e9..3e909e5 100644 --- a/src/test/testFiles/CodeGenFeatures/While.java +++ b/src/test/testFiles/CodeGenFeatures/While.java @@ -1,24 +1,24 @@ public class While { - int whileRepititions; - int doWhileRepititions; + int whileRepetitions; + int doWhileRepetitions; public While() { - this.whileRepititions = 0; - this.doWhileRepititions = 0; + this.whileRepetitions = 1; + this.doWhileRepetitions = 1; } public void whileLoop() { - this.whileRepititions = 0; - while (i < 5) { - this.whileRepititions = this.whileRepititions + 1; + this.whileRepetitions = 0; + while (this.whileRepetitions < 5) { + this.whileRepetitions = this.whileRepetitions + 1; } } public void doWhileLoop() { - this.doWhileRepititions = 0; + this.doWhileRepetitions = 5; do { - this.doWhileRepititions = this.doWhileRepititions + 1; - } while (i < 5); + this.doWhileRepetitions = this.doWhileRepetitions + 1; + } while (this.doWhileRepetitions < 5); } } \ No newline at end of file