diff --git a/src/main/java/de/maishai/typedast/ExceptionHandler/TypeOfReturnNotMatchException.java b/src/main/java/de/maishai/typedast/ExceptionHandler/TypeOfReturnNotMatchException.java new file mode 100644 index 0000000..64c93dc --- /dev/null +++ b/src/main/java/de/maishai/typedast/ExceptionHandler/TypeOfReturnNotMatchException.java @@ -0,0 +1,17 @@ +package de.maishai.typedast.ExceptionHandler; + +import de.maishai.typedast.Type; + +public class TypeOfReturnNotMatchException extends RuntimeException{ + + public TypeOfReturnNotMatchException(String excepted, String actual, String name){ + super("Mismatched return type: " + + " Expected: " + excepted + + " Actual: " + actual + + " Method name: " + name + ); + } + public TypeOfReturnNotMatchException(String name){ + super("Constructor " + name + " must not have a return"); + } +} diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java index 8576a84..bf6d42a 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java @@ -1,6 +1,8 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Assignment; +import de.maishai.typedast.ExceptionHandler.TypeMismatchException; +import de.maishai.typedast.ExceptionHandler.VariableNotDeclaredException; import de.maishai.typedast.MethodContext; import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedStatement; @@ -35,11 +37,15 @@ public class TypedAssignment implements TypedStatement { Type typeLeft = getTypeLeft(typedProgram); Type typeRight = value.typeCheck(typedProgram); - if (typeLeft.equals(typeRight)) { - type = typeLeft; - return typeLeft; + // so because of the collection of exceptions + if(typeLeft != null && typeRight != null){ + if (typeLeft.equals(typeRight)) { + type = typeLeft; + return typeLeft; + } } - throw new RuntimeException("type of left not equals with type of right"); + TypedProgram.addException("Type Not Match", new TypeMismatchException(typeRight.getKind().toString())); + return Type.VOID; } private Type getTypeLeft(TypedProgram typedProgram) { @@ -58,7 +64,8 @@ public class TypedAssignment implements TypedStatement { return getTypeFromConstructorOrField(currentClass.getCurrentConstructor(), name, currentClass); } - throw new RuntimeException("Variable " + name + " not declared"); + TypedProgram.addException(name, new VariableNotDeclaredException(name)); + return null; } private Type getTypeFromMethodOrField(TypedMethod currentMethod, String name, TypedClass currentClass) { @@ -67,7 +74,8 @@ public class TypedAssignment implements TypedStatement { } else if (currentClass.isThereField(name)) { return currentClass.getFieldType(name); } else { - throw new RuntimeException("Variable " + name + " not declared in method"); + TypedProgram.addException(name, new VariableNotDeclaredException(name)); + return null; } } @@ -77,7 +85,8 @@ public class TypedAssignment implements TypedStatement { } else if (currentClass.isThereField(name)) { return currentClass.getFieldType(name); } else { - throw new RuntimeException("Variable " + name + " not declared in constructor"); + TypedProgram.addException(name, new VariableNotDeclaredException(name)); + return null; } } @@ -99,14 +108,14 @@ public class TypedAssignment implements TypedStatement { receiver = location.getRecursiveOwnerChain().getType().getReference(); } ctx.getMv().visitFieldInsn(Opcodes.PUTFIELD, receiver, location.getName(), value.getType().getDescriptor()); - System.out.println("PUTFIELD: " + receiver + " " + location.getName() + " " + value.getType().getDescriptor()); + // System.out.println("PUTFIELD: " + receiver + " " + location.getName() + " " + value.getType().getDescriptor()); ctx.popStack(); } else { if(value.getType().getKind() == Type.Kind.REFERENCE) { - System.out.println("ASTORE " + ctx.getLocalVar(location.getName()).get().index()); + //System.out.println("ASTORE " + ctx.getLocalVar(location.getName()).get().index()); ctx.getMv().visitVarInsn(Opcodes.ASTORE, ctx.getLocalVar(location.getName()).get().index()); } else { - System.out.println("ISTORE " + ctx.getLocalVar(location.getName()).get().index()); + // System.out.println("ISTORE " + ctx.getLocalVar(location.getName()).get().index()); ctx.getMv().visitVarInsn(Opcodes.ISTORE, ctx.getLocalVar(location.getName()).get().index()); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java b/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java index 30171b2..fd8ef95 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java @@ -2,6 +2,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.Operator; import de.maishai.ast.records.Binary; +import de.maishai.typedast.ExceptionHandler.TypeMismatchException; import de.maishai.typedast.MethodContext; import de.maishai.typedast.TypedExpression; import de.maishai.typedast.Type; @@ -9,11 +10,8 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import java.util.Map; - import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @@ -46,21 +44,24 @@ public class TypedBinary implements TypedExpression { type = Type.INT; return Type.INT; } else { - throw new RuntimeException("Type mismatch in " + op); + TypedProgram.addException(op.name(), new TypeMismatchException(op.toString())); + return null; } } else if (op == Operator.GT || op == Operator.LT || op == Operator.GE || op == Operator.LE) { if (leftType == Type.INT && rightType == Type.INT) { type = Type.BOOL; return Type.BOOL; } else { - throw new RuntimeException("Type mismatch in " + op); + TypedProgram.addException(op.name(), new TypeMismatchException(op.toString())); + return null; } } else if (op == Operator.AND || op == Operator.OR) { if (leftType == Type.BOOL && rightType == Type.BOOL) { type = Type.BOOL; return Type.BOOL; } else { - throw new RuntimeException("Type mismatch in " + op); + TypedProgram.addException(op.name(), new TypeMismatchException(op.toString())); + return null; } } @@ -68,7 +69,8 @@ public class TypedBinary implements TypedExpression { type = rightType; return type; } - throw new RuntimeException("Void can not be compared with Void"); + TypedProgram.addException("Void", new RuntimeException("Void can not be compared with Void")); + return null; } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java b/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java index 873866d..dd10bcf 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java @@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Constructor; import de.maishai.ast.records.Parameter; import de.maishai.typedast.*; +import de.maishai.typedast.ExceptionHandler.ParameterAlreadyExistsException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -63,7 +64,7 @@ public class TypedConstructor implements TypedNode { public void checkIfParameterExists(String paraName) { if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(paraName))) { - throw new RuntimeException("Parameter " + paraName + " already exists"); + TypedProgram.addException(paraName, new ParameterAlreadyExistsException(paraName)); } } @@ -79,7 +80,8 @@ public class TypedConstructor implements TypedNode { public Type typeCheck(TypedProgram typedProgram) { type = typedBlock.typeCheck(typedProgram); if (type != Type.VOID) { - throw new RuntimeException("Constructor must not habe a return statement"); + TypedProgram.addException("ConstructorContainsReturn",new RuntimeException("Constructor must not habe a return statement")); + return null; } return type; @@ -89,13 +91,13 @@ public class TypedConstructor implements TypedNode { public void codeGen(ClassContext ctx) { int accessModifier = Opcodes.ACC_PUBLIC; // ist laut Andi ok MethodVisitor mv = ctx.getCw().visitMethod(accessModifier, "", CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), Type.VOID), null, null); - System.out.println("Visiting method: " + "" + CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), Type.VOID)); + //System.out.println("Visiting method: " + "" + CodeGenUtils.generateDescriptor(typedParameters.stream().map(TypedParameter::getType).toList(), Type.VOID)); MethodContext mctx = new MethodContext(ctx, mv); typedParameters.forEach(param -> mctx.registerVariable(param.getParaName(), param.getType())); //super(); mctx.pushStack("this"); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); - System.out.println("INVOKESPECIAL: " + "java/lang/Object" + " " + "" + " " + "()V"); + //System.out.println("INVOKESPECIAL: " + "java/lang/Object" + " " + "" + " " + "()V"); mctx.popStack(); typedBlock.codeGen(mctx); diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java b/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java index d653b54..5096f88 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java @@ -1,6 +1,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Declaration; +import de.maishai.typedast.ExceptionHandler.FieldAlreadyDeclaredException; import de.maishai.typedast.TypedNode; import de.maishai.typedast.Type; import lombok.AllArgsConstructor; @@ -31,11 +32,13 @@ public final class TypedDeclaration implements TypedNode { public Type typeCheck(TypedProgram typedProgram) { if (type.getReference() != null && !typedProgram.getCurrentClass().getClassName().equals(type.getReference())) { if (!typedProgram.isTypedClassPresent(type.getReference())) { - throw new RuntimeException("Type " + type.getReference() + " not found"); + TypedProgram.addException(type.getReference(), new RuntimeException("Type " + type.getReference() + " not found")); + return null; } } if (typedProgram.getCurrentClass().isThereField(name)) { - throw new RuntimeException("Field " + name + " already declared"); + TypedProgram.addException(name, new FieldAlreadyDeclaredException(name)); + return null; } return type; } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java b/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java index 31294eb..b5725cf 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java @@ -29,7 +29,8 @@ public class TypedDoWhile implements TypedStatement { @Override public Type typeCheck(TypedProgram typedProgram) { if (cond.typeCheck(typedProgram) != Type.BOOL) { - throw new RuntimeException("Condition must be boolean"); + TypedProgram.addException("ConditionError", new RuntimeException("Condition must be boolean")); + return null; } typedBlock.typeCheck(typedProgram); this.type = Type.VOID; diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java index 123a982..ac52494 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java @@ -1,17 +1,15 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.*; +import de.maishai.typedast.ExceptionHandler.VariableNotDeclaredException; 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.MethodVisitor; import org.objectweb.asm.Opcodes; -import java.util.Map; - import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @@ -56,7 +54,8 @@ public class TypedFieldVarAccess implements TypedExpression { type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); return type; } else { - throw new RuntimeException("Field " + name + " not declared"); + TypedProgram.addException(name,new RuntimeException("Field " + name + " not declared") ); + return null; } } @@ -66,7 +65,8 @@ public class TypedFieldVarAccess implements TypedExpression { } else if (typedProgram.getCurrentClass().isCurrentMethodPresent()) { return checkMethodVariableType(typedProgram); } else { - throw new RuntimeException("Variable " + name + " not declared"); + TypedProgram.addException(name, new VariableNotDeclaredException(name)); + return null; } } @@ -100,7 +100,7 @@ public class TypedFieldVarAccess implements TypedExpression { } else if (recursiveOwnerChain instanceof TypedFieldVarAccess typedFieldVarAccess) { type = typedProgram.getCurrentClass().getFieldType(typedFieldVarAccess.getName()); } else { - throw new RuntimeException("Variable " + name + " not declared"); + TypedProgram.addException(name, new VariableNotDeclaredException(name)); } return type; } @@ -130,7 +130,7 @@ public class TypedFieldVarAccess implements TypedExpression { } else { int loadOpcode = type.getKind() == Type.Kind.REFERENCE ? Opcodes.ALOAD : Opcodes.ILOAD; ctx.getMv().visitVarInsn(loadOpcode, ctx.getLocalVar(name).get().index()); - System.out.println(loadOpcode == Opcodes.ALOAD ? "ALOAD " + ctx.getLocalVar(name).get().index() : "ILOAD " + ctx.getLocalVar(name).get().index()); + //System.out.println(loadOpcode == Opcodes.ALOAD ? "ALOAD " + ctx.getLocalVar(name).get().index() : "ILOAD " + ctx.getLocalVar(name).get().index()); } ctx.pushAnonToStack(); } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFor.java b/src/main/java/de/maishai/typedast/typedclass/TypedFor.java index 406f6b2..73c203a 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFor.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFor.java @@ -36,7 +36,8 @@ public class TypedFor implements TypedStatement { public Type typeCheck(TypedProgram typedProgram) { assign.typeCheck(typedProgram); if (!cond.typeCheck(typedProgram).equals(Type.BOOL)) { - throw new RuntimeException("Condition must be a boolean"); + TypedProgram.addException("ConditionError", new RuntimeException("Condition must be boolean")); + return null; } inc.typeCheck(typedProgram); type = typedBlock.typeCheck(typedProgram); diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java index 08ec98c..c5d76ca 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java @@ -7,11 +7,8 @@ import de.maishai.typedast.Type; import lombok.AllArgsConstructor; import lombok.Data; import lombok.RequiredArgsConstructor; -import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import java.util.Map; - @Data @AllArgsConstructor @RequiredArgsConstructor @@ -43,13 +40,13 @@ public class TypedIntLiteral implements TypedExpression { public void codeGen(MethodContext ctx) { if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { ctx.getMv().visitIntInsn(Opcodes.BIPUSH, value); - System.out.println("BIPUSH " + value); + // System.out.println("BIPUSH " + value); } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { ctx.getMv().visitIntInsn(Opcodes.SIPUSH, value); - System.out.println("SIPUSH " + value); + // System.out.println("SIPUSH " + value); } else { ctx.getMv().visitLdcInsn(value); - System.out.println("LDC " + value); + // System.out.println("LDC " + value); } ctx.pushInstantToStack(); } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java b/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java index ad73cbf..7d7ce8e 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java @@ -1,6 +1,8 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Declaration; +import de.maishai.typedast.ExceptionHandler.LocalVariableAlreadDeclaredException; +import de.maishai.typedast.ExceptionHandler.NotFoundMethodOrConstructor; import de.maishai.typedast.MethodContext; import de.maishai.typedast.TypedNode; import de.maishai.typedast.Type; @@ -30,19 +32,22 @@ public final class TypedLocalVariable implements TypedNode { public Type typeCheck(TypedProgram typedProgram) { if (typedProgram.getCurrentClass().isCurrentMethodPresent() && !typedProgram.getCurrentClass().isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().getCurrentMethod().isLocalVariableInMethod(name)) { - throw new RuntimeException("Variable " + name + " already declared"); + TypedProgram.addException(name, new LocalVariableAlreadDeclaredException(name)); + return null; } typedProgram.getCurrentClass().getCurrentMethod().getLocalVariables().add(this); return type; } if (!typedProgram.getCurrentClass().isCurrentMethodPresent() && typedProgram.getCurrentClass().isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().getCurrentConstructor().isLocalVariableInConstructor(name)) { - throw new RuntimeException("Variable " + name + " already declared"); + TypedProgram.addException(name, new LocalVariableAlreadDeclaredException(name)); + return null; } typedProgram.getCurrentClass().getCurrentConstructor().getLocalVariables().add(this); return type; } - throw new RuntimeException("not found method or constructor in class"); + TypedProgram.addException("NotFoundMethodOrConstructor", new NotFoundMethodOrConstructor()); + return null; } public void codeGen(MethodVisitor mv, MethodContext ctx) { diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java index 3acbf7f..4ee8e3a 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java @@ -2,6 +2,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Method; import de.maishai.typedast.*; +import de.maishai.typedast.ExceptionHandler.ParameterAlreadyExistsException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -38,14 +39,14 @@ public class TypedMethod implements TypedNode { typedProgram.getCurrentClass().getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse( method -> { - throw new RuntimeException("Method " + name + " already exists"); + TypedProgram.addException(name, new RuntimeException("Method " + name + " already exists")); }, () -> { }); } public void checkIfParameterExists(String parameterName) { if (typedParameters.stream().anyMatch(parameter -> parameter.getParaName().equals(parameterName))) { - throw new RuntimeException("Parameter " + parameterName + " already exists"); + TypedProgram.addException(parameterName, new ParameterAlreadyExistsException(parameterName)); } } @@ -101,9 +102,11 @@ public class TypedMethod implements TypedNode { if (returnType != Type.VOID && !hasEvenReturnsInIfElseBlocks()) { if (typedBlock.typeCheck(typedProgram).getKind() != returnType.getKind()) { if (hasEvenReturnsInIfElseBlocks()) { - throw new RuntimeException("Method " + name + " must have even returns in if else blocks"); + TypedProgram.addException(name, new RuntimeException("Method " + name + " must have even returns in if else blocks")); + return null; } else { - throw new RuntimeException("Method " + name + " must return " + returnType.getKind()); + TypedProgram.addException(name, new RuntimeException("Method " + name + " must return " + returnType.getKind())); + return null; } } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java index e6ea8a6..f0157f8 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java @@ -59,7 +59,8 @@ public class TypedMethodCall implements TypedExpression, TypedStatement { } } - throw new RuntimeException("Method not found"); + TypedProgram.addException("MethodNotFound", new RuntimeException("Method not found") ); + return null; } public Optional findMatchingMethod(TypedClass ownerChain, String methodName) { @@ -99,7 +100,7 @@ public class TypedMethodCall implements TypedExpression, TypedStatement { methodOwnerClass = recipient.getRecursiveOwnerChain().getType().getReference(); } ctx.getMv().visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodOwnerClass, recipient.getName(), descriptor, false); - System.out.println("INVOKEVIRTUAL " + methodOwnerClass + " " + recipient.getName() + " " + descriptor); + //System.out.println("INVOKEVIRTUAL " + methodOwnerClass + " " + recipient.getName() + " " + descriptor); ctx.popStack(); // pop the owner for (TypedExpression arg : args) { ctx.popStack(); diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedNew.java b/src/main/java/de/maishai/typedast/typedclass/TypedNew.java index 8442f31..281d2d6 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedNew.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedNew.java @@ -3,9 +3,9 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Expression; import de.maishai.ast.records.New; import de.maishai.typedast.*; +import de.maishai.typedast.ExceptionHandler.NotMatchConstructorException; import lombok.AllArgsConstructor; import lombok.Data; -import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import java.util.ArrayList; @@ -52,17 +52,18 @@ public class TypedNew implements TypedExpression, TypedStatement { } } } - throw new RuntimeException("No matching constructor found"); + TypedProgram.addException("notMatchConstructor", new NotMatchConstructorException()); + return null; } @Override public void codeGen(MethodContext ctx) { ctx.getMv().visitTypeInsn(Opcodes.NEW, type.getReference()); - System.out.println("NEW " + type.getReference()); + //System.out.println("NEW " + type.getReference()); ctx.pushAnonToStack(); ctx.getMv().visitInsn(Opcodes.DUP); - System.out.println("DUP"); + // System.out.println("DUP"); ctx.pushAnonToStack(); for (TypedExpression arg : args) { arg.codeGen(ctx); @@ -71,6 +72,6 @@ public class TypedNew implements TypedExpression, TypedStatement { for (TypedExpression arg : args) { ctx.popStack(); } - System.out.println("INVOKESPECIAL " + type.getReference() + " " + CodeGenUtils.generateDescriptor(args.stream().map(TypedExpression::getType).toList(), Type.VOID)); + //System.out.println("INVOKESPECIAL " + type.getReference() + " " + CodeGenUtils.generateDescriptor(args.stream().map(TypedExpression::getType).toList(), Type.VOID)); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java b/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java index 6cc752a..e7ad1f2 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java @@ -1,6 +1,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Parameter; +import de.maishai.typedast.ExceptionHandler.ParameterAlreadyExistsException; import de.maishai.typedast.Type; import de.maishai.typedast.TypedNode; import lombok.AllArgsConstructor; @@ -36,11 +37,13 @@ public class TypedParameter implements TypedNode { if (typedProgram.getCurrentClass().isCurrentMethodPresent()) { if (typedProgram.getCurrentClass().isParameterWitNameInMethod(paraName)) { - throw new RuntimeException("Parameter " + paraName + " already exists"); + TypedProgram.addException(paraName, new ParameterAlreadyExistsException(paraName)); + return null; } } else if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) { if (typedProgram.getCurrentClass().isParameterWitNameInConstructor(paraName)) { - throw new RuntimeException("Parameter " + paraName + " already exists"); + TypedProgram.addException(paraName, new ParameterAlreadyExistsException(paraName)); + return null; } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedProgram.java b/src/main/java/de/maishai/typedast/typedclass/TypedProgram.java index d30440b..728898a 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedProgram.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedProgram.java @@ -5,12 +5,15 @@ import lombok.AllArgsConstructor; import lombok.Getter; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Getter @AllArgsConstructor public class TypedProgram { private List typedClasses = new ArrayList<>(); + public static Map EXCEPTIONS = new HashMap<>(); private TypedClass currentClass; public TypedProgram(Program program) { @@ -41,6 +44,21 @@ public class TypedProgram { exitCurrentClass(); i++; } + + if(EXCEPTIONS.isEmpty()){ + System.out.println("Es wurde erfolgreich kompiliert."); + }else{ + System.out.println("Es wurden insgesamt " + EXCEPTIONS.size() + " Fehlern gefunden:"); + int counter = 0; + for(Map.Entry entry : EXCEPTIONS.entrySet()){ + System.out.println("["+ counter + "] Fehler: " + + "\n Schlüssel: " + entry.getKey() + + "\n Exception: " + entry.getValue().getClass().getSimpleName() + + "\n Message: " + entry.getValue().getMessage() + ); + counter++; + } + } } public TypedClass getTypedClass(String className) { @@ -59,6 +77,12 @@ public class TypedProgram { currentClass = null; } + public static void addException(String name, Exception ex){ + if(!EXCEPTIONS.containsKey(name)){ + EXCEPTIONS.put(name, ex); + } + } + @Override public boolean equals(Object obj) { if (this == obj) return true; @@ -69,7 +93,7 @@ public class TypedProgram { || currentClass.equals(other.currentClass))) { return true; } else { - System.out.println("TypedPrograms are not equal:\n" + this.typedClasses + "\n" + other.typedClasses + "\n"); + //System.out.println("TypedPrograms are not equal:\n" + this.typedClasses + "\n" + other.typedClasses + "\n"); return false; } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java b/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java index 5d33978..85e3f3d 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java @@ -3,6 +3,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.*; import de.maishai.typedast.*; +import de.maishai.typedast.ExceptionHandler.TypeOfReturnNotMatchException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -35,12 +36,17 @@ public class TypedReturn implements TypedStatement { public Type typeCheck(TypedProgram typedProgram) { if (typedProgram.getCurrentClass().isCurrentMethodPresent()) { if (typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind() != this.type.getKind()) { - StringBuilder exp = new StringBuilder(); - exp.append("\nMismatched return type: "); - exp.append("\nExpected: ").append(typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind()); - exp.append("\nActual: ").append(this.type.getKind()); - exp.append("\nMethod name: ").append(typedProgram.getCurrentClass().getCurrentMethod().getName()); - throw new RuntimeException(exp.toString()); + String key = "Type of return in " + typedProgram.getCurrentClass().getCurrentMethod().getName(); + TypeOfReturnNotMatchException ex = new TypeOfReturnNotMatchException( + typedProgram.getCurrentClass().getCurrentMethod().getReturnType().getKind().name(), + this.type.getKind().name(), + typedProgram.getCurrentClass().getCurrentMethod().getName()); + TypedProgram.addException(key, ex); + } + } + if (typedProgram.getCurrentClass().isCurrentConstructorPresent()) { + if (typedProgram.getCurrentClass().getCurrentConstructor().getType().getKind() != this.type.getKind()) { + TypedProgram.addException(typedProgram.getCurrentClass().getCurrentConstructor().getName(), new TypeOfReturnNotMatchException(typedProgram.getCurrentClass().getCurrentConstructor().getName())); } } return type; @@ -50,15 +56,15 @@ public class TypedReturn implements TypedStatement { public void codeGen(MethodContext ctx) { if (ret == null) { ctx.getMv().visitInsn(Opcodes.RETURN); - System.out.println("RETURN"); + //System.out.println("RETURN"); } else { ret.codeGen(ctx); if (ret.getType().getKind() != Type.Kind.REFERENCE) { ctx.getMv().visitInsn(Opcodes.IRETURN); - System.out.println("IRETURN"); + // System.out.println("IRETURN"); } else { ctx.getMv().visitInsn(Opcodes.ARETURN); - System.out.println("ARETURN"); + // System.out.println("ARETURN"); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java b/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java index 152aa79..6d5c348 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java @@ -31,18 +31,21 @@ public class TypedUnary implements TypedExpression { if (op == UnaryOperator.NOT) { if (right.typeCheck(typedProgram) != Type.BOOL) { - throw new RuntimeException("Not operator must be applied to boolean"); + TypedProgram.addException(UnaryOperator.NOT.name(), new RuntimeException("Not operator must be applied to boolean")); + return null; } return Type.BOOL; } if (op == UnaryOperator.SUB) { if (right.typeCheck(typedProgram) != Type.INT) { - throw new RuntimeException("Minus operator must be applied to int"); + TypedProgram.addException(UnaryOperator.SUB.name(),new RuntimeException("Minus operator must be applied to int") ); + return null; } return Type.INT; } - throw new RuntimeException("Unknown unary operator"); + TypedProgram.addException("UnknownUnary",new RuntimeException("Unknown unary operator") ); + return null; } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java b/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java index 8119725..1b34bf9 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java @@ -28,7 +28,8 @@ public class TypedWhile implements TypedStatement { @Override public Type typeCheck(TypedProgram typedProgram) { if (cond.typeCheck(typedProgram) != Type.BOOL) { - throw new RuntimeException("While condition must be a boolean"); + TypedProgram.addException("ConditionError",new RuntimeException("While condition must be a boolean") ); + return null; } type = typedBlock.typeCheck(typedProgram); return type;