Refactored typedAST

This commit is contained in:
ahmad 2024-06-30 20:34:29 +02:00
parent ae3280fb67
commit b4fd003f8e
17 changed files with 166 additions and 111 deletions

View File

@ -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");
} }
@ -74,7 +74,7 @@ public class TypedAssignment implements TypedStatement {
if (currentMethod.isLocalVariableInMethod(name)) { if (currentMethod.isLocalVariableInMethod(name)) {
return currentMethod.getLocalVariableType(name); return currentMethod.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) { } else if (currentClass.isThereField(name)) {
throw new RuntimeException("Field Variable "+ name + " should be used with `this´"); throw new RuntimeException("Field Variable " + name + " should be used with `this´");
} else { } else {
throw new RuntimeException("Variable " + name + " not declared in method"); throw new RuntimeException("Variable " + name + " not declared in method");
} }
@ -84,7 +84,7 @@ public class TypedAssignment implements TypedStatement {
if (currentConstructor.isLocalVariableInConstructor(name)) { if (currentConstructor.isLocalVariableInConstructor(name)) {
return currentConstructor.getLocalVariableType(name); return currentConstructor.getLocalVariableType(name);
} else if (currentClass.isThereField(name)) { } else if (currentClass.isThereField(name)) {
throw new RuntimeException("Field Variable "+ name+ " should be used with `this´"); throw new RuntimeException("Field Variable " + name + " should be used with `this´");
} else { } else {
throw new RuntimeException("Variable " + name + " not declared in constructor"); throw new RuntimeException("Variable " + name + " not declared in constructor");
} }
@ -92,7 +92,7 @@ public class TypedAssignment implements TypedStatement {
@Override @Override
public void codeGen(MethodContext ctx) { public void codeGen(MethodContext ctx) {
if(value instanceof TypedMethodCall) { if (value instanceof TypedMethodCall) {
value.codeGen(ctx); value.codeGen(ctx);
getOwnerChain(ctx); getOwnerChain(ctx);
} else { } else {
@ -116,7 +116,7 @@ public class TypedAssignment implements TypedStatement {
return; return;
} }
MethodContext.LocalVariable localVariable = localVariableOptional.get(); MethodContext.LocalVariable localVariable = localVariableOptional.get();
if(value.getType().getKind() == Type.Kind.REFERENCE) { if (value.getType().getKind() == Type.Kind.REFERENCE) {
LOGGER.finest("ASTORE " + localVariable.index()); LOGGER.finest("ASTORE " + localVariable.index());
ctx.getMv().visitVarInsn(Opcodes.ASTORE, localVariable.index()); ctx.getMv().visitVarInsn(Opcodes.ASTORE, localVariable.index());
} else { } else {

View File

@ -52,8 +52,8 @@ public class TypedBinary implements TypedExpression {
} else { } else {
throw new RuntimeException("Type mismatch in " + op); throw new RuntimeException("Type mismatch in " + op);
} }
} else if(op == Operator.EQ || op == Operator.NE || op == Operator.AND || op == Operator.OR){ } else if (op == Operator.EQ || op == Operator.NE || op == Operator.AND || op == Operator.OR) {
if(leftType == Type.INT && rightType == Type.INT || leftType == Type.BOOL && rightType == Type.BOOL){ if (leftType == Type.INT && rightType == Type.INT || leftType == Type.BOOL && rightType == Type.BOOL) {
type = Type.BOOL; type = Type.BOOL;
return Type.BOOL; return Type.BOOL;
} else { } else {

View File

@ -97,16 +97,20 @@ public class TypedBlock implements TypedNode {
return type; return type;
} }
private void clearLocalVariable(TypedProgram typedProgram){ private void clearLocalVariable(TypedProgram typedProgram) {
for(var typedLocalVariable : vars){ TypedClass typedClass = typedProgram.getCurrentClass();
if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) { TypedMethod typedMethod = typedClass.getCurrentMethod();
if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(typedLocalVariable.getName())) { TypedConstructor typedConstructor = typedClass.getCurrentConstructor();
typedProgram.getCurrentClass().getCurrentMethod().deleteLocalVariableInMethod(typedLocalVariable.getName());
for (var typedLocalVariable : vars) {
if (typedClass.isCurrentMethodPresent() && !typedClass.isCurrentConstructorPresent()) {
if (typedMethod.isLocalVariableInMethod(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());
} }
} }
} }

View File

@ -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);
} }

View File

@ -13,7 +13,7 @@ public class TypedCharLiteral implements TypedExpression {
private char value; private char value;
private Type type; private Type type;
public TypedCharLiteral( CharLiteral unTypedCharLiteral) { public TypedCharLiteral(CharLiteral unTypedCharLiteral) {
convertToCharLiteral(unTypedCharLiteral); convertToCharLiteral(unTypedCharLiteral);
} }

View File

@ -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;
@ -36,7 +37,7 @@ public class TypedClass implements TypedNode {
isMainCurrentMethod = false; isMainCurrentMethod = false;
} }
public TypedClass(String className,List<TypedDeclaration> typedDeclarations, List<TypedMethod> typedMethods, List<TypedConstructor> typedConstructors, TypedMain typedMain, TypedMethod currentMethod, TypedConstructor currentConstructor, Type type) { public TypedClass(String className, List<TypedDeclaration> typedDeclarations, List<TypedMethod> typedMethods, List<TypedConstructor> typedConstructors, TypedMain typedMain, TypedMethod currentMethod, TypedConstructor currentConstructor, Type type) {
this.className = className; this.className = className;
this.typedDeclarations = typedDeclarations; this.typedDeclarations = typedDeclarations;
this.typedMethods = typedMethods; this.typedMethods = typedMethods;
@ -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;
} }

View File

@ -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;

View File

@ -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;

View File

@ -48,22 +48,24 @@ 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;
}else{ } else {
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) {

View File

@ -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);
} }

View File

@ -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");

View File

@ -15,14 +15,14 @@ public class TypedMain implements TypedNode {
private Type type = Type.VOID; private Type type = Type.VOID;
private TypedMethod typedMethod; private TypedMethod typedMethod;
public TypedMain(){ public TypedMain() {
typedMethod = new TypedMethod(); typedMethod = new TypedMethod();
typedMethod.setName("main"); typedMethod.setName("main");
typedMethod.setReturnType(type); typedMethod.setReturnType(type);
typedMethod.setTypedParameters(List.of(new TypedParameter("args", Type.REFERENCE("String[]")))); typedMethod.setTypedParameters(List.of(new TypedParameter("args", Type.REFERENCE("String[]"))));
} }
public void convertToTypedMethod(TypedProgram typedProgram, Class unTypedClass){ public void convertToTypedMethod(TypedProgram typedProgram, Class unTypedClass) {
typedMethod.setTypedBlock(new TypedBlock(typedProgram, unTypedClass.mainmeth())); typedMethod.setTypedBlock(new TypedBlock(typedProgram, unTypedClass.mainmeth()));
} }

View File

@ -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);
@ -67,9 +69,10 @@ public class TypedMethod implements TypedNode {
return isLocalVariablePresent(localVarName) || isParameterPresent(localVarName); return isLocalVariablePresent(localVarName) || isParameterPresent(localVarName);
} }
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();
} }

View File

@ -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;

View File

@ -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());

View File

@ -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();
} }
@ -71,7 +73,7 @@ public class TypedProgram {
if (this == obj) return true; if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false; if (obj == null || getClass() != obj.getClass()) return false;
TypedProgram other = (TypedProgram) obj; TypedProgram other = (TypedProgram) obj;
if(typedClasses.equals(other.typedClasses) && if (typedClasses.equals(other.typedClasses) &&
(currentClass == null && other.currentClass == null (currentClass == null && other.currentClass == null
|| currentClass.equals(other.currentClass))) { || currentClass.equals(other.currentClass))) {
return true; return true;

View File

@ -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());
} }
} }