mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-28 16:28:04 +00:00
Refactored typedAST
This commit is contained in:
parent
ae3280fb67
commit
b4fd003f8e
@ -31,13 +31,13 @@ public class TypedAssignment implements TypedStatement {
|
|||||||
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
|
public void convertToTypedAssignment(TypedProgram typedProgram, Assignment untyped) {
|
||||||
value = convertExpression(typedProgram, untyped.value());
|
value = convertExpression(typedProgram, untyped.value());
|
||||||
location = new TypedFieldVarAccess(typedProgram, untyped.location());
|
location = new TypedFieldVarAccess(typedProgram, untyped.location());
|
||||||
//location.typeCheck(typedProgram);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
|
||||||
if(typedProgram.getCurrentClass().isCurrentMainMethodPresent() && location.getField() && location.getRecursiveOwnerChain() == null){
|
if (currentClass.isCurrentMainMethodPresent() && location.getField() && location.getRecursiveOwnerChain() == null) {
|
||||||
throw new RuntimeException("Main Method, is not allowed to have fields, they are not static");
|
throw new RuntimeException("Main Method, is not allowed to have fields, they are not static");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +98,19 @@ public class TypedBlock implements TypedNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void clearLocalVariable(TypedProgram typedProgram) {
|
private void clearLocalVariable(TypedProgram typedProgram) {
|
||||||
|
TypedClass typedClass = typedProgram.getCurrentClass();
|
||||||
|
TypedMethod typedMethod = typedClass.getCurrentMethod();
|
||||||
|
TypedConstructor typedConstructor = typedClass.getCurrentConstructor();
|
||||||
|
|
||||||
for (var typedLocalVariable : vars) {
|
for (var typedLocalVariable : vars) {
|
||||||
if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
|
if (typedClass.isCurrentMethodPresent() && !typedClass.isCurrentConstructorPresent()) {
|
||||||
if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(typedLocalVariable.getName())) {
|
if (typedMethod.isLocalVariableInMethod(typedLocalVariable.getName())) {
|
||||||
typedProgram.getCurrentClass().getCurrentMethod().deleteLocalVariableInMethod(typedLocalVariable.getName());
|
typedMethod.deleteLocalVariableInMethod(typedLocalVariable.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
|
if (!typedClass.isCurrentMethodPresent() && typedClass.isCurrentConstructorPresent()) {
|
||||||
if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(typedLocalVariable.getName())) {
|
if (typedConstructor.isLocalVariableInConstructor(typedLocalVariable.getName())) {
|
||||||
typedProgram.getCurrentClass().getCurrentConstructor().deleteLocalVariableInConstructor(typedLocalVariable.getName());
|
typedConstructor.deleteLocalVariableInConstructor(typedLocalVariable.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ public class TypedBoolLiteral implements TypedExpression {
|
|||||||
private Boolean value;
|
private Boolean value;
|
||||||
private Type type;
|
private Type type;
|
||||||
|
|
||||||
|
|
||||||
public TypedBoolLiteral(BoolLiteral unTypedBoolLiteral) {
|
public TypedBoolLiteral(BoolLiteral unTypedBoolLiteral) {
|
||||||
convertToTypedBoolLiteral(unTypedBoolLiteral);
|
convertToTypedBoolLiteral(unTypedBoolLiteral);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import de.maishai.ast.records.Declaration;
|
|||||||
import de.maishai.ast.records.Method;
|
import de.maishai.ast.records.Method;
|
||||||
import de.maishai.typedast.ClassContext;
|
import de.maishai.typedast.ClassContext;
|
||||||
import de.maishai.typedast.Type;
|
import de.maishai.typedast.Type;
|
||||||
|
import de.maishai.typedast.TypedExpression;
|
||||||
import de.maishai.typedast.TypedNode;
|
import de.maishai.typedast.TypedNode;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -47,17 +48,6 @@ public class TypedClass implements TypedNode {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
isMainCurrentMethod = false;
|
isMainCurrentMethod = false;
|
||||||
}
|
}
|
||||||
public boolean isParameterNameInCurrentConstructor(String parameterName) {
|
|
||||||
if (currentConstructor == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (TypedParameter p : currentConstructor.getTypedParameters()) {
|
|
||||||
if (p.getParaName().equals(parameterName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
|
public void convertMethodsAndConstructorsAndFields(TypedProgram typedProgram, Class c) {
|
||||||
// Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt.
|
// Am Anfang werden die Attribute, die Konstruktoren und Methoden in die jeweilige Liste eingefügt.
|
||||||
@ -108,11 +98,31 @@ public class TypedClass implements TypedNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkMethodExists(TypedMethod typedMethod) {
|
||||||
|
typedMethods.stream().filter(method -> method.equals(typedMethod)).findFirst().ifPresentOrElse(
|
||||||
|
method -> {
|
||||||
|
throw new RuntimeException("Method " + typedMethod.getName() + " already exists");
|
||||||
|
}, () -> {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isParameterNameInCurrentConstructor(String parameterName) {
|
||||||
|
if (currentConstructor == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (TypedParameter p : currentConstructor.getTypedParameters()) {
|
||||||
|
if (p.getParaName().equals(parameterName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isParameterWitNameInCurrentMethod(String parameterName) {
|
public boolean isParameterWitNameInCurrentMethod(String parameterName) {
|
||||||
return this.getCurrentMethod().getTypedParameters().stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName));
|
return this.getCurrentMethod().getTypedParameters().stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName));
|
||||||
}
|
}
|
||||||
@ -188,6 +198,7 @@ public class TypedClass implements TypedNode {
|
|||||||
public boolean isCurrentConstructorPresent() {
|
public boolean isCurrentConstructorPresent() {
|
||||||
return currentConstructor != null;
|
return currentConstructor != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCurrentMainMethodPresent() {
|
public boolean isCurrentMainMethodPresent() {
|
||||||
return isMainCurrentMethod;
|
return isMainCurrentMethod;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,32 @@ public class TypedConstructor implements TypedNode {
|
|||||||
this.typedBlock = typedBlock;
|
this.typedBlock = typedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
|
||||||
|
name = unTypedConstructor.className();
|
||||||
|
convertToTypedParameter(typedProgram, unTypedConstructor.params());
|
||||||
|
type = Type.VOID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertToTypedParameter(TypedProgram typedProgram, List<Parameter> params) {
|
||||||
|
for (Parameter param : params) {
|
||||||
|
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
|
||||||
|
checkIfParameterExists(typedParameter.getParaName());
|
||||||
|
typedParameters.add(typedParameter);
|
||||||
|
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
|
type = typedBlock.typeCheck(typedProgram);
|
||||||
|
if (type != Type.VOID) {
|
||||||
|
throw new RuntimeException("Constructor must not habe a return statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
|
public TypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
|
||||||
convertToTypedConstructor(typedProgram, unTypedConstructor);
|
convertToTypedConstructor(typedProgram, unTypedConstructor);
|
||||||
}
|
}
|
||||||
@ -53,19 +79,7 @@ public class TypedConstructor implements TypedNode {
|
|||||||
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
|
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void convertToTypedConstructor(TypedProgram typedProgram, Constructor unTypedConstructor) {
|
private void checkIfParameterExists(String paraName) {
|
||||||
name = unTypedConstructor.className();
|
|
||||||
|
|
||||||
for (Parameter param : unTypedConstructor.params()) {
|
|
||||||
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
|
|
||||||
checkIfParameterExists(typedParameter.getParaName());
|
|
||||||
typedParameters.add(typedParameter);
|
|
||||||
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
|
|
||||||
}
|
|
||||||
type = Type.VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkIfParameterExists(String paraName) {
|
|
||||||
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) {
|
if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) {
|
||||||
throw new RuntimeException("Parameter " + paraName + " already exists");
|
throw new RuntimeException("Parameter " + paraName + " already exists");
|
||||||
}
|
}
|
||||||
@ -75,20 +89,11 @@ public class TypedConstructor implements TypedNode {
|
|||||||
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
|
this.typedBlock = new TypedBlock(typedProgram, unTypedConstructor.block());
|
||||||
typeCheck(typedProgram);
|
typeCheck(typedProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteLocalVariableInConstructor(String localVarName) {
|
public void deleteLocalVariableInConstructor(String localVarName) {
|
||||||
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
|
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
|
||||||
type = typedBlock.typeCheck(typedProgram);
|
|
||||||
if (type != Type.VOID) {
|
|
||||||
throw new RuntimeException("Constructor must not habe a return statement");
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void codeGen(ClassContext ctx) {
|
public void codeGen(ClassContext ctx) {
|
||||||
int accessModifier = Opcodes.ACC_PUBLIC;
|
int accessModifier = Opcodes.ACC_PUBLIC;
|
||||||
|
@ -29,12 +29,15 @@ public final class TypedDeclaration implements TypedNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
if (type.getReference() != null && !typedProgram.getCurrentClass().getClassName().equals(type.getReference())) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
|
||||||
|
if (type.getReference() != null && !currentClass.getClassName().equals(type.getReference())) {
|
||||||
if (!typedProgram.isTypedClassPresent(type.getReference())) {
|
if (!typedProgram.isTypedClassPresent(type.getReference())) {
|
||||||
throw new RuntimeException("Type " + type.getReference() + " not found");
|
throw new RuntimeException("Type " + type.getReference() + " not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typedProgram.getCurrentClass().isThereField(name)) {
|
|
||||||
|
if (currentClass.isThereField(name)) {
|
||||||
throw new RuntimeException("Field " + name + " already declared");
|
throw new RuntimeException("Field " + name + " already declared");
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
|
@ -48,14 +48,16 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type checkFieldOrMethodType(TypedProgram typedProgram) {
|
private Type checkFieldOrMethodType(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isThereField(name)) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
|
||||||
|
if (currentClass.isThereField(name)) {
|
||||||
return checkTypeField(typedProgram);
|
return checkTypeField(typedProgram);
|
||||||
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
|
} else if (currentClass.isMethodOfCurrentClass(name)) {
|
||||||
type = typedProgram.getCurrentClass().getMethodType(name);
|
type = currentClass.getMethodType(name);
|
||||||
return type;
|
return type;
|
||||||
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
|
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
|
||||||
|
boolean isClassWithNamePresent = typedProgram.isClassWithNamePresent(recursiveOwnerChain.getType().getReference());
|
||||||
if (typedProgram.isClassWithNamePresent(recursiveOwnerChain.getType().getReference())) {
|
if (isClassWithNamePresent) {
|
||||||
Type typeofFieldNameInClass = typedProgram.getTypeOfFieldNameInClass(recursiveOwnerChain.getType().getReference(), name);
|
Type typeofFieldNameInClass = typedProgram.getTypeOfFieldNameInClass(recursiveOwnerChain.getType().getReference(), name);
|
||||||
if (typeofFieldNameInClass != null) {
|
if (typeofFieldNameInClass != null) {
|
||||||
return typeofFieldNameInClass;
|
return typeofFieldNameInClass;
|
||||||
@ -63,7 +65,7 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
throw new RuntimeException("Field " + name + " not declared in class " + recursiveOwnerChain.getType().getReference());
|
throw new RuntimeException("Field " + name + " not declared in class " + recursiveOwnerChain.getType().getReference());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
|
type = currentClass.getFieldType(typedFieldVarAccess.getName());
|
||||||
return type;
|
return type;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Field " + name + " not declared");
|
throw new RuntimeException("Field " + name + " not declared");
|
||||||
@ -71,9 +73,11 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type checkVariableType(TypedProgram typedProgram) {
|
private Type checkVariableType(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
|
||||||
|
if (currentClass.isCurrentConstructorPresent()) {
|
||||||
return checkConstructorVariableType(typedProgram);
|
return checkConstructorVariableType(typedProgram);
|
||||||
} else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
|
} else if (currentClass.isCurrentMethodPresent()) {
|
||||||
return checkMethodVariableType(typedProgram);
|
return checkMethodVariableType(typedProgram);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Variable " + name + " not declared");
|
throw new RuntimeException("Variable " + name + " not declared");
|
||||||
@ -81,10 +85,13 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type checkConstructorVariableType(TypedProgram typedProgram) {
|
private Type checkConstructorVariableType(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name);
|
TypedConstructor currentConstructor = currentClass.getCurrentConstructor();
|
||||||
} else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) {
|
|
||||||
type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name);
|
if (currentClass.isParameterNameInCurrentConstructor(name)) {
|
||||||
|
type = currentClass.getParameterTypeInCurrentConstructor(name);
|
||||||
|
} else if (currentConstructor.isLocalVariablePresent(name)) {
|
||||||
|
type = currentConstructor.getLocalVariableType(name);
|
||||||
} else {
|
} else {
|
||||||
return checkFieldOrMethodOrRecursiveType(typedProgram);
|
return checkFieldOrMethodOrRecursiveType(typedProgram);
|
||||||
}
|
}
|
||||||
@ -92,10 +99,13 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type checkMethodVariableType(TypedProgram typedProgram) {
|
private Type checkMethodVariableType(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isParameterWitNameInCurrentMethod(name)) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name);
|
TypedMethod currentMethod = currentClass.getCurrentMethod();
|
||||||
} else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) {
|
|
||||||
type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name);
|
if (currentClass.isParameterWitNameInCurrentMethod(name)) {
|
||||||
|
type = currentClass.getParameterTypeInCurrentMethod(name);
|
||||||
|
} else if (currentMethod.isLocalVariablePresent(name)) {
|
||||||
|
type = currentMethod.getLocalVariableType(name);
|
||||||
} else {
|
} else {
|
||||||
return checkFieldOrMethodOrRecursiveType(typedProgram);
|
return checkFieldOrMethodOrRecursiveType(typedProgram);
|
||||||
}
|
}
|
||||||
@ -103,17 +113,20 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type checkFieldOrMethodOrRecursiveType(TypedProgram typedProgram) {
|
private Type checkFieldOrMethodOrRecursiveType(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isThereField(name)) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
type = typedProgram.getCurrentClass().getFieldType(name);
|
|
||||||
} else if (typedProgram.getCurrentClass().isMethodOfCurrentClass(name)) {
|
if (currentClass.isThereField(name)) {
|
||||||
type = typedProgram.getCurrentClass().getMethodType(name);
|
type = currentClass.getFieldType(name);
|
||||||
|
} else if (currentClass.isMethodOfCurrentClass(name)) {
|
||||||
|
type = currentClass.getMethodType(name);
|
||||||
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
|
} else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) {
|
||||||
type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName());
|
type = currentClass.getFieldType(typedFieldVarAccess.getName());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Variable " + name + " not declared");
|
throw new RuntimeException("Variable " + name + " not declared");
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type checkTypeField(TypedProgram typedProgram) {
|
private Type checkTypeField(TypedProgram typedProgram) {
|
||||||
if (recursiveOwnerChain != null) {
|
if (recursiveOwnerChain != null) {
|
||||||
if (recursiveOwnerChain.getType() != null) {
|
if (recursiveOwnerChain.getType() != null) {
|
||||||
@ -123,6 +136,7 @@ public class TypedFieldVarAccess implements TypedExpression {
|
|||||||
type = typedProgram.getCurrentClass().getFieldType(name);
|
type = typedProgram.getCurrentClass().getFieldType(name);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodContext ctx) {
|
public void codeGen(MethodContext ctx) {
|
||||||
if (recursiveOwnerChain != null) {
|
if (recursiveOwnerChain != null) {
|
||||||
|
@ -20,7 +20,6 @@ public class TypedIntLiteral implements TypedExpression {
|
|||||||
private Integer value;
|
private Integer value;
|
||||||
private Type type;
|
private Type type;
|
||||||
|
|
||||||
|
|
||||||
public TypedIntLiteral(IntLiteral unTypedIntLiteral) {
|
public TypedIntLiteral(IntLiteral unTypedIntLiteral) {
|
||||||
convertToTypedIntLiteral(unTypedIntLiteral);
|
convertToTypedIntLiteral(unTypedIntLiteral);
|
||||||
}
|
}
|
||||||
|
@ -28,18 +28,22 @@ public final class TypedLocalVariable implements TypedNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(name)) {
|
TypedMethod currentMethod = currentClass.getCurrentMethod();
|
||||||
|
TypedConstructor currentConstructor = currentClass.getCurrentConstructor();
|
||||||
|
|
||||||
|
if (currentClass.isCurrentMethodPresent() && !currentClass.isCurrentConstructorPresent()) {
|
||||||
|
if (currentMethod.isLocalVariableInMethod(name)) {
|
||||||
throw new RuntimeException("Variable " + name + " already declared");
|
throw new RuntimeException("Variable " + name + " already declared");
|
||||||
}
|
}
|
||||||
typedProgram.getCurrentClass().getCurrentMethod().getLocalVariables().add(this);
|
currentMethod.getLocalVariables().add(this);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
|
if (!currentClass.isCurrentMethodPresent() && currentClass.isCurrentConstructorPresent()) {
|
||||||
if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(name)) {
|
if (currentConstructor.isLocalVariableInConstructor(name)) {
|
||||||
throw new RuntimeException("Variable " + name + " already declared");
|
throw new RuntimeException("Variable " + name + " already declared");
|
||||||
}
|
}
|
||||||
typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariables().add(this);
|
currentConstructor.getLocalVariables().add(this);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("not found method or constructor in class");
|
throw new RuntimeException("not found method or constructor in class");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.maishai.typedast.typedclass;
|
package de.maishai.typedast.typedclass;
|
||||||
|
|
||||||
import de.maishai.ast.records.Method;
|
import de.maishai.ast.records.Method;
|
||||||
|
import de.maishai.ast.records.Parameter;
|
||||||
import de.maishai.typedast.*;
|
import de.maishai.typedast.*;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -26,21 +27,21 @@ public class TypedMethod implements TypedNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
|
public void convertToTypedMethod(TypedProgram typedProgram, Method unTypedMethod) {
|
||||||
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
|
||||||
name = unTypedMethod.methodName();
|
name = unTypedMethod.methodName();
|
||||||
returnType = unTypedMethod.type();
|
returnType = unTypedMethod.type();
|
||||||
for (var parameter : unTypedMethod.params()) {
|
convertToTypedParameter(typedProgram, unTypedMethod.params());
|
||||||
TypedParameter typedParameter = new TypedParameter(typedProgram, parameter);
|
currentClass.checkMethodExists(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertToTypedParameter(TypedProgram typedProgram, List<Parameter> params) {
|
||||||
|
for (Parameter param : params) {
|
||||||
|
TypedParameter typedParameter = new TypedParameter(typedProgram, param);
|
||||||
checkIfParameterExists(typedParameter.getParaName());
|
checkIfParameterExists(typedParameter.getParaName());
|
||||||
typedParameters.add(typedParameter);
|
typedParameters.add(typedParameter);
|
||||||
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
|
localVariables.add(new TypedLocalVariable(typedParameter.getParaName(), typedParameter.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedProgram.getCurrentClass().getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse(
|
|
||||||
method -> {
|
|
||||||
throw new RuntimeException("Method " + name + " already exists");
|
|
||||||
}, () -> {
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkIfParameterExists(String parameterName) {
|
public void checkIfParameterExists(String parameterName) {
|
||||||
@ -49,6 +50,7 @@ public class TypedMethod implements TypedNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
|
public void convertToTypedBlock(TypedProgram typedProgram, Method unTypedMethod) {
|
||||||
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
|
typedBlock = new TypedBlock(typedProgram, unTypedMethod.block());
|
||||||
typeCheck(typedProgram);
|
typeCheck(typedProgram);
|
||||||
@ -70,6 +72,7 @@ public class TypedMethod implements TypedNode {
|
|||||||
public void deleteLocalVariableInMethod(String localVarName) {
|
public void deleteLocalVariableInMethod(String localVarName) {
|
||||||
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
|
localVariables.removeIf(localVariable -> localVariable.getName().equals(localVarName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getLocalVariableType(String localVarName) {
|
public Type getLocalVariableType(String localVarName) {
|
||||||
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
|
return localVariables.stream().filter(localVariable -> localVariable.getName().equals(localVarName)).findFirst().get().getType();
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,9 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
String ownerChainName = null;
|
String ownerChainName = null;
|
||||||
if (typedProgram.getCurrentClass().isCurrentMainMethodPresent() && recipient.getRecursiveOwnerChain() == null) {
|
if (currentClass.isCurrentMainMethodPresent() && recipient.getRecursiveOwnerChain() == null) {
|
||||||
throw new RuntimeException("Main Method, is not allowed to have methods, they are not static");
|
throw new RuntimeException("Main Method, is not allowed to have methods, they are not static");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
|||||||
ownerChainName = recipient.getRecursiveOwnerChain().getType().getReference();
|
ownerChainName = recipient.getRecursiveOwnerChain().getType().getReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!typedProgram.getCurrentClass().getClassName().equals(ownerChainName) && ownerChainName != null) {
|
if (!currentClass.getClassName().equals(ownerChainName) && ownerChainName != null) {
|
||||||
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getTypedClass(ownerChainName), recipient.getName());
|
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getTypedClass(ownerChainName), recipient.getName());
|
||||||
if (matchingMethod.isPresent()) {
|
if (matchingMethod.isPresent()) {
|
||||||
type = matchingMethod.get();
|
type = matchingMethod.get();
|
||||||
@ -58,8 +59,8 @@ public class TypedMethodCall implements TypedExpression, TypedStatement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typedProgram.getCurrentClass().isCurrentMethodPresent() || typedProgram.getCurrentClass().isCurrentConstructorPresent()) {
|
if (currentClass.isCurrentMethodPresent() || currentClass.isCurrentConstructorPresent()) {
|
||||||
Optional<Type> matchingMethod = findMatchingMethod(typedProgram.getCurrentClass(), recipient.getName());
|
Optional<Type> matchingMethod = findMatchingMethod(currentClass, recipient.getName());
|
||||||
if (matchingMethod.isPresent()) {
|
if (matchingMethod.isPresent()) {
|
||||||
type = matchingMethod.get();
|
type = matchingMethod.get();
|
||||||
return type;
|
return type;
|
||||||
|
@ -35,29 +35,36 @@ public class TypedNew implements TypedExpression, TypedStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
|
||||||
if (typedProgram.isTypedClassPresent(type.getReference())) {
|
if (typedProgram.isTypedClassPresent(type.getReference())) {
|
||||||
return Type.REFERENCE(type.getReference());
|
return Type.REFERENCE(type.getReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var constructor : typedProgram.getCurrentClass().getTypedConstructors()) {
|
return findMatchingConstructorType(typedProgram, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type findMatchingConstructorType(TypedProgram typedProgram, List<TypedExpression> args) {
|
||||||
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
|
List<TypedConstructor> constructors = currentClass.getTypedConstructors();
|
||||||
|
for (var constructor : constructors) {
|
||||||
if (constructor.getTypedParameters().size() == args.size()) {
|
if (constructor.getTypedParameters().size() == args.size()) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
for (int i = 0; i < args.size(); i++) {
|
for (int i = 0; i < args.size(); i++) {
|
||||||
if (!constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(typedProgram))) {
|
boolean typeOfPara = constructor.getTypedParameters().get(i).getType().equals(args.get(i).typeCheck(typedProgram));
|
||||||
|
if (!typeOfPara) {
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
return Type.REFERENCE(typedProgram.getCurrentClass().getClassName());
|
return Type.REFERENCE(currentClass.getClassName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No matching constructor found");
|
throw new RuntimeException("No matching constructor found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void codeGen(MethodContext ctx) {
|
public void codeGen(MethodContext ctx) {
|
||||||
ctx.getMv().visitTypeInsn(Opcodes.NEW, type.getReference());
|
ctx.getMv().visitTypeInsn(Opcodes.NEW, type.getReference());
|
||||||
|
@ -47,9 +47,11 @@ public class TypedProgram {
|
|||||||
public boolean isClassWithNamePresent(String className) {
|
public boolean isClassWithNamePresent(String className) {
|
||||||
return typedClasses.stream().anyMatch(clas -> clas.getClassName().equals(className));
|
return typedClasses.stream().anyMatch(clas -> clas.getClassName().equals(className));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getTypeOfFieldNameInClass(String className, String fieldName) {
|
public Type getTypeOfFieldNameInClass(String className, String fieldName) {
|
||||||
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get().getFieldType(fieldName);
|
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get().getFieldType(fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedClass getTypedClass(String className) {
|
public TypedClass getTypedClass(String className) {
|
||||||
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get();
|
return typedClasses.stream().filter(clas -> clas.getClassName().equals(className)).findFirst().get();
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,16 @@ public class TypedReturn implements TypedStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type typeCheck(TypedProgram typedProgram) {
|
public Type typeCheck(TypedProgram typedProgram) {
|
||||||
if (typedProgram.getCurrentClass().isCurrentMethodPresent()) {
|
TypedClass currentClass = typedProgram.getCurrentClass();
|
||||||
if (typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind() != this.type.getKind()) {
|
TypedMethod currentMethod = currentClass.getCurrentMethod();
|
||||||
|
|
||||||
|
if (currentClass.isCurrentMethodPresent()) {
|
||||||
|
if (currentMethod.getReturnType().getKind() != this.type.getKind()) {
|
||||||
StringBuilder exp = new StringBuilder();
|
StringBuilder exp = new StringBuilder();
|
||||||
exp.append("\nMismatched return type: ");
|
exp.append("\nMismatched return type: ");
|
||||||
exp.append("\nExpected: ").append(typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind());
|
exp.append("\nExpected: ").append(currentMethod.getReturnType().getKind());
|
||||||
exp.append("\nActual: ").append(this.type.getKind());
|
exp.append("\nActual: ").append(this.type.getKind());
|
||||||
exp.append("\nMethod name: ").append(typedProgram.getCurrentClass().getCurrentMethod().getName());
|
exp.append("\nMethod name: ").append(currentMethod.getName());
|
||||||
throw new RuntimeException(exp.toString());
|
throw new RuntimeException(exp.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user