diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java index 16143fd..6a5e40d 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java @@ -29,31 +29,8 @@ public class TypedAssignment implements TypedStatement { @Override public Type typeCheck(TypedProgram typedProgram) { - Type typeLeft = null; - - if (typedProgram.getCurrentClass().isThereField(location.getName()) && location.getField()) { - typeLeft = typedProgram.getCurrentClass().getFieldType(location.getName()); - } else { - if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) { - if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(location.getName())) { - typeLeft = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(location.getName()); - } else if(typedProgram.getCurrentClass().isThereField(location.getName())){ - typeLeft = typedProgram.getCurrentClass().getFieldType(location.getName()); - }else { - throw new RuntimeException("Variable " + location.getName() + " not declared in method"); - } - } - if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) { - if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(location.getName())) { - typeLeft = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(location.getName()); - }else if(typedProgram.getCurrentClass().isThereField(location.getName())){ - typeLeft = typedProgram.getCurrentClass().getFieldType(location.getName()); - }else { - throw new RuntimeException("Variable " + location.getName() + " not declared in constructor"); - } - } - } + Type typeLeft = getTypeLeft(typedProgram); Type typeRight = value.typeCheck(typedProgram); if (typeLeft.equals(typeRight)) { @@ -63,6 +40,45 @@ public class TypedAssignment implements TypedStatement { throw new RuntimeException("type of left not equals with type of right"); } + private Type getTypeLeft(TypedProgram typedProgram) { + String name = location.getName(); + TypedClass currentClass = typedProgram.getCurrentClass(); + + if (currentClass.isThereField(name) && location.getField()) { + return currentClass.getFieldType(name); + } + + if (currentClass.isCurrentMethodPresent() && !currentClass.isCurrentConstructorPresent()) { + return getTypeFromMethodOrField(currentClass.getCurrentMethod(), name, currentClass); + } + + if (!currentClass.isCurrentMethodPresent() && currentClass.isCurrentConstructorPresent()) { + return getTypeFromConstructorOrField(currentClass.getCurrentConstructor(), name, currentClass); + } + + throw new RuntimeException("Variable " + name + " not declared"); + } + + private Type getTypeFromMethodOrField(TypedMethod currentMethod, String name, TypedClass currentClass) { + if (currentMethod.isLocalVariableInMethod(name)) { + return currentMethod.getLocalVariableType(name); + } else if (currentClass.isThereField(name)) { + return currentClass.getFieldType(name); + } else { + throw new RuntimeException("Variable " + name + " not declared in method"); + } + } + + private Type getTypeFromConstructorOrField(TypedConstructor currentConstructor, String name, TypedClass currentClass) { + if (currentConstructor.isLocalVariableInConstructor(name)) { + return currentConstructor.getLocalVariableType(name); + } else if (currentClass.isThereField(name)) { + return currentClass.getFieldType(name); + } else { + throw new RuntimeException("Variable " + name + " not declared in constructor"); + } + } + @Override public void codeGen(MethodContext ctx) { if (value instanceof TypedIntLiteral) { diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java b/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java index 587df2d..34f5691 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java @@ -34,12 +34,9 @@ public final class TypedDeclaration implements TypedNode { throw new RuntimeException("Type " + type.getReference() + " not found"); } } - if (typedProgram.getCurrentClass().isThereField(name)) { throw new RuntimeException("Field " + name + " already declared"); } - - return type; } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java index d7d5b36..a575e85 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java @@ -32,55 +32,66 @@ public class TypedFieldVarAccess implements TypedExpression { @Override public Type typeCheck(TypedProgram typedProgram) { if (field) { - if (typedProgram.getCurrentClass().isThereField(name)) { - type = typedProgram.getCurrentClass().getFieldType(name); - return type; - }else if(recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess){ - type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); - return type; - }else{ - throw new RuntimeException("Field " + name + " not declared "); - } + type = checkFieldType(typedProgram); + return type; } else { - if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) { - if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) { - type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name); - return type; - } else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) { - type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name); - return type; - } else if(typedProgram.getCurrentClass().isThereField(name)){ - type = typedProgram.getCurrentClass().getFieldType(name); - return type; - } else if(recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess){ - type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); - return type; - } - else { - throw new RuntimeException("Variable " + name + " not declared in constructor"); - } - - } else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) { - if (typedProgram.getCurrentClass().isParameterWitNameInMethod(name)) { - type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name); - return type; - } else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) { - type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name); - return type; - } else if(typedProgram.getCurrentClass().isThereField(name)){ - type = typedProgram.getCurrentClass().getFieldType(name); - return type; - } else if(recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess){ - type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); - return type; - } - else { - throw new RuntimeException("Variable " + name + " not declared in method"); - } - } - throw new RuntimeException("Variable " + name + " not declared "); + type = checkVariableType(typedProgram); + return type; } } + private Type checkFieldType(TypedProgram typedProgram) { + if (typedProgram.getCurrentClass().isThereField(name)) { + type = typedProgram.getCurrentClass().getFieldType(name); + return type; + } else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) { + type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); + return type; + } else { + throw new RuntimeException("Field " + name + " not declared"); + } + } + private Type checkVariableType(TypedProgram typedProgram) { + if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) { + return checkConstructorVariableType(typedProgram); + } else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) { + return checkMethodVariableType(typedProgram); + } else { + throw new RuntimeException("Variable " + name + " not declared"); + } + } + + private Type checkConstructorVariableType(TypedProgram typedProgram) { + if (typedProgram.getCurrentClass().isParameterNameInCurrentConstructor(name)) { + type = typedProgram.getCurrentClass().getParameterTypeInCurrentConstructor(name); + } else if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariablePresent(name)) { + type = typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariableType(name); + } else { + return checkFieldOrRecursiveType(typedProgram); + } + return type; + } + + private Type checkMethodVariableType(TypedProgram typedProgram) { + if (typedProgram.getCurrentClass().isParameterWitNameInMethod(name)) { + type = typedProgram.getCurrentClass().getParameterTypeInCurrentMethod(name); + } else if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariablePresent(name)) { + type = typedProgram.getCurrentClass().getCurrentMethod().getLocalVariableType(name); + } else { + return checkFieldOrRecursiveType(typedProgram); + } + return type; + } + + private Type checkFieldOrRecursiveType(TypedProgram typedProgram) { + if (typedProgram.getCurrentClass().isThereField(name)) { + type = typedProgram.getCurrentClass().getFieldType(name); + } else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) { + type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); + } else { + throw new RuntimeException("Variable " + name + " not declared"); + } + return type; + } @Override public void codeGen(MethodContext ctx) {