methodcall
This commit is contained in:
parent
8182e1ee7a
commit
2a2e14ae21
@ -71,6 +71,6 @@ public class Compiler {
|
|||||||
|
|
||||||
abstractSyntaxTree.typeCheck();
|
abstractSyntaxTree.typeCheck();
|
||||||
|
|
||||||
//abstractSyntaxTree.codeGen();
|
abstractSyntaxTree.codeGen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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){
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user