From a05a4c8744f277210b791273d014fc783a95680f Mon Sep 17 00:00:00 2001 From: ahmad Date: Sun, 12 May 2024 11:19:31 +0200 Subject: [PATCH] renamed and refactored --- .../typedast/Help/TypedExpressionHelp.java | 2 +- .../typedast/typedclass/TypedAssignment.java | 19 ++++---- .../typedast/typedclass/TypedBinary.java | 28 ++++++----- .../typedast/typedclass/TypedBlock.java | 24 +++++----- .../typedast/typedclass/TypedBoolLiteral.java | 5 +- .../typedast/typedclass/TypedBreak.java | 2 +- .../typedast/typedclass/TypedCharLiteral.java | 7 ++- .../typedast/typedclass/TypedClass.java | 47 +++++++++---------- .../typedast/typedclass/TypedConstructor.java | 12 +++-- ...calVariable.java => TypedDeclaration.java} | 25 +++++----- .../typedast/typedclass/TypedDoWhile.java | 5 +- .../typedast/typedclass/TypedField.java | 12 ++--- .../typedclass/TypedFieldVarAccess.java | 23 +++++---- .../maishai/typedast/typedclass/TypedFor.java | 13 +++-- .../typedast/typedclass/TypedIfElse.java | 14 ++++-- .../typedast/typedclass/TypedIntLiteral.java | 2 + .../typedast/typedclass/TypedMethod.java | 30 ++++++------ .../typedast/typedclass/TypedMethodCall.java | 6 +-- .../maishai/typedast/typedclass/TypedNew.java | 8 +--- .../typedast/typedclass/TypedParameter.java | 25 ++++++---- .../typedast/typedclass/TypedReturn.java | 9 ++-- .../typedast/typedclass/TypedUnary.java | 20 ++++---- .../typedast/typedclass/TypedWhile.java | 12 ++--- 23 files changed, 193 insertions(+), 157 deletions(-) rename src/main/java/de/maishai/typedast/typedclass/{TypedLocalVariable.java => TypedDeclaration.java} (66%) diff --git a/src/main/java/de/maishai/typedast/Help/TypedExpressionHelp.java b/src/main/java/de/maishai/typedast/Help/TypedExpressionHelp.java index 8dad9b2..368c513 100644 --- a/src/main/java/de/maishai/typedast/Help/TypedExpressionHelp.java +++ b/src/main/java/de/maishai/typedast/Help/TypedExpressionHelp.java @@ -9,7 +9,7 @@ import java.util.Map; public class TypedExpressionHelp { - public static TypedExpression getKindOfExpression(Map localVar, TypedClass clas, Expression expression) { + public static TypedExpression convertExpression(Map localVar, TypedClass clas, Expression expression) { if (expression instanceof BoolLiteral boolLiteral) { TypedBoolLiteral typedBoolLiteral = new TypedBoolLiteral(localVar, clas, boolLiteral); typedBoolLiteral.typeCheck(localVar, clas); diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java index 3c5bfa1..6960010 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedAssignment.java @@ -1,6 +1,7 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Assignment; +import de.maishai.ast.records.Expression; import de.maishai.typedast.MethodContext; import de.maishai.typedast.TypedExpression; import de.maishai.typedast.TypedStatement; @@ -11,12 +12,13 @@ import org.objectweb.asm.Opcodes; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data public class TypedAssignment implements TypedStatement { private String varName; private TypedExpression value; + // private TypedExpression recursiveOwnerChain; private Type type; public TypedAssignment(Map localVar, TypedClass clas, Assignment untyped) { @@ -25,21 +27,22 @@ public class TypedAssignment implements TypedStatement { public void convertToTypedAssignment(Map localVar, TypedClass clas, Assignment untyped) { varName = untyped.location().id(); - value = getKindOfExpression(localVar, clas, untyped.value()); + value = convertExpression(localVar, clas, untyped.value()); + // recursiveOwnerChain = convertExpression(localVar, clas, untyped.location().recursiveOwnerChain()); } @Override - public Type typeCheck(Map localVar, TypedClass clas) { + public Type typeCheck(Map localVar, TypedClass clas) { Type typeLeft = null; + if (!localVar.containsKey(varName)) { - if(clas.isThereField(varName)){ + if (clas.isThereField(varName)) { typeLeft = clas.getFieldType(varName); - }else if(clas.isParameterWitNameInMethod(varName)) { + } else if (clas.isParameterWitNameInMethod(varName)) { typeLeft = clas.getParameterTypeInCurrentMethod(varName); - }else if(clas.isParameterNameInCurrentConstructor(varName)) { + } else if (clas.isParameterNameInCurrentConstructor(varName)) { typeLeft = clas.getParameterTypeInCurrentConstructor(varName); - } - else{ + } else { throw new RuntimeException("Variable not declared"); } } else { diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java b/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java index d8b493c..e882eea 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBinary.java @@ -11,7 +11,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @NoArgsConstructor @@ -26,40 +26,44 @@ public class TypedBinary implements TypedExpression { } public void convertToTypedBinary(Map localVar, TypedClass clas, Binary unTypedBinary) { - left = getKindOfExpression(localVar, clas, unTypedBinary.left()); - right = getKindOfExpression(localVar, clas, unTypedBinary.right()); + left = convertExpression(localVar, clas, unTypedBinary.left()); + right = convertExpression(localVar, clas, unTypedBinary.right()); op = unTypedBinary.op(); } + @Override public Type typeCheck(Map localVar, TypedClass clas) { + Type leftType = left.typeCheck(localVar, clas); + Type rightType = right.typeCheck(localVar, clas); + if (op == Operator.ADD || op == Operator.SUB || op == Operator.MUL) { - if (left.typeCheck(localVar, clas) == Type.INT && - right.typeCheck(localVar, clas) == Type.INT) { + if (leftType == Type.INT && rightType == Type.INT) { type = Type.INT; return Type.INT; } else { throw new RuntimeException("Type mismatch in " + op); } - } else if (op == Operator.GT || op == Operator.LT || op == Operator.GE || op == Operator.LE || op == Operator.EQ || op == Operator.NE ) { - if (left.typeCheck(localVar, clas) == Type.INT && - right.typeCheck(localVar, clas) == Type.INT) { + } 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); } } else if (op == Operator.AND || op == Operator.OR) { - if (left.typeCheck(localVar, clas) == Type.BOOL && - right.typeCheck(localVar, clas) == Type.BOOL) { + if (leftType == Type.BOOL && rightType == Type.BOOL) { type = Type.BOOL; return Type.BOOL; } else { throw new RuntimeException("Type mismatch in " + op); } - } else { - throw new RuntimeException("Invalid operator"); } + if (leftType == rightType && leftType != Type.VOID) { + type = rightType; + return type; + } + throw new RuntimeException("Void can not be compared with Void"); } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java b/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java index 76708d1..24aee1a 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBlock.java @@ -1,7 +1,10 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.*; -import de.maishai.typedast.*; +import de.maishai.typedast.MethodContext; +import de.maishai.typedast.Type; +import de.maishai.typedast.TypedNode; +import de.maishai.typedast.TypedStatement; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -15,28 +18,28 @@ import java.util.Map; @AllArgsConstructor @Data public class TypedBlock implements TypedNode { - private List vars = new ArrayList<>(); + private List vars = new ArrayList<>(); private List stmts = new ArrayList<>(); private Type type; - public TypedBlock(Map localVar, TypedClass clas, Block unTypedBlock) { convertToTypedBlock(localVar, clas, unTypedBlock); } - public TypedBlock(List vars, List stmts) { + + public TypedBlock(List vars, List stmts) { this.vars = vars; this.stmts = stmts; } public void convertToTypedBlock(Map localVar, TypedClass clas, Block unTypedBlock) { - if(unTypedBlock == null) { + if (unTypedBlock == null) { return; } for (Declaration var : unTypedBlock.localVariables()) { - TypedLocalVariable typedVar = new TypedLocalVariable(localVar, clas, var); + TypedDeclaration typedVar = new TypedDeclaration(localVar, clas, var); vars.add(typedVar); } @@ -85,9 +88,7 @@ public class TypedBlock implements TypedNode { } if (stmt instanceof Break) { - TypedBreak typedBreak = new TypedBreak(); - typedBreak.typeCheck(localVar, clas); - stmts.add(typedBreak); + stmts.add(new TypedBreak()); continue; } @@ -104,7 +105,7 @@ public class TypedBlock implements TypedNode { @Override public Type typeCheck(Map localVar, TypedClass clas) { - for (TypedLocalVariable var : vars) { + for (TypedDeclaration var : vars) { var.typeCheck(localVar, clas); } @@ -112,12 +113,13 @@ public class TypedBlock implements TypedNode { stmt.typeCheck(localVar, clas); } + //TODO: Type von Return zurückgeben type = Type.VOID; return type; } public void codeGen(MethodVisitor mv, MethodContext ctx) { - for (TypedLocalVariable var : vars) { + for (TypedDeclaration var : vars) { //var.codeGen(mv, ctx); } for (TypedStatement stmt : stmts) { diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java index ae6a978..027a362 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBoolLiteral.java @@ -12,6 +12,7 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import java.util.Map; + @Data @NoArgsConstructor public class TypedBoolLiteral implements TypedExpression { @@ -36,9 +37,9 @@ public class TypedBoolLiteral implements TypedExpression { @Override public void codeGen(MethodVisitor mv, MethodContext ctx) { - if(value){ + if (value) { mv.visitInsn(Opcodes.ICONST_1); - }else{ + } else { mv.visitInsn(Opcodes.ICONST_0); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java b/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java index 64b6045..8e22ca0 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedBreak.java @@ -10,6 +10,7 @@ import lombok.Data; import org.objectweb.asm.MethodVisitor; import java.util.Map; + @Data public class TypedBreak implements TypedStatement { private Type type = Type.VOID; @@ -19,7 +20,6 @@ public class TypedBreak implements TypedStatement { } @Override public Type typeCheck(Map localVar, TypedClass clas) { - type = Type.VOID; return type; } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java index d4683d8..42e64c5 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedCharLiteral.java @@ -10,6 +10,7 @@ import lombok.Data; import org.objectweb.asm.MethodVisitor; import java.util.Map; + @Data public class TypedCharLiteral implements TypedExpression { private char value; @@ -18,10 +19,12 @@ public class TypedCharLiteral implements TypedExpression { public TypedCharLiteral(Map localVar, TypedClass clas, CharLiteral unTypedCharLiteral) { convertToCharLiteral(localVar, clas, unTypedCharLiteral); } + public void convertToCharLiteral(Map localVar, TypedClass clas, CharLiteral unTypedCharLiteral) { - value = unTypedCharLiteral.value(); - type = Type.CHAR; + value = unTypedCharLiteral.value(); + type = Type.CHAR; } + @Override public Type typeCheck(Map localVar, TypedClass clas) { return type; diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedClass.java b/src/main/java/de/maishai/typedast/typedclass/TypedClass.java index 832f135..060e819 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedClass.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedClass.java @@ -32,24 +32,31 @@ public class TypedClass implements TypedNode { public TypedClass(Map localVar, Class c) { convertToTypedClass(localVar, c); } + public void enterCurrentMethod(TypedMethod method) { currentMethod = method; } + public void exitCurrentMethod() { currentMethod = null; } + public void enterCurrentConstructor(TypedConstructor constructor) { currentConstructor = constructor; } + public void exitCurrentConstructor() { currentConstructor = null; } + public boolean isCurrentMethodPresent() { return currentMethod != null; } + public boolean isCurrentConstructorPresent() { return currentConstructor != null; } + public boolean isParameterNameInCurrentMethod(String parameterName) { if (currentMethod == null) { return false; @@ -61,6 +68,7 @@ public class TypedClass implements TypedNode { } return false; } + public boolean isParameterNameInCurrentConstructor(String parameterName) { if (currentConstructor == null) { return false; @@ -80,13 +88,17 @@ public class TypedClass implements TypedNode { for (Declaration field : c.fieldDeclarations()) { typedFields.add(new TypedField(localVar, this, field)); } - for (Constructor constructor : c.constructors()){ + // Am Anfang werden die Konstruktoren und Methoden in die Listen eingefügt + // Methoden können verwendet werden, bevor deren Blöcke ausgeführt werden + for (Constructor constructor : c.constructors()) { typedConstructors.add(new TypedConstructor(localVar, this, constructor)); } + for (Method method : c.methods()) { typedMethods.add(new TypedMethod(localVar, this, method)); } + // Hier werden die Blöcke der Konstruktoren und Methoden ausgeführt int i = 0; for (Constructor constructor : c.constructors()) { enterCurrentConstructor(typedConstructors.get(i)); @@ -102,25 +114,13 @@ public class TypedClass implements TypedNode { exitCurrentMethod(); j++; } + + System.out.println("TypedClass: " + this.toString()); } @Override public Type typeCheck(Map localVar, TypedClass clas) { - - if (clas == null) { - throw new RuntimeException("Class not found"); - } - - for (TypedField field : typedFields) { - field.typeCheck(localVar, clas); - } - for (TypedConstructor constructor : typedConstructors) { - constructor.typeCheck(localVar, clas); - } - for (TypedMethod typedMethod : typedMethods) { - typedMethod.typeCheck(localVar, clas); - } - return Type.REFERENCE(className); + return type; } public TypedNode startConversion(Class c) { @@ -139,6 +139,7 @@ public class TypedClass implements TypedNode { } return false; } + public boolean isParameterWitNameInConstructor(String parameterName) { for (TypedConstructor c : typedConstructors) { for (TypedParameter p : c.getTypedParameters()) { @@ -160,6 +161,7 @@ public class TypedClass implements TypedNode { } return null; } + public Type getParameterTypeInCurrentConstructor(String parameterName) { for (TypedParameter p : currentConstructor.getTypedParameters()) { if (p.getParaName().equals(parameterName)) { @@ -170,28 +172,23 @@ public class TypedClass implements TypedNode { } public boolean isThereField(String fieldName) { - for (TypedField f : typedFields) { - if (f.getVarName().equals(getFieldNameWithOutThis(fieldName))) { + if (f.getVarName().equals(fieldName)) { return true; } } return false; } - private String getFieldNameWithOutThis(String fieldName) { - if(fieldName.startsWith("this.")){ - fieldName = fieldName.substring(5); - } - return fieldName; - } + public Type getFieldType(String fieldName) { for (TypedField f : typedFields) { - if (f.getVarName().equals(getFieldNameWithOutThis(fieldName))) { + if (f.getVarName().equals(fieldName)) { return f.getType(); } } return null; } + public Type getMethodType(String methodName) { for (TypedMethod m : typedMethods) { if (m.getName().equals(methodName)) { diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java b/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java index 0634ec5..cb2c140 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedConstructor.java @@ -26,11 +26,13 @@ public class TypedConstructor implements TypedNode { private List typedParameters = new ArrayList<>(); private TypedBlock typedBlock; private Type type; + public TypedConstructor(String name, List typedParameters, TypedBlock typedBlock) { this.name = name; this.typedParameters = typedParameters; this.typedBlock = typedBlock; } + public TypedConstructor(Map localVar, TypedClass clas, Constructor unTypedConstructor) { convertToTypedConstructor(localVar, clas, unTypedConstructor); } @@ -41,16 +43,16 @@ public class TypedConstructor implements TypedNode { for (Parameter param : unTypedConstructor.params()) { typedParameters.add(new TypedParameter(localVar, clas, param)); } - // Konstrukteur hat den Rückgabetyp wie der Klassenname, obwohl es keinen expliziten Rückgabetyp gibt - type = clas.getType(); - + type = Type.VOID; } + public void convertToBlock(Map localVar, TypedClass clas, Constructor unTypedConstructor) { - this.typedBlock = new TypedBlock(localVar, clas ,unTypedConstructor.block()); + this.typedBlock = new TypedBlock(localVar, clas, unTypedConstructor.block()); } @Override public Type typeCheck(Map localVar, TypedClass clas) { + //TODO: check if return is there return type; } @@ -69,6 +71,6 @@ public class TypedConstructor implements TypedNode { mv.visitInsn(Opcodes.RETURN); - context.wrapUp(0,0); + context.wrapUp(0, 0); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java b/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java similarity index 66% rename from src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java rename to src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java index 1a8af9c..8ba500b 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedLocalVariable.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedDeclaration.java @@ -1,7 +1,6 @@ package de.maishai.typedast.typedclass; import de.maishai.ast.records.Declaration; -import de.maishai.ast.records.Node; import de.maishai.typedast.MethodContext; import de.maishai.typedast.TypedNode; import de.maishai.typedast.Type; @@ -11,32 +10,34 @@ import lombok.NoArgsConstructor; import org.objectweb.asm.MethodVisitor; import java.util.Map; + @Data @AllArgsConstructor @NoArgsConstructor -public final class TypedLocalVariable implements TypedNode { +public final class TypedDeclaration implements TypedNode { private String name; private Type type; - public TypedLocalVariable(Map localVar, TypedClass clas, Declaration declaration){ + public TypedDeclaration(Map localVar, TypedClass clas, Declaration declaration) { convertToTypedLocalVariable(localVar, clas, declaration); } - public void convertToTypedLocalVariable(Map localVar, TypedClass clas, Declaration declaration){ - if(localVar.containsKey(declaration.name())){ + + public void convertToTypedLocalVariable(Map localVar, TypedClass clas, Declaration declaration) { + if (localVar.containsKey(declaration.name())) { throw new RuntimeException("Variable " + declaration.name() + " already declared"); } - this.setName(declaration.name()); - this.setType(declaration.type()); + name = declaration.name(); + type = declaration.type(); localVar.put(this.name, this.type); } @Override public Type typeCheck(Map localVar, TypedClass clas) { - Type type = localVar.get(name); - if(type == this.type) { - return type; - } - throw new RuntimeException("type of left not equals with type of right"); + Type type = localVar.get(name); + if (type == this.type) { + return type; + } + throw new RuntimeException("type of left not equals with type of right"); } public void codeGen(MethodVisitor mv, MethodContext ctx) { diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java b/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java index d04f5fe..5590261 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedDoWhile.java @@ -7,7 +7,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data public class TypedDoWhile implements TypedStatement { @@ -18,9 +18,10 @@ public class TypedDoWhile implements TypedStatement { public TypedDoWhile(Map localVar, TypedClass clas, DoWhile unTypedDoWhile) { convertToTypedDoWhile(localVar, clas, unTypedDoWhile); } + public void convertToTypedDoWhile(Map localVar, TypedClass clas, DoWhile unTypedDoWhile) { typedBlock = new TypedBlock(localVar, clas, unTypedDoWhile.block()); - cond = getKindOfExpression(localVar, clas, unTypedDoWhile.cond()); + cond = convertExpression(localVar, clas, unTypedDoWhile.cond()); } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedField.java b/src/main/java/de/maishai/typedast/typedclass/TypedField.java index 7ff2ce0..b607f23 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedField.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedField.java @@ -21,12 +21,12 @@ public class TypedField implements TypedNode { private String varName; private Type type; - public TypedField(Map localVar, TypedClass clas, Declaration declaration){ + //TODO: remove TypedField + public TypedField(Map localVar, TypedClass clas, Declaration declaration) { convertToTypedField(localVar, clas, declaration); } - public void convertToTypedField(Map localVar, TypedClass clas, Declaration declaration){ - + public void convertToTypedField(Map localVar, TypedClass clas, Declaration declaration) { this.type = declaration.type(); varName = declaration.name(); this.typeCheck(localVar, clas); @@ -35,11 +35,11 @@ public class TypedField implements TypedNode { @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(clas.isThereField(varName)){ + if (clas.isThereField(varName)) { throw new RuntimeException("Field " + varName + " already declared"); } - if(type.getKind() == REFERENCE){ - if(!type.getReference().equals(clas.getClassName())){ + if (type.getKind() == REFERENCE) { + if (!type.getReference().equals(clas.getClassName())) { throw new RuntimeException("Field " + varName + " has wrong type"); } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java index 0b2d9fe..fa04377 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFieldVarAccess.java @@ -10,7 +10,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @NoArgsConstructor @@ -23,40 +23,43 @@ public class TypedFieldVarAccess implements TypedExpression { public TypedFieldVarAccess(Map localVar, TypedClass clas, FieldVarAccess unTypedFieldVarAccess) { convertToTypedFieldVarAccess(localVar, clas, unTypedFieldVarAccess); } + public void convertToTypedFieldVarAccess(Map localVar, TypedClass clas, FieldVarAccess unTypedFieldVarAccess) { field = unTypedFieldVarAccess.field(); - recursiveOwnerChain = getKindOfExpression(localVar, clas, unTypedFieldVarAccess.recursiveOwnerChain()); + recursiveOwnerChain = convertExpression(localVar, clas, unTypedFieldVarAccess.recursiveOwnerChain()); name = unTypedFieldVarAccess.id(); } @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(field){ + if (field) { if (clas.isThereField(name)) { type = clas.getFieldType(name); return clas.getFieldType(name); } - }else{ + } else { + if (clas.isThereField(name)) { type = clas.getFieldType(name); return clas.getFieldType(name); - }else if(clas.isCurrentConstructorPresent()){ - if(clas.isParameterNameInCurrentConstructor(name)){ + } else if (clas.isCurrentConstructorPresent()) { + if (clas.isParameterNameInCurrentConstructor(name)) { type = clas.getParameterTypeInCurrentConstructor(name); return clas.getParameterTypeInCurrentConstructor(name); } - }else if(clas.isCurrentMethodPresent()){ - if(clas.isParameterWitNameInMethod(name)){ + } else if (clas.isCurrentMethodPresent()) { + if (clas.isParameterWitNameInMethod(name)) { type = clas.getParameterTypeInCurrentMethod(name); return clas.getParameterTypeInCurrentMethod(name); } } - if(localVar.containsKey(name)) { + if (localVar.containsKey(name)) { type = localVar.get(name); return localVar.get(name); } } - throw new RuntimeException("Variable "+name+" not declared "); + + throw new RuntimeException("Variable " + name + " not declared "); } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedFor.java b/src/main/java/de/maishai/typedast/typedclass/TypedFor.java index f474b1f..0d6957c 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedFor.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedFor.java @@ -9,7 +9,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @AllArgsConstructor @@ -19,14 +19,16 @@ public class TypedFor implements TypedStatement { private TypedExpression cond; private TypedAssignment inc; private TypedBlock typedBlock; - //TODO: add Type + //TODO: type of block in for loop + private Type type; public TypedFor(Map localVar, TypedClass clas, For unTypedFor) { convertToTypedFor(localVar, clas, unTypedFor); } - public void convertToTypedFor(Map localVar,TypedClass clas, For unTypedFor) { + + public void convertToTypedFor(Map localVar, TypedClass clas, For unTypedFor) { assign = new TypedAssignment(localVar, clas, unTypedFor.assign()); - cond = getKindOfExpression(localVar, clas, unTypedFor.cond()); + cond = convertExpression(localVar, clas, unTypedFor.cond()); inc = new TypedAssignment(localVar, clas, unTypedFor.inc()); typedBlock = new TypedBlock(localVar, clas, unTypedFor.block()); } @@ -38,7 +40,8 @@ public class TypedFor implements TypedStatement { throw new RuntimeException("Condition must be a boolean"); } inc.typeCheck(localVar, clas); - return typedBlock.typeCheck(localVar, clas); + type = typedBlock.typeCheck(localVar, clas); + return type; } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java b/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java index 793c629..d17867b 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedIfElse.java @@ -10,7 +10,7 @@ import org.objectweb.asm.Opcodes; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @NoArgsConstructor @@ -19,14 +19,16 @@ public class TypedIfElse implements TypedStatement { private TypedBlock ifTypedBlock; private TypedBlock elseTypedBlock; //TODO: add Type + private Type type; public TypedIfElse(Map localVar, TypedClass clas, IfElse unTypedIfElse) { convertToTypedIfElse(localVar, clas, unTypedIfElse); } + public void convertToTypedIfElse(Map localVar, TypedClass clas, IfElse unTypedIfElse) { ifTypedBlock = new TypedBlock(localVar, clas, unTypedIfElse.ifBlock()); elseTypedBlock = new TypedBlock(localVar, clas, unTypedIfElse.elseBlock()); - typedCon = getKindOfExpression(localVar, clas, unTypedIfElse.cond()); + typedCon = convertExpression(localVar, clas, unTypedIfElse.cond()); } @Override @@ -38,7 +40,13 @@ public class TypedIfElse implements TypedStatement { if (ifTypedBlock.typeCheck(localVar, clas) != Type.VOID) { throw new RuntimeException("If block must be of type void"); } - return Type.VOID; + + //TODO: catch all cases of return when one method has a return type + if (ifTypedBlock.typeCheck(localVar, clas) == elseTypedBlock.typeCheck(localVar, clas)) { + type = ifTypedBlock.typeCheck(localVar, clas); + } + + return type; } @Override diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java b/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java index 8b19937..33bf693 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedIntLiteral.java @@ -23,6 +23,7 @@ public class TypedIntLiteral implements TypedExpression { public TypedIntLiteral(Map localVar, TypedClass clas, IntLiteral unTypedIntLiteral) { convertToTypedIntLiteral(localVar, clas, unTypedIntLiteral); } + public void convertToTypedIntLiteral(Map localVar, TypedClass clas, IntLiteral unTypedIntLiteral) { value = unTypedIntLiteral.value(); type = Type.INT; @@ -32,6 +33,7 @@ public class TypedIntLiteral implements TypedExpression { public Type typeCheck(Map localVar, TypedClass clas) { return type; } + public TypedIntLiteral(Integer value) { this.value = value; } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java index 16fa165..50fba3c 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethod.java @@ -21,33 +21,35 @@ public class TypedMethod implements TypedNode { private Type returnType; private List typedParameters = new ArrayList<>(); private TypedBlock typedBlock; + //private List localVariables = new ArrayList<>(); public TypedMethod(Map localVar, TypedClass clas, Method unTypedMethod) { convertToTypedMethod(localVar, clas, unTypedMethod); } + @Override + public boolean equals(Object obj) { + if (obj instanceof TypedMethod) { + TypedMethod other = (TypedMethod) obj; + return name.equals(other.name) && returnType.equals(other.returnType) && typedParameters.equals(other.typedParameters); + } + return false; + } + public void convertToTypedMethod(Map localVar, TypedClass clas, Method unTypedMethod) { name = unTypedMethod.methodName(); returnType = unTypedMethod.type(); - for (Parameter parameter : unTypedMethod.params()) { + for (var parameter : unTypedMethod.params()) { typedParameters.add(new TypedParameter(localVar, clas, parameter)); } - for (var method : clas.getTypedMethods()) { - if (method.getName().equals(name) && method.getTypedParameters().size() == typedParameters.size() - && method.getReturnType().equals(returnType)) { - for (int i = 0; i < method.getTypedParameters().size(); i++){ - if(method.getTypedParameters().get(i).getType().equals(typedParameters.get(i).getType())){ - throw new RuntimeException("Method " + name + " already exists"); - } - } - - if (method.getTypedParameters().isEmpty() && typedParameters.isEmpty()) { + clas.getTypedMethods().stream().filter(method -> method.equals(this)).findFirst().ifPresentOrElse( + method -> { throw new RuntimeException("Method " + name + " already exists"); - } - } - } + }, () -> { + }); + localVar.put(name, returnType); } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java b/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java index 2bae2f9..3969a2f 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedMethodCall.java @@ -10,7 +10,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.List; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @NoArgsConstructor @@ -26,13 +26,13 @@ public class TypedMethodCall implements TypedExpression, TypedStatement { public void convertToTypedMethodCall(Map localVar, TypedClass clas, MethodCall unTypedMethodCall) { recipient = new TypedFieldVarAccess(localVar, clas, unTypedMethodCall.recipient()); for (Expression arg : unTypedMethodCall.args()) { - args.add(getKindOfExpression(localVar, clas, arg)); + args.add(convertExpression(localVar, clas, arg)); } } @Override public Type typeCheck(Map localVar, TypedClass clas) { - + //TODO: implement this return null; } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedNew.java b/src/main/java/de/maishai/typedast/typedclass/TypedNew.java index 8ace078..d60509e 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedNew.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedNew.java @@ -10,7 +10,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data public class TypedNew implements TypedExpression, TypedStatement { @@ -23,16 +23,12 @@ public class TypedNew implements TypedExpression, TypedStatement { public void convertToTypedNew(Map localVar, TypedClass clas, New unTypedNew) { type = unTypedNew.type(); for (Expression arg : unTypedNew.args()) { - args.add(getKindOfExpression(localVar, clas, arg)); + args.add(convertExpression(localVar, clas, arg)); } } @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(clas == null){ - throw new RuntimeException("Class not found"); - } - for(var constructor : clas.getTypedConstructors()){ if(constructor.getTypedParameters().size() == args.size()){ boolean valid = true; diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java b/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java index 58350d4..d5fbbfb 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedParameter.java @@ -1,17 +1,14 @@ package de.maishai.typedast.typedclass; -import de.maishai.ast.records.Node; import de.maishai.ast.records.Parameter; -import de.maishai.typedast.TypedNode; import de.maishai.typedast.Type; +import de.maishai.typedast.TypedNode; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.RequiredArgsConstructor; import java.util.Map; @AllArgsConstructor -@RequiredArgsConstructor @Data public class TypedParameter implements TypedNode { private String paraName; @@ -20,22 +17,31 @@ public class TypedParameter implements TypedNode { public TypedParameter(Map localVar, TypedClass clas, Parameter unTypedParameter) { convertToTypedParameter(localVar, clas, unTypedParameter); } + public void convertToTypedParameter(Map localVar, TypedClass clas, Parameter unTypedParameter) { paraName = unTypedParameter.name(); type = unTypedParameter.type(); - //localVar.put(paraName, type); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TypedParameter) { + TypedParameter other = (TypedParameter) obj; + return paraName.equals(other.paraName) && type.equals(other.type); + } + return false; } @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(clas.isCurrentMethodPresent()){ - if(clas.isParameterWitNameInMethod(paraName)) { + if (clas.isCurrentMethodPresent()) { + if (clas.isParameterWitNameInMethod(paraName)) { throw new RuntimeException("Parameter " + paraName + " already exists"); } - }else if(clas.isCurrentConstructorPresent()){ - if(clas.isParameterWitNameInConstructor(paraName)) { + } else if (clas.isCurrentConstructorPresent()) { + if (clas.isParameterWitNameInConstructor(paraName)) { throw new RuntimeException("Parameter " + paraName + " already exists"); } } @@ -44,5 +50,4 @@ public class TypedParameter implements TypedNode { } - } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java b/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java index e960d99..053c3e5 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedReturn.java @@ -10,7 +10,7 @@ import org.objectweb.asm.Opcodes; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data @NoArgsConstructor @@ -21,15 +21,16 @@ public class TypedReturn implements TypedStatement { public TypedReturn(Map localVar, TypedClass clas, Return unTypedReturn) { convertToTypedReturn(localVar, clas, unTypedReturn); } + public void convertToTypedReturn(Map localVar, TypedClass clas, Return unTypedReturn) { - ret = getKindOfExpression(localVar, clas, unTypedReturn.ret()); + ret = convertExpression(localVar, clas, unTypedReturn.ret()); type = ret.getType(); } @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(clas.isCurrentMethodPresent()){ - if(clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()){ + if (clas.isCurrentMethodPresent()) { + if (clas.getCurrentMethod().getReturnType().getKind() != this.type.getKind()) { StringBuilder exp = new StringBuilder(); exp.append("\nMismatched return type: "); exp.append("\nExpected: ").append(clas.getCurrentMethod().getReturnType().getKind()); diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java b/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java index 4f82630..f69d043 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedUnary.java @@ -11,7 +11,7 @@ import org.objectweb.asm.Opcodes; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data public class TypedUnary implements TypedExpression { @@ -19,25 +19,27 @@ public class TypedUnary implements TypedExpression { private TypedExpression right; private Type type; - public TypedUnary(Map localVar, TypedClass clas, Unary unTypedUnary){ + public TypedUnary(Map localVar, TypedClass clas, Unary unTypedUnary) { convertToTypedUnary(localVar, clas, unTypedUnary); } + public void convertToTypedUnary(Map localVar, TypedClass clas, Unary unTypedUnary) { op = unTypedUnary.op(); - right = getKindOfExpression(localVar, clas, unTypedUnary.right()); + right = convertExpression(localVar, clas, unTypedUnary.right()); } + @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(op == UnaryOperator.NOT){ - if(right.typeCheck(localVar, clas) != Type.BOOL){ + if (op == UnaryOperator.NOT) { + if (right.typeCheck(localVar, clas) != Type.BOOL) { throw new RuntimeException("Not operator must be applied to boolean"); } return Type.BOOL; } - if(op == UnaryOperator.SUB){ - if(right.typeCheck(localVar, clas) != Type.INT){ + if (op == UnaryOperator.SUB) { + if (right.typeCheck(localVar, clas) != Type.INT) { throw new RuntimeException("Minus operator must be applied to int"); } return Type.INT; @@ -48,11 +50,11 @@ public class TypedUnary implements TypedExpression { @Override public void codeGen(MethodVisitor mv, MethodContext ctx) { right.codeGen(mv, ctx); - if(op == UnaryOperator.NOT){ + if (op == UnaryOperator.NOT) { mv.visitInsn(Opcodes.ICONST_1); mv.visitInsn(Opcodes.IXOR); } - if(op == UnaryOperator.SUB){ + if (op == UnaryOperator.SUB) { mv.visitInsn(Opcodes.INEG); } } diff --git a/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java b/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java index 291445d..4fcd915 100644 --- a/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java +++ b/src/main/java/de/maishai/typedast/typedclass/TypedWhile.java @@ -7,7 +7,7 @@ import org.objectweb.asm.MethodVisitor; import java.util.Map; -import static de.maishai.typedast.Help.TypedExpressionHelp.getKindOfExpression; +import static de.maishai.typedast.Help.TypedExpressionHelp.convertExpression; @Data public class TypedWhile implements TypedStatement { @@ -20,17 +20,17 @@ public class TypedWhile implements TypedStatement { } public void convertToTypedWhile(Map localVar, TypedClass clas, While unTypedWhile) { - cond = getKindOfExpression(localVar, clas, unTypedWhile.cond()); + cond = convertExpression(localVar, clas, unTypedWhile.cond()); typedBlock = new TypedBlock(localVar, clas, unTypedWhile.block()); } + @Override public Type typeCheck(Map localVar, TypedClass clas) { - if(cond.typeCheck(localVar, clas) != Type.BOOL){ + if (cond.typeCheck(localVar, clas) != Type.BOOL) { throw new RuntimeException("While condition must be a boolean"); } - typedBlock.typeCheck(localVar, clas); - this.type = Type.VOID; - return Type.BOOL; + type = typedBlock.typeCheck(localVar, clas); + return type; }