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.codeGen();
abstractSyntaxTree.codeGen();
}
}

View File

@ -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;}
}

View File

@ -18,9 +18,8 @@ import java.util.Objects;
public class InstVarExpression extends AbstractType implements IExpression{
public RefType classRef;
public List<SubReceiver> receivers; ;
public String thisClass;
public List<SubReceiver> receivers;
public List<ReceivingMethod> receivingMethods;
public String fieldName;
@ -32,9 +31,9 @@ public class InstVarExpression extends AbstractType implements IExpression{
@Override
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) {
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)
);
}

View File

@ -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;

View File

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

View File

@ -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){

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -31,43 +31,53 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
@Override
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;
//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<MethodDecl> 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

View File

@ -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<IExpression> arguments;
public String methodName;
public List<IExpression> arguments;
public ReceivingMethod(String methodName, List<IExpression> arguments) {
this.methodName = methodName;
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);
}
}
}