diff --git a/src/main/java/Compiler.java b/src/main/java/Compiler.java index a771ca9..0a0ff90 100644 --- a/src/main/java/Compiler.java +++ b/src/main/java/Compiler.java @@ -79,40 +79,6 @@ public class Compiler { System.out.println(refType.name); } -// -// List fieldDecls = new ArrayList<>(); -// -// FieldDecl fieldDecl = new FieldDecl("int", "i"); -// fieldDecls.add(fieldDecl); -// -//// FieldDecl fieldDecl2 = new FieldDecl("char", "i"); -//// fieldDecls.add(fieldDecl2); -// -// List methodDecls = new ArrayList<>(); -// -// -// MethodDecl methodDecl = new MethodDecl("ClassA", "int", "m", new ParameterList(new ArrayList<>()), new BlockStatement(new ArrayList<>(), "void")); -// methodDecls.add(methodDecl); -// -//// MethodDecl methodDecl2 = new MethodDecl("ClassA", "int", "m", new ArrayList<>(), new ArrayList<>()); -//// methodDecls.add(methodDecl2); -// -// abstractSyntaxTree.classes.add(new RefType("MyClass", fieldDecls, methodDecls, false)); -// -// System.out.println("Parsed " + abstractSyntaxTree.classes.size() + " classes with identifiers/names:"); -// for (RefType refType : abstractSyntaxTree.classes) { -// System.out.println(refType.name); -// } - - - IfElseStatement c = (IfElseStatement) abstractSyntaxTree.classes.get(0).methodDecls.get(0).codeBlock.statements.get(2); - InstVarExpression d = (InstVarExpression) c.condition; - d.classRef = abstractSyntaxTree.classes.get(0); - - - AssignStatementExpression a = (AssignStatementExpression) abstractSyntaxTree.classes.get(0).methodDecls.get(0).codeBlock.statements.get(1); - InstVarExpression b = (InstVarExpression) a.left; - b.classRef = abstractSyntaxTree.classes.get(0); abstractSyntaxTree.typeCheck(); abstractSyntaxTree.codeGen(); diff --git a/src/main/java/Input.java b/src/main/java/Input.java index 44ddefc..52fd8ff 100644 --- a/src/main/java/Input.java +++ b/src/main/java/Input.java @@ -1,15 +1,24 @@ -class Example { +class Example1 { int i; boolean b; char c; int m(int n){ - int localA; - this.b = true; - if(this.b){ + Example e = new Example(); + e.m(1); + return 0; + } +} + +class Example { + int i; + boolean b; + char c; + int m(int a){ + int localA = 0; + boolean localB = true; + if(localB){ localA = 7; - }else{ - localA = 5; - } + }else{} return localA; } -} \ No newline at end of file +} diff --git a/src/main/java/TypeCheck/TypeCheckException.java b/src/main/java/TypeCheck/TypeCheckException.java new file mode 100644 index 0000000..bf66d5e --- /dev/null +++ b/src/main/java/TypeCheck/TypeCheckException.java @@ -0,0 +1,7 @@ +package TypeCheck; + +public class TypeCheckException extends Exception { + public TypeCheckException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/TypeCheck/TypeCheckHelper.java b/src/main/java/TypeCheck/TypeCheckHelper.java index f31555d..6e7542a 100644 --- a/src/main/java/TypeCheck/TypeCheckHelper.java +++ b/src/main/java/TypeCheck/TypeCheckHelper.java @@ -4,23 +4,19 @@ import java.util.List; import java.util.Objects; public class TypeCheckHelper { - public String upperBound(String type1, String type2) throws Exception{ - if(Objects.equals(type1, "boolean")) - type1 = "bool"; - if (Objects.equals(type2, "boolean")) - type2 = "bool"; - boolean type1Primitiv = Objects.equals(type1, "bool") || Objects.equals(type1, "int") || Objects.equals(type1, "char"); - boolean type2Primitiv = Objects.equals(type2, "bool") || Objects.equals(type2, "int") || Objects.equals(type2, "char"); + public String upperBound(String type1, String type2) throws TypeCheckException{ + boolean type1Primitiv = Objects.equals(type1, "boolean") || Objects.equals(type1, "int") || Objects.equals(type1, "char"); + boolean type2Primitiv = Objects.equals(type2, "boolean") || Objects.equals(type2, "int") || Objects.equals(type2, "char"); String result; if(type1Primitiv && type2Primitiv){ if(Objects.equals(type1, type2)){ result = type1; }else{ - throw new Exception("no upper bound"); + throw new TypeCheckException("There is no upper bound."); } }else if(type1Primitiv || type2Primitiv){ - throw new Exception("no upper bound"); + throw new TypeCheckException("There is no upper bound."); }else{ result = "class"; } diff --git a/src/main/java/abstractSyntaxTree/Class/FieldDecl.java b/src/main/java/abstractSyntaxTree/Class/FieldDecl.java index 56416a5..1213e5e 100644 --- a/src/main/java/abstractSyntaxTree/Class/FieldDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/FieldDecl.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Class; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Node; @@ -23,7 +24,7 @@ public class FieldDecl extends AbstractType implements Node { this.type = type; this.identifier = identifier; } - public TypeCheckResult typeCheck(HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap> typeContext) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); diff --git a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java index 384d8a1..d528767 100644 --- a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Class; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Node; import abstractSyntaxTree.Parameter.Parameter; @@ -33,7 +34,7 @@ public class MethodDecl implements Node { this.localVars = new LinkedHashMap<>(); } - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext) throws TypeCheckException { // jede methode als block statement aufrufen und jede neue locale varibale in localvars schreiben List parametersList = parameters.parameterList; for(Parameter parameter : parametersList){ @@ -43,7 +44,7 @@ public class MethodDecl implements Node { TypeCheckResult result = new TypeCheckResult(); String CodeBlockType = codeBlock.typeCheck(methodContext, typeContext, localVars).type; if(!Objects.equals(this.returnType, CodeBlockType)) - throw new Exception("TypeCheck Exception: Method retruns wrong type"); + throw new TypeCheckException("Method returns " + CodeBlockType + ", but should retrun " + this.returnType + ". "); result.type = codeBlock.returnType; return result; } diff --git a/src/main/java/abstractSyntaxTree/Class/RefType.java b/src/main/java/abstractSyntaxTree/Class/RefType.java index 4ce323a..4c255bc 100644 --- a/src/main/java/abstractSyntaxTree/Class/RefType.java +++ b/src/main/java/abstractSyntaxTree/Class/RefType.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Class; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Node; @@ -34,14 +35,14 @@ public class RefType extends AbstractType implements Node { } public TypeCheckResult typeCheck(HashMap>> methodContext, - HashMap> typeContext) throws Exception { + HashMap> typeContext) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); // check if field with the same identifier is defined more than once List discoveredFieldIdentifiers = new ArrayList<>(); for (FieldDecl fieldDecl : fieldDecls) { if(discoveredFieldIdentifiers.contains(fieldDecl.identifier)){ - throw new Exception("A field with the identifier " + fieldDecl.identifier + " was defined more than once in the same class."); + throw new TypeCheckException("A field with the identifier " + fieldDecl.identifier + " was defined more than once in the class " + this.name + ". "); } discoveredFieldIdentifiers.add(fieldDecl.identifier); } @@ -58,7 +59,7 @@ public class RefType extends AbstractType implements Node { if (discoveredMethods.containsKey(methodDecl.returnType)) { if(discoveredMethods.get(methodDecl.returnType).equals(methodDecl.name)){ - throw new Exception("A method with the name " + methodDecl.name + " and return type " + methodDecl.returnType + " was defined more than once in the same class."); + throw new TypeCheckException("A method with the name " + methodDecl.name + " and return type " + methodDecl.returnType + " was defined more than once in the same class."); } } discoveredMethods.put(methodDecl.returnType, methodDecl.name); diff --git a/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java index 03d7f06..1ed7d5f 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/BoolDatatype.java @@ -17,10 +17,10 @@ public class BoolDatatype extends AbstractType implements IDatatype{ return (Objects.equals(value, boolDatatype.value)); } @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck() { TypeCheckResult result = new TypeCheckResult(); - result.type = "bool"; + result.type = "boolean"; setTypeCheckResult(result); return result; diff --git a/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java index a1aa152..92e74be 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/CharDatatype.java @@ -10,7 +10,7 @@ public class CharDatatype extends AbstractType implements IDatatype{ char value; @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck() { TypeCheckResult result = new TypeCheckResult(); result.type = "char"; diff --git a/src/main/java/abstractSyntaxTree/Datatype/IDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/IDatatype.java index 9f57666..f0ef832 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/IDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/IDatatype.java @@ -1,11 +1,12 @@ package abstractSyntaxTree.Datatype; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import org.objectweb.asm.MethodVisitor; public interface IDatatype { // typeCheck method - TypeCheckResult typeCheck() throws Exception; + TypeCheckResult typeCheck() throws TypeCheckException; // visit method for code generation diff --git a/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java b/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java index 17e58c1..b1576aa 100644 --- a/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java +++ b/src/main/java/abstractSyntaxTree/Datatype/IntDatatype.java @@ -10,7 +10,7 @@ import java.util.Objects; public class IntDatatype extends AbstractType implements IDatatype{ int value; @Override - public TypeCheckResult typeCheck() throws Exception { + public TypeCheckResult typeCheck() { TypeCheckResult result = new TypeCheckResult(); result.type = "int"; @@ -19,9 +19,6 @@ public class IntDatatype extends AbstractType implements IDatatype{ return result; } - // visit method for code generation - - @Override public void codeGen(MethodVisitor mv) throws Exception { diff --git a/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java index 25b5b14..4cec259 100644 --- a/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/BinaryExpression.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Expression; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckHelper; import TypeCheck.AbstractType; @@ -24,7 +25,7 @@ public class BinaryExpression extends AbstractType implements IExpression{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckHelper helper = new TypeCheckHelper(); TypeCheckResult result = new TypeCheckResult(); @@ -163,7 +164,7 @@ public class BinaryExpression extends AbstractType implements IExpression{ break; default: - throw new Exception("Unknown operator: " + operator); + throw new TypeCheckException("The operator " + operator + " is not known."); } mv.visitLabel(operationFalse); diff --git a/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java index c7ec132..ffc7198 100644 --- a/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/BooleanConstantExpression.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Expression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Parameter.ParameterList; import org.objectweb.asm.MethodVisitor; @@ -16,9 +17,9 @@ public class BooleanConstantExpression extends AbstractType implements IExpressi } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) { TypeCheckResult result = new TypeCheckResult(); - result.type = "bool"; + result.type = "boolean"; setTypeCheckResult(result); return result; } diff --git a/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java index e3a6430..ecc0b4f 100644 --- a/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/CharConstantExpression.java @@ -16,7 +16,7 @@ public class CharConstantExpression extends AbstractType implements IExpression{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) { TypeCheckResult result = new TypeCheckResult(); result.type = "char"; setTypeCheckResult(result); diff --git a/src/main/java/abstractSyntaxTree/Expression/IExpression.java b/src/main/java/abstractSyntaxTree/Expression/IExpression.java index db3db58..958a6de 100644 --- a/src/main/java/abstractSyntaxTree/Expression/IExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/IExpression.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Expression; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Node; import abstractSyntaxTree.Parameter.ParameterList; @@ -11,7 +12,7 @@ import java.util.LinkedHashMap; public interface IExpression extends Node { // typeCheck method //TypeCheckResult typeCheck() throws Exception; - TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception; + TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException; // visit method for code generation void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception; diff --git a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java index 8e47168..9e3e115 100644 --- a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Expression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Parameter.ParameterList; @@ -30,10 +31,11 @@ public class InstVarExpression extends AbstractType implements IExpression{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - - //todo /////////////////// + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { String varType = typeContext.get(classRef.name).get(fieldName); + if (varType == null) { + throw new TypeCheckException("Field " + fieldName + " was not found in class " + classRef.name + "."); + } TypeCheckResult result = new TypeCheckResult(); result.type = varType; return result; diff --git a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java index 3665fd2..c10e36c 100644 --- a/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/IntConstantExpression.java @@ -18,7 +18,7 @@ public class IntConstantExpression extends AbstractType implements IExpression{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) { TypeCheckResult result = new TypeCheckResult(); result.type = "int"; setTypeCheckResult(result); diff --git a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index 5065969..69c115f 100644 --- a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Expression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import org.objectweb.asm.*; @@ -25,12 +26,12 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); if (localVars.containsKey(identifier)) { result.type = localVars.get(identifier); } else { - throw new Exception("TypeCheck Exception: Local var " + identifier + " does not exist."); + throw new TypeCheckException("Local var " + identifier + " does not exist."); } setTypeCheckResult(result); return result; diff --git a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java index 5be81e7..741e673 100644 --- a/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/UnaryExpression.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Expression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Datatype.IDatatype; @@ -20,7 +21,7 @@ public class UnaryExpression extends AbstractType implements IExpression{ this.operand = operand; } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); TypeCheckResult operandTypeCheckResult = operand.typeCheck(); diff --git a/src/main/java/abstractSyntaxTree/Program.java b/src/main/java/abstractSyntaxTree/Program.java index 0c330ce..9512434 100644 --- a/src/main/java/abstractSyntaxTree/Program.java +++ b/src/main/java/abstractSyntaxTree/Program.java @@ -1,5 +1,6 @@ package abstractSyntaxTree; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.FieldDecl; import abstractSyntaxTree.Class.MethodDecl; @@ -27,7 +28,7 @@ public class Program implements Node { } - public TypeCheckResult typeCheck() throws Exception{ + public TypeCheckResult typeCheck() throws TypeCheckException { this.typeContext = new HashMap<>(); this.methodContext = new HashMap<>(); diff --git a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java index 5459b52..af76b02 100644 --- a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Statement; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Class.FieldDecl; @@ -28,7 +29,7 @@ public class BlockStatement extends AbstractType implements IStatement { @Override public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, - HashMap localVars) throws Exception { + HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); this.localVars = localVars; @@ -54,10 +55,10 @@ public class BlockStatement extends AbstractType implements IStatement { if (!firstType.equals(this.returnType) || !firstType.equals(this.returnType)) { if (!firstType.equals("void") && this.returnType != null) { - throw new Exception("TypeCheck Exception: if paths return wrong type"); + throw new TypeCheckException("The if-Path returns the wrong type."); } if (!secondType.equals("void") && this.returnType != null) { - throw new Exception("TypeCheck Exception: else paths return wrong type"); + throw new TypeCheckException("The else-path returns the wrong type."); } boolean firstIsVoid = firstType.equals("void"); @@ -78,11 +79,9 @@ public class BlockStatement extends AbstractType implements IStatement { this.returnType = typeOfCurrentStatement.type; if (!typeOfCurrentStatement.type.equals(this.returnType)) - throw new Exception("TypeCheck Exception: Block returns the wrong type."); + throw new TypeCheckException("At least some statements of the block returns the wrong type or missing return statement."); } result.type = this.returnType; - // todo check if the block returns the needed return type in every case - // todo ignore unreachable statements? setTypeCheckResult(result); return result; } diff --git a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java index f5c4e43..5a91eef 100644 --- a/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/EmptyStatement.java @@ -13,7 +13,7 @@ import java.util.Objects; public class EmptyStatement extends AbstractType implements IStatement{ @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) { TypeCheckResult result = new TypeCheckResult(); result.type = "void"; return result; diff --git a/src/main/java/abstractSyntaxTree/Statement/IStatement.java b/src/main/java/abstractSyntaxTree/Statement/IStatement.java index 7e5c2b6..a270b60 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IStatement.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Statement; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Node; import abstractSyntaxTree.Parameter.ParameterList; @@ -11,7 +12,7 @@ import java.util.List; public interface IStatement extends Node { - TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception; + TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException; void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext) throws Exception; TypeCheckResult getTypeCheckResult(); diff --git a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java index 41fb152..d34270e 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfElseStatement.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Statement; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; @@ -24,13 +25,13 @@ public class IfElseStatement extends AbstractType implements IStatement{ @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars); if (!conditionType.type.equals("boolean")) { - throw new IllegalArgumentException("should be boolean"); + throw new TypeCheckException("The condition of a if statement is " + conditionType.type + ", but should be boolean."); } TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars); @@ -38,7 +39,7 @@ public class IfElseStatement extends AbstractType implements IStatement{ if (!ifStatementType.type.equals(elseStatementType.type)) { if(ifStatementType.type != "void" && elseStatementType.type != "void") - throw new IllegalArgumentException("TypeCeck Exception: if and else have different types"); + throw new TypeCheckException("If- and else-path return different not-void types."); } result.type = ifStatementType.type + "," + elseStatementType.type; diff --git a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java index 7938a9b..c54fe62 100644 --- a/src/main/java/abstractSyntaxTree/Statement/IfStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/IfStatement.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Statement; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; @@ -23,13 +24,13 @@ public class IfStatement extends AbstractType implements IStatement{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars); - if (!conditionType.equals("bool")) { - throw new Exception("TypeCheck Exception: Condition of If-Statement should be bool."); + if (!conditionType.type.equals("boolean")) { + throw new TypeCheckException("Condition of If-Statement should is " + conditionType.type + ", but should be boolean."); } TypeCheckResult ifStatementType = ifStatement.typeCheck(methodContext, typeContext, localVars); diff --git a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java index 21553de..7a444f0 100644 --- a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java +++ b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.Statement; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Parameter.ParameterList; @@ -17,7 +18,7 @@ public class LocalVarDecl extends AbstractType implements IStatement{ this.identifier = identifier; } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckHelper.typeExists(this.type, new ArrayList<>(methodContext.keySet())); localVars.put(this.identifier, this.type); diff --git a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java index c255aee..f6dfd8c 100644 --- a/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/ReturnStatement.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Statement; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; @@ -19,7 +20,7 @@ public class ReturnStatement extends AbstractType implements IStatement{ } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); if (expression == null) { @@ -45,7 +46,7 @@ public class ReturnStatement extends AbstractType implements IStatement{ //TODO: Resolve how do we get the type of the expression String type = expression.getTypeCheckResult().type; - if (type.equals("int") || type.equals("bool") || type.equals("char")) { + if (type.equals("int") || type.equals("boolean") || type.equals("char")) { mv.visitInsn(Opcodes.IRETURN); } else { mv.visitInsn(Opcodes.ARETURN); diff --git a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java index 23ef3bf..e063cdd 100644 --- a/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/WhileStatement.java @@ -1,5 +1,6 @@ package abstractSyntaxTree.Statement; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import TypeCheck.AbstractType; import abstractSyntaxTree.Expression.IExpression; @@ -21,12 +22,12 @@ public class WhileStatement extends AbstractType implements IStatement { } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); // check condition TypeCheckResult conditionType = condition.typeCheck(methodContext, typeContext, localVars); - if (!conditionType.equals("bool")) { + if (!conditionType.type.equals("boolean")) { throw new IllegalArgumentException("Expected boolean"); } diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java index 6d5cbd8..eb31a57 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.StatementExpression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; @@ -28,7 +29,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckHelper helper = new TypeCheckHelper(); TypeCheckResult result = new TypeCheckResult(); @@ -48,7 +49,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi if(Objects.equals(leftType.type, "boolean")) leftType.type = "bool"; if (!Objects.equals(upperbound, leftType.type)) { - throw new Exception("TypeCheck Exception: upper bound of assignment is not left type"); + throw new TypeCheckException("The upper bound of assignment is not the left type."); } result.type = "void"; setTypeCheckResult(result); diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index 4fa060c..93845ac 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -1,12 +1,14 @@ package abstractSyntaxTree.StatementExpression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Statement.IStatement; +import jdk.jshell.spi.ExecutionControl; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -28,7 +30,8 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr this.arguments = arguments; } - public TypeCheckResult typeCheck() throws Exception { + @Override + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { TypeCheckResult result = new TypeCheckResult(); RefType searchMethodHere; @@ -41,18 +44,12 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr List methods = searchMethodHere.methodDecls; if(!methods.contains(methodName)){ - throw new Exception("method not found"); + throw new TypeCheckException("The method " + methodName + " is called, but does not exist."); } return result; } - - @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { - return null; - } - //Errors occur due to the change in parameter in the RefType class // I need the methodContext here to get the method descriptor @Override diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java index af9fbe7..3beba9b 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/NewStatementExpression.java @@ -1,6 +1,7 @@ package abstractSyntaxTree.StatementExpression; import TypeCheck.AbstractType; +import TypeCheck.TypeCheckException; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; @@ -26,14 +27,16 @@ public class NewStatementExpression extends AbstractType implements IExpression, } @Override - public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws Exception { + public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { + //todo testen wenn in ast vorhanden if(!TypeCheckHelper.typeExists(className, new ArrayList<>(typeContext.keySet()))){ - throw new Exception("TypeCheck Exception: An instance of " + className + " is created, but the type does not exist."); + throw new TypeCheckException("An instance of " + className + " is created, but the type does not exist."); } TypeCheckResult result = new TypeCheckResult(); result.type = className; setTypeCheckResult(result); return result; + } @Override diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/Receiver.java b/src/main/java/abstractSyntaxTree/StatementExpression/Receiver.java index 589c169..f670456 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/Receiver.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/Receiver.java @@ -1,7 +1,16 @@ package abstractSyntaxTree.StatementExpression; +import TypeCheck.TypeCheckException; +import TypeCheck.TypeCheckResult; +import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.InstVarExpression; import abstractSyntaxTree.Node; +import abstractSyntaxTree.Parameter.ParameterList; +import abstractSyntaxTree.Statement.IStatement; +import org.objectweb.asm.MethodVisitor; + +import java.util.HashMap; +import java.util.LinkedHashMap; public class Receiver implements Node { boolean thisExpression; @@ -24,6 +33,7 @@ public class Receiver implements Node { public Receiver(String identifier) { this.identifier = identifier; } + }