From 2a2e14ae21fc9c111f7af7e8be747b4c3a5d05d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krau=C3=9F=2C=20Josefine?= Date: Wed, 26 Jun 2024 15:38:46 +0200 Subject: [PATCH] methodcall --- src/main/java/Compiler.java | 2 +- src/main/java/Input.java | 19 +++--- .../Expression/InstVarExpression.java | 17 +++-- .../Expression/SubReceiver.java | 4 +- src/main/java/abstractSyntaxTree/Program.java | 4 +- .../Statement/BlockStatement.java | 3 + .../Statement/LocalVarDecl.java | 7 ++ .../AssignStatementExpression.java | 6 +- .../MethodCallStatementExpression.java | 66 +++++++++++-------- .../StatementExpression/ReceivingMethod.java | 12 +++- 10 files changed, 86 insertions(+), 54 deletions(-) diff --git a/src/main/java/Compiler.java b/src/main/java/Compiler.java index 599c4cf..fb2f6d9 100644 --- a/src/main/java/Compiler.java +++ b/src/main/java/Compiler.java @@ -71,6 +71,6 @@ public class Compiler { abstractSyntaxTree.typeCheck(); - //abstractSyntaxTree.codeGen(); + abstractSyntaxTree.codeGen(); } } diff --git a/src/main/java/Input.java b/src/main/java/Input.java index 20d6133..b9ae3c2 100644 --- a/src/main/java/Input.java +++ b/src/main/java/Input.java @@ -3,22 +3,25 @@ class Example1 { int a = 12345; Example e; public Example1(){i = 3456;} - int m(int n){ - boolean b123; - int x; - x = -3; - int i = 5; + int meth(int n){ Example e = new Example(); - e.m(1); + int abc = e.example1.m1(2).m2().m3(); + return 0; } + Example m1(int n){ + return new Example(); + } } class Example { int i; boolean b; char c; - int m(int a){ - return 0; + Example1 example1; + Example1 m(int a){ + return new Example1(); } + Example m2(){return new Example();} + int m3(){return 1;} } diff --git a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java index 9e3e115..eefab82 100644 --- a/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java +++ b/src/main/java/abstractSyntaxTree/Expression/InstVarExpression.java @@ -18,9 +18,8 @@ import java.util.Objects; public class InstVarExpression extends AbstractType implements IExpression{ - public RefType classRef; - - public List receivers; ; + public String thisClass; + public List receivers; public List receivingMethods; public String fieldName; @@ -32,9 +31,9 @@ public class InstVarExpression extends AbstractType implements IExpression{ @Override public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { - String varType = typeContext.get(classRef.name).get(fieldName); + String varType = typeContext.get(thisClass).get(fieldName); if (varType == null) { - throw new TypeCheckException("Field " + fieldName + " was not found in class " + classRef.name + "."); + throw new TypeCheckException("Field " + fieldName + " was not found in class " + thisClass + "."); } TypeCheckResult result = new TypeCheckResult(); result.type = varType; @@ -48,7 +47,7 @@ public class InstVarExpression extends AbstractType implements IExpression{ mv.visitVarInsn(Opcodes.ALOAD, 0); //Get the field information - String fieldType = typeContext.get(classRef.name).get(fieldName); + String fieldType = typeContext.get(thisClass).get(fieldName); StringBuilder descriptor = new StringBuilder(); @@ -64,7 +63,7 @@ public class InstVarExpression extends AbstractType implements IExpression{ descriptor.append("C"); break; default: - String fullReturnType = typeContext.get(classRef.name).get(fieldName); + String fullReturnType = typeContext.get(thisClass).get(fieldName); // If it is a class reference replace the "." with "/" and return it if (fieldType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/"); @@ -73,7 +72,7 @@ public class InstVarExpression extends AbstractType implements IExpression{ } // Load the variable onto the stack - mv.visitFieldInsn(Opcodes.GETFIELD, classRef.name, fieldName, descriptor.toString()); + mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, fieldName, descriptor.toString()); } @Override @@ -81,7 +80,7 @@ public class InstVarExpression extends AbstractType implements IExpression{ if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; InstVarExpression instVarExpression = (InstVarExpression) o; - return (Objects.equals(classRef, instVarExpression.classRef) + return (Objects.equals(thisClass, instVarExpression.thisClass) && Objects.equals(fieldName, instVarExpression.fieldName) ); } diff --git a/src/main/java/abstractSyntaxTree/Expression/SubReceiver.java b/src/main/java/abstractSyntaxTree/Expression/SubReceiver.java index cfbce8a..a00f187 100644 --- a/src/main/java/abstractSyntaxTree/Expression/SubReceiver.java +++ b/src/main/java/abstractSyntaxTree/Expression/SubReceiver.java @@ -5,8 +5,8 @@ import abstractSyntaxTree.StatementExpression.NewStatementExpression; public class SubReceiver implements Node { boolean thisExpression; - NewStatementExpression newStatementExpression; - String identifier; + public NewStatementExpression newStatementExpression; + public String identifier; public SubReceiver(boolean thisExpression) { this.thisExpression = thisExpression; diff --git a/src/main/java/abstractSyntaxTree/Program.java b/src/main/java/abstractSyntaxTree/Program.java index eb6fa31..e84ca9c 100644 --- a/src/main/java/abstractSyntaxTree/Program.java +++ b/src/main/java/abstractSyntaxTree/Program.java @@ -42,9 +42,11 @@ public class Program implements Node { typeContext.put(oneClass.name, classVars); // build method context - HashMap returnTypeAndParameter = new HashMap<>(); + HashMap> identifierAndMethod = new HashMap<>(); for (MethodDecl methodDecl : oneClass.methodDecls){ + if(methodDecl.returnType == null) continue; + HashMap returnTypeAndParameter = new HashMap<>(); returnTypeAndParameter.put(methodDecl.returnType, methodDecl.parameters); identifierAndMethod.put(methodDecl.name, returnTypeAndParameter); } diff --git a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java index 3c5eefe..b0f0e48 100644 --- a/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java +++ b/src/main/java/abstractSyntaxTree/Statement/BlockStatement.java @@ -57,6 +57,9 @@ public class BlockStatement extends AbstractType implements IStatement { if(statement instanceof AssignStatementExpression assignStatementExpression){ assignStatementExpression.thisClass = thisClass; } + if(statement instanceof LocalVarDecl localVarDecl){ + localVarDecl.thisClass = thisClass; + } TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars); if(statement instanceof LocalVarDecl localVarDecl){ diff --git a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java index 44338f2..5fbb3cb 100644 --- a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java +++ b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java @@ -6,6 +6,7 @@ import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Parameter.ParameterList; +import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -15,6 +16,7 @@ public class LocalVarDecl extends AbstractType implements IStatement{ String type; String identifier; IExpression expression; + public String thisClass; public LocalVarDecl(String type, String identifier, IExpression expression) { this.type = type; this.identifier = identifier; @@ -29,6 +31,11 @@ public class LocalVarDecl extends AbstractType implements IStatement{ // right part if existing if(expression != null){ + if(expression instanceof MethodCallStatementExpression){ + MethodCallStatementExpression methodCall = (MethodCallStatementExpression) expression; + methodCall.thisClass = this.thisClass; + + } expression.typeCheck(methodContext, typeContext, localVars); } diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java index fe4db08..7e6f0a0 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/AssignStatementExpression.java @@ -112,7 +112,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi mv.visitInsn(Opcodes.DUP_X1); // Get the field information - String fieldType = typeContext.get(instVar.classRef.name).get(instVar.fieldName); + String fieldType = typeContext.get(instVar.thisClass).get(instVar.fieldName); StringBuilder descriptor = new StringBuilder(); @@ -124,7 +124,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi descriptor.append("Z"); break; default: - String fullReturnType = typeContext.get(instVar.classRef.name).get(instVar.fieldName); + String fullReturnType = typeContext.get(instVar.thisClass).get(instVar.fieldName); // If it is a class reference replace the "." with "/" and return it if (fieldType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/"); @@ -133,7 +133,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi } // Store the value in the field - mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.classRef.name, instVar.fieldName, descriptor.toString()); + mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.thisClass, instVar.fieldName, descriptor.toString()); } } diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index 1d33317..2013599 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -31,43 +31,53 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr @Override public TypeCheckResult typeCheck(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { - //todo i really dont get this. waiting for tuesday meeting - String classToSearchMethodIn = thisClass; - //method is called on something that is not this + //method is called on something that is not this ??? if(!receiver.thisExpression){ classToSearchMethodIn = localVars.get(receiver.identifier); + if(classToSearchMethodIn == null) + classToSearchMethodIn = thisClass; } + + String currentType = ""; + + // receiver is instvar + if(receiver.instVarExpression != null){ + String Subreceiver = receiver.instVarExpression.receivers.get(0).identifier; // e + String mostLeftField = receiver.instVarExpression.fieldName; // example1 + + String typeOfSubreceiver = typeContext.get(thisClass).get(Subreceiver); + + receiver.instVarExpression.thisClass = typeOfSubreceiver; + receiver.instVarExpression.typeCheck(methodContext, typeContext, localVars); + currentType = typeContext.get(typeOfSubreceiver).get(mostLeftField); + } + //if classToSearchMethodIn does not conatin method, throw exception. go through list and check each + for(int i = 0; i < receivingMethods.size(); i++){ + //todo throw exception + currentType = (String) methodContext.get(currentType).get(receivingMethods.get(i).methodName).keySet().toArray()[0]; + if(currentType == null) + throw new TypeCheckException("The method " + methodName + " was not found in "+ classToSearchMethodIn + "."); + receivingMethods.get(i).checkParameters(methodContext, typeContext, localVars); + System.out.println(currentType); - throw new TypeCheckException("NOT IMPLEMENTED"); -// TypeCheckResult result = new TypeCheckResult(); -// String receivingField; -// String classContainingMethod; -// -// if(receiver.instVarExpression != null){ -// receivingField = receiver.instVarExpression.fieldName; -// }else if(receiver.thisExpression) { -// -// } -// RefType searchMethodHere; -// if(classThatHasTheMethodIfNotThis == null){ -// searchMethodHere = thisClass; -// } else { -// searchMethodHere = classThatHasTheMethodIfNotThis; -// } -// -// List methods = searchMethodHere.methodDecls; -// -// if(!methods.contains(methodName)){ -// throw new TypeCheckException("The method " + methodName + " is called, but does not exist."); -// } -// -// return result; - //return null; + } + currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0]; + // todo checkparameter +// if(method == null) +// throw new TypeCheckException("The method " + methodName + " was not found in "+ classToSearchMethodIn + "."); + + // typecheck arguments + + + TypeCheckResult result = new TypeCheckResult(); + result.type = currentType; + setTypeCheckResult(result); + return result; } //Errors occur due to the change in parameter in the RefType class diff --git a/src/main/java/abstractSyntaxTree/StatementExpression/ReceivingMethod.java b/src/main/java/abstractSyntaxTree/StatementExpression/ReceivingMethod.java index df6ffc1..faf141f 100644 --- a/src/main/java/abstractSyntaxTree/StatementExpression/ReceivingMethod.java +++ b/src/main/java/abstractSyntaxTree/StatementExpression/ReceivingMethod.java @@ -1,16 +1,24 @@ package abstractSyntaxTree.StatementExpression; +import TypeCheck.TypeCheckException; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Node; +import abstractSyntaxTree.Parameter.ParameterList; +import java.util.HashMap; import java.util.List; public class ReceivingMethod implements Node { - String methodName; - List arguments; + public String methodName; + public List arguments; public ReceivingMethod(String methodName, List arguments) { this.methodName = methodName; this.arguments = arguments; } + void checkParameters(HashMap>> methodContext, HashMap> typeContext, HashMap localVars) throws TypeCheckException { + for (IExpression parameter : arguments){ + parameter.typeCheck(methodContext, typeContext, localVars); + } + } }