implemented test with complex class for type check

This commit is contained in:
JonathanFleischmann 2024-05-16 00:09:05 +02:00
parent f1b366e157
commit 2eecf3faa8
14 changed files with 1002 additions and 8 deletions

View File

@ -25,6 +25,7 @@ public class TypedAssignment implements TypedStatement {
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
value = convertExpression(typedProgram, untyped.value());
location = new TypedFieldVarAccess(typedProgram, untyped.location());
location.typeCheck(typedProgram);
}
@Override

View File

@ -4,12 +4,14 @@ import de.maishai.ast.records.BoolLiteral;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Opcodes;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedBoolLiteral implements TypedExpression {
private Boolean value;

View File

@ -4,9 +4,11 @@ import de.maishai.ast.records.CharLiteral;
import de.maishai.typedast.MethodContext;
import de.maishai.typedast.TypedExpression;
import de.maishai.typedast.Type;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class TypedCharLiteral implements TypedExpression {
private char value;
private Type type;

View File

@ -2,6 +2,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Label;
@ -11,6 +12,7 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedIfElse implements TypedStatement {
private TypedExpression typedCon;
private TypedBlock ifTypedBlock;

View File

@ -2,6 +2,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Method;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.MethodVisitor;
@ -12,6 +13,7 @@ import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedMethod implements TypedNode {
private String name;
private Type returnType;

View File

@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Expression;
import de.maishai.ast.records.MethodCall;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -15,6 +16,7 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedMethodCall implements TypedExpression, TypedStatement {
private TypedFieldVarAccess recipient;
private List<TypedExpression> args = new ArrayList<>();

View File

@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.Expression;
import de.maishai.ast.records.New;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@ -13,6 +14,7 @@ import java.util.List;
import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@AllArgsConstructor
public class TypedNew implements TypedExpression, TypedStatement {
private Type type;
private List<TypedExpression> args = new ArrayList<>();

View File

@ -59,4 +59,18 @@ public class TypedProgram {
currentClass = null;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
TypedProgram other = (TypedProgram) obj;
if(typedClasses.equals(other.typedClasses) &&
(currentClass == null && other.currentClass == null
|| currentClass.equals(other.currentClass))) {
return true;
} else {
System.out.println("TypedPrograms are not equal:\n" + this.typedClasses + "\n" + other.typedClasses + "\n");
return false;
}
}
}

View File

@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass;
import de.maishai.ast.records.*;
import de.maishai.typedast.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.objectweb.asm.Opcodes;
@ -11,6 +12,7 @@ import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TypedReturn implements TypedStatement {
private TypedExpression ret;
private Type type;

View File

@ -165,7 +165,6 @@ public class AbstractSyntax_ClassWithConstructor {
localVariables,
statementList
);
return new Constructor(
"ClassWithConstructor",
parameters,

View File

@ -35,7 +35,7 @@ public class TypedAbstractSyntax_ClassWithConstructor {
getConstructors(),
null,
null,
Type.REFERENCE("ClassWithField")
Type.REFERENCE("ClassWithConstructor")
)
),
null
@ -204,20 +204,20 @@ public class TypedAbstractSyntax_ClassWithConstructor {
Type.INT
)
),
Type.INT
Type.VOID
),
Type.INT
Type.VOID
)
),
Type.INT
Type.VOID
),
Type.INT
Type.VOID
)
);
TypedBlock typedBlock = new TypedBlock(
typedLocalVariables,
typedStatementList,
Type.INT
Type.VOID
);
return new TypedConstructor(

View File

@ -0,0 +1,960 @@
//public class ComplexClass {
//
// int x;
// int y;
// ComplexClass b;
// ComplexClass c;
//
// public ComplexClass() {
// this.y = 10;
// this.x = 2;
// int i;
// for (i = 0; i < (this.y + 1); i = i + 1) {
// int j;
// for (j = 0; j < this.y; j += 1) {
// this.x = this.x * this.x;
// if (this.x == 100) {
// break;
// }
// }
// }
// this.y = 2;
// do {
// this.y = this.y + 1;
// } while (this.y < 10);
//
// int k;
// k = 0;
// for (k = 0; k < 10; k = k + 1) {
// if (k == 5) {
// return this;
// }
// }
//
// }
//
// public ComplexClass(int x) {
// this.b = new ComplexClass();
// this.c = new ComplexClass();
// this.x = x;
// this.b.x = 7;
// this.b.y = 13;
// this.c.x = this.b.getX() * this.b.y * this.b.getX('g');
// this.c.y = 25;
// }
//
// public ComplexClass(int x, int y) {
// this.x = x;
// this.y = y;
// }
//
// public ComplexClass initComplexClass(int x) {
// int a;
// a = 10;
// this.b = new ComplexClass(x);
// this.b.x = 10 + a;
// this.b.y = 20;
// this.b.c.x = 20 + a;
// if (methodCall()) {
// this.b.getC().b.y = this.b.x;
// }
// return this.b;
// }
//
// public ComplexClass init(int x, int y) {
// return new ComplexClass(x, y);
// }
//
// public ComplexClass(int x, int y, char z) {
// this.x = x;
// this.y = y;
// }
//
// public int getX(char z) {
// return this.x;
// }
//
// public ComplexClass getC() {
// return this.c;
// }
//
// public int getX() {
// return this.x;
// }
//
// public boolean methodCall() {
// return false;
// }
//
//}
import de.maishai.ast.Operator;
import de.maishai.typedast.Type;
import de.maishai.typedast.typedclass.*;
import java.util.List;
public class TypedAbstractSyntax_ComplexClass {
public static TypedProgram get() {
return new TypedProgram(
getClasses(),
null
);
}
private static List<TypedClass> getClasses() {
return List.of(
getClass1()
);
}
private static TypedClass getClass1() {
return new TypedClass(
"ComplexClass",
getFields(),
getMethods(),
getConstructors(),
null,
null,
Type.REFERENCE("ComplexClass")
);
}
private static List<TypedDeclaration> getFields() {
return List.of(
new TypedDeclaration("x", Type.INT),
new TypedDeclaration("y", Type.INT),
new TypedDeclaration("b", Type.REFERENCE("ComplexClass")),
new TypedDeclaration("c", Type.REFERENCE("ComplexClass"))
);
}
private static List<TypedConstructor> getConstructors() {
return List.of(
getConstructor1(),
getConstructor2(),
getConstructor3(),
getConstructor4()
);
}
private static TypedConstructor getConstructor1() {
TypedBlock block = new TypedBlock(
List.of(
new TypedLocalVariable("i", Type.INT),
new TypedLocalVariable("k", Type.INT)
),
List.of(
new TypedAssignment(
new TypedIntLiteral(10),
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(2),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedFor(
new TypedAssignment(
new TypedIntLiteral(0),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Type.INT
),
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Operator.LT,
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Operator.ADD,
new TypedIntLiteral(1),
Type.INT
),
Type.BOOL
),
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Operator.ADD,
new TypedIntLiteral(1),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"i",
Type.INT),
Type.INT
),
new TypedBlock(
List.of(
new TypedLocalVariable(
"j",
Type.INT
)
),
List.of(
new TypedFor(
new TypedAssignment(
new TypedIntLiteral(0),
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT),
Type.INT
),
new TypedBinary(
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT),
Operator.LT,
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.BOOL
),
new TypedAssignment(
new TypedBinary(
new TypedIntLiteral(1),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"j",
Type.INT
),
Type.INT
),
new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Operator.MUL,
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedIfElse(
new TypedBinary(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Operator.EQ,
new TypedIntLiteral(100),
Type.BOOL
),
new TypedBlock(
List.of(),
List.of(
new TypedBreak()
)
),
null,
Type.VOID
)
)
),
Type.VOID
)
)
),
Type.VOID
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(),
block
);
}
private static TypedConstructor getConstructor2() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of()
),
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
),
new TypedAssignment(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of()
),
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
),
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(7),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(13),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedBinary(
new TypedBinary(
new TypedMethodCall(
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"getX",
Type.INT
),
List.of(),
Type.INT
),
Operator.MUL,
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
),
Operator.MUL,
new TypedMethodCall(
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"getX",
Type.INT
),
List.of(
new TypedCharLiteral(
'g',
Type.CHAR
)
),
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"c",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(25),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"c",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(
new TypedParameter(
"x",
Type.INT
)
),
block
);
}
private static TypedConstructor getConstructor3() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.INT
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
)
),
block
);
}
private static TypedConstructor getConstructor4() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
),
new TypedFieldVarAccess(
true,
null,
"y",
Type.INT
),
Type.INT
)
)
);
return new TypedConstructor(
"ComplexClass",
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
),
new TypedParameter(
"z",
Type.CHAR
)
),
block
);
}
private static List<TypedMethod> getMethods() {
return List.of(
getMethod1(),
getMethod2(),
getMethod3(),
getMethod4(),
getMethod5(),
getMethod6()
);
}
private static TypedMethod getMethod1() {
TypedBlock block = new TypedBlock(
List.of(
new TypedLocalVariable("a", Type.INT)
),
List.of(
new TypedAssignment(
new TypedIntLiteral(10),
new TypedFieldVarAccess(
false,
null,
"a",
Type.REFERENCE("ComplexClass")
),
Type.INT
),
new TypedAssignment(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
)
)
),
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
),
new TypedAssignment(
new TypedBinary(
new TypedIntLiteral(10),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"a",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedIntLiteral(20),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
),
new TypedAssignment(
new TypedBinary(
new TypedIntLiteral(20),
Operator.ADD,
new TypedFieldVarAccess(
false,
null,
"a",
Type.INT
),
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"c",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
Type.INT
),
new TypedIfElse(
new TypedMethodCall(
new TypedFieldVarAccess(
false,
null,
"methodCall",
Type.BOOL
),
List.of(),
Type.BOOL
),
new TypedBlock(
List.of(),
List.of(
new TypedAssignment(
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"x",
Type.INT
),
new TypedFieldVarAccess(
true,
new TypedFieldVarAccess(
false,
new TypedMethodCall(
new TypedFieldVarAccess(
false,
new TypedFieldVarAccess(
false,
null,
"b",
Type.REFERENCE("ComplexClass")
),
"getC",
Type.REFERENCE("ComplexClass")
),
List.of(),
Type.REFERENCE("ComplexClass")
),
"b",
Type.REFERENCE("ComplexClass")
),
"y",
Type.INT
),
Type.INT
)
)
),
null,
Type.VOID
),
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"b",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
)
)
);
return new TypedMethod(
"initComplexClass",
Type.REFERENCE("ComplexClass"),
List.of(
new TypedParameter(
"x",
Type.INT
)
),
List.of(),
block
);
}
private static TypedMethod getMethod2() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedNew(
Type.REFERENCE("ComplexClass"),
List.of(
new TypedFieldVarAccess(
false,
null,
"x",
Type.INT
),
new TypedFieldVarAccess(
false,
null,
"y",
Type.INT
)
)
),
Type.REFERENCE("ComplexClass")
)
)
);
return new TypedMethod(
"init",
Type.REFERENCE("ComplexClass"),
List.of(
new TypedParameter(
"x",
Type.INT
),
new TypedParameter(
"y",
Type.INT
)
),
List.of(),
block
);
}
private static TypedMethod getMethod3() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
)
)
);
return new TypedMethod(
"getX",
Type.INT,
List.of(
new TypedParameter(
"z",
Type.CHAR
)
),
List.of(),
block
);
}
private static TypedMethod getMethod4() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"c",
Type.REFERENCE("ComplexClass")
),
Type.REFERENCE("ComplexClass")
)
)
);
return new TypedMethod(
"getC",
Type.REFERENCE("ComplexClass"),
List.of(),
List.of(),
block
);
}
private static TypedMethod getMethod5() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedFieldVarAccess(
true,
null,
"x",
Type.INT
),
Type.INT
)
)
);
return new TypedMethod(
"getX",
Type.INT,
List.of(),
List.of(),
block
);
}
private static TypedMethod getMethod6() {
TypedBlock block = new TypedBlock(
List.of(),
List.of(
new TypedReturn(
new TypedBoolLiteral(
false,
Type.BOOL
),
Type.BOOL
)
)
);
return new TypedMethod(
"methodCall",
Type.BOOL,
List.of(),
List.of(),
block
);
}
}

View File

@ -59,6 +59,6 @@ public class ScannerParserTests {
@Test
public void testComplexClass() {
Program resultAst = Compiler.generateASTFromFile(List.of("src/main/resources/JavaTestfiles/ComplexClass.java"));
assertEquals(AbstractSyntax_ComplexClass.get(), resultAst);
assertEquals(TypedAbstractSyntax_ComplexClass.get(), resultAst);
}
}

View File

@ -23,4 +23,10 @@ public class TypingTests {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_ClassWithConstructor.get());
assertEquals(TypedAbstractSyntax_ClassWithConstructor.get(), resultTypedAst);
}
@Test
public void testComplexClass() {
TypedProgram resultTypedAst = Compiler.generateTypedASTFromAst(AbstractSyntax_ComplexClass.get());
assertEquals(TypedAbstractSyntax_ComplexClass.get(), resultTypedAst);
}
}