methodcall

This commit is contained in:
Krauß, Josefine 2024-06-26 15:38:46 +02:00
parent 8182e1ee7a
commit 2a2e14ae21
10 changed files with 86 additions and 54 deletions

View File

@ -71,6 +71,6 @@ public class Compiler {
abstractSyntaxTree.typeCheck(); abstractSyntaxTree.typeCheck();
//abstractSyntaxTree.codeGen(); abstractSyntaxTree.codeGen();
} }
} }

View File

@ -3,22 +3,25 @@ class Example1 {
int a = 12345; int a = 12345;
Example e; Example e;
public Example1(){i = 3456;} public Example1(){i = 3456;}
int m(int n){ int meth(int n){
boolean b123;
int x;
x = -3;
int i = 5;
Example e = new Example(); Example e = new Example();
e.m(1); int abc = e.example1.m1(2).m2().m3();
return 0; return 0;
} }
Example m1(int n){
return new Example();
}
} }
class Example { class Example {
int i; int i;
boolean b; boolean b;
char c; char c;
int m(int a){ Example1 example1;
return 0; Example1 m(int a){
return new Example1();
} }
Example m2(){return new Example();}
int m3(){return 1;}
} }

View File

@ -18,9 +18,8 @@ import java.util.Objects;
public class InstVarExpression extends AbstractType implements IExpression{ public class InstVarExpression extends AbstractType implements IExpression{
public RefType classRef; public String thisClass;
public List<SubReceiver> receivers;
public List<SubReceiver> receivers; ;
public List<ReceivingMethod> receivingMethods; public List<ReceivingMethod> receivingMethods;
public String fieldName; public String fieldName;
@ -32,9 +31,9 @@ public class InstVarExpression extends AbstractType implements IExpression{
@Override @Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException { public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
String varType = typeContext.get(classRef.name).get(fieldName); String varType = typeContext.get(thisClass).get(fieldName);
if (varType == null) { 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(); TypeCheckResult result = new TypeCheckResult();
result.type = varType; result.type = varType;
@ -48,7 +47,7 @@ public class InstVarExpression extends AbstractType implements IExpression{
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);
//Get the field information //Get the field information
String fieldType = typeContext.get(classRef.name).get(fieldName); String fieldType = typeContext.get(thisClass).get(fieldName);
StringBuilder descriptor = new StringBuilder(); StringBuilder descriptor = new StringBuilder();
@ -64,7 +63,7 @@ public class InstVarExpression extends AbstractType implements IExpression{
descriptor.append("C"); descriptor.append("C");
break; break;
default: 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 it is a class reference replace the "." with "/" and return it
if (fieldType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/"); if (fieldType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/");
@ -73,7 +72,7 @@ public class InstVarExpression extends AbstractType implements IExpression{
} }
// Load the variable onto the stack // Load the variable onto the stack
mv.visitFieldInsn(Opcodes.GETFIELD, classRef.name, fieldName, descriptor.toString()); mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, fieldName, descriptor.toString());
} }
@Override @Override
@ -81,7 +80,7 @@ public class InstVarExpression extends AbstractType implements IExpression{
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
InstVarExpression instVarExpression = (InstVarExpression) o; InstVarExpression instVarExpression = (InstVarExpression) o;
return (Objects.equals(classRef, instVarExpression.classRef) return (Objects.equals(thisClass, instVarExpression.thisClass)
&& Objects.equals(fieldName, instVarExpression.fieldName) && Objects.equals(fieldName, instVarExpression.fieldName)
); );
} }

View File

@ -5,8 +5,8 @@ import abstractSyntaxTree.StatementExpression.NewStatementExpression;
public class SubReceiver implements Node { public class SubReceiver implements Node {
boolean thisExpression; boolean thisExpression;
NewStatementExpression newStatementExpression; public NewStatementExpression newStatementExpression;
String identifier; public String identifier;
public SubReceiver(boolean thisExpression) { public SubReceiver(boolean thisExpression) {
this.thisExpression = thisExpression; this.thisExpression = thisExpression;

View File

@ -42,9 +42,11 @@ public class Program implements Node {
typeContext.put(oneClass.name, classVars); typeContext.put(oneClass.name, classVars);
// build method context // build method context
HashMap<String, ParameterList> returnTypeAndParameter = new HashMap<>();
HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>(); HashMap<String, HashMap<String, ParameterList>> identifierAndMethod = new HashMap<>();
for (MethodDecl methodDecl : oneClass.methodDecls){ for (MethodDecl methodDecl : oneClass.methodDecls){
if(methodDecl.returnType == null) continue;
HashMap<String, ParameterList> returnTypeAndParameter = new HashMap<>();
returnTypeAndParameter.put(methodDecl.returnType, methodDecl.parameters); returnTypeAndParameter.put(methodDecl.returnType, methodDecl.parameters);
identifierAndMethod.put(methodDecl.name, returnTypeAndParameter); identifierAndMethod.put(methodDecl.name, returnTypeAndParameter);
} }

View File

@ -57,6 +57,9 @@ public class BlockStatement extends AbstractType implements IStatement {
if(statement instanceof AssignStatementExpression assignStatementExpression){ if(statement instanceof AssignStatementExpression assignStatementExpression){
assignStatementExpression.thisClass = thisClass; assignStatementExpression.thisClass = thisClass;
} }
if(statement instanceof LocalVarDecl localVarDecl){
localVarDecl.thisClass = thisClass;
}
TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars); TypeCheckResult typeOfCurrentStatement = statement.typeCheck(methodContext, typeContext, localVars);
if(statement instanceof LocalVarDecl localVarDecl){ if(statement instanceof LocalVarDecl localVarDecl){

View File

@ -6,6 +6,7 @@ import TypeCheck.TypeCheckHelper;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Parameter.ParameterList;
import abstractSyntaxTree.StatementExpression.MethodCallStatementExpression;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
@ -15,6 +16,7 @@ public class LocalVarDecl extends AbstractType implements IStatement{
String type; String type;
String identifier; String identifier;
IExpression expression; IExpression expression;
public String thisClass;
public LocalVarDecl(String type, String identifier, IExpression expression) { public LocalVarDecl(String type, String identifier, IExpression expression) {
this.type = type; this.type = type;
this.identifier = identifier; this.identifier = identifier;
@ -29,6 +31,11 @@ public class LocalVarDecl extends AbstractType implements IStatement{
// right part if existing // right part if existing
if(expression != null){ if(expression != null){
if(expression instanceof MethodCallStatementExpression){
MethodCallStatementExpression methodCall = (MethodCallStatementExpression) expression;
methodCall.thisClass = this.thisClass;
}
expression.typeCheck(methodContext, typeContext, localVars); expression.typeCheck(methodContext, typeContext, localVars);
} }

View File

@ -112,7 +112,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
mv.visitInsn(Opcodes.DUP_X1); mv.visitInsn(Opcodes.DUP_X1);
// Get the field information // 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(); StringBuilder descriptor = new StringBuilder();
@ -124,7 +124,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
descriptor.append("Z"); descriptor.append("Z");
break; break;
default: 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 it is a class reference replace the "." with "/" and return it
if (fieldType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/"); if (fieldType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/");
@ -133,7 +133,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
} }
// Store the value in the field // 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());
} }
} }

View File

@ -31,43 +31,53 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
@Override @Override
public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException { public TypeCheckResult typeCheck(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
//todo i really dont get this. waiting for tuesday meeting
String classToSearchMethodIn = thisClass; String classToSearchMethodIn = thisClass;
//method is called on something that is not this //method is called on something that is not this ???
if(!receiver.thisExpression){ if(!receiver.thisExpression){
classToSearchMethodIn = localVars.get(receiver.identifier); 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 //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(); currentType = (String) methodContext.get(currentType).get(methodName).keySet().toArray()[0];
// String receivingField; // todo checkparameter
// String classContainingMethod; // if(method == null)
// // throw new TypeCheckException("The method " + methodName + " was not found in "+ classToSearchMethodIn + ".");
// if(receiver.instVarExpression != null){
// receivingField = receiver.instVarExpression.fieldName; // typecheck arguments
// }else if(receiver.thisExpression) {
//
// } TypeCheckResult result = new TypeCheckResult();
// RefType searchMethodHere; result.type = currentType;
// if(classThatHasTheMethodIfNotThis == null){ setTypeCheckResult(result);
// searchMethodHere = thisClass; return result;
// } else {
// searchMethodHere = classThatHasTheMethodIfNotThis;
// }
//
// List<MethodDecl> methods = searchMethodHere.methodDecls;
//
// if(!methods.contains(methodName)){
// throw new TypeCheckException("The method " + methodName + " is called, but does not exist.");
// }
//
// return result;
//return null;
} }
//Errors occur due to the change in parameter in the RefType class //Errors occur due to the change in parameter in the RefType class

View File

@ -1,16 +1,24 @@
package abstractSyntaxTree.StatementExpression; package abstractSyntaxTree.StatementExpression;
import TypeCheck.TypeCheckException;
import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Node; import abstractSyntaxTree.Node;
import abstractSyntaxTree.Parameter.ParameterList;
import java.util.HashMap;
import java.util.List; import java.util.List;
public class ReceivingMethod implements Node { public class ReceivingMethod implements Node {
String methodName; public String methodName;
List<IExpression> arguments; public List<IExpression> arguments;
public ReceivingMethod(String methodName, List<IExpression> arguments) { public ReceivingMethod(String methodName, List<IExpression> arguments) {
this.methodName = methodName; this.methodName = methodName;
this.arguments = arguments; this.arguments = arguments;
} }
void checkParameters(HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, String> localVars) throws TypeCheckException {
for (IExpression parameter : arguments){
parameter.typeCheck(methodContext, typeContext, localVars);
}
}
} }