Second step of codeGen refactoring in which other methods were refactored to use the methods in CodeGenHelper
This commit is contained in:
parent
3e908293ee
commit
32353b9a37
@ -1,9 +1,6 @@
|
|||||||
package CodeGen;
|
package CodeGen;
|
||||||
|
|
||||||
import abstractSyntaxTree.Expression.SubReceiver;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CodeGenHelper {
|
public class CodeGenHelper {
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import CodeGen.CodeGenHelper;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckException;
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
@ -59,15 +60,8 @@ public class LocalVarDecl extends AbstractType implements IStatement{
|
|||||||
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
public void codeGen(MethodVisitor mv, LinkedHashMap<String, String> localVars, HashMap<String, HashMap<String, String>> typeContext, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
||||||
localVars.put(identifier, type);
|
localVars.put(identifier, type);
|
||||||
|
|
||||||
int index = -1;
|
|
||||||
int counter = 0;
|
int index = CodeGenHelper.GetLocalVarIndex(localVars, identifier);
|
||||||
for (String key : localVars.keySet()){
|
|
||||||
if (key.equals(identifier)){
|
|
||||||
index = counter+1; // +1 because the first local variable is at index 1, 0 is used for "this"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == -1){
|
if (index == -1){
|
||||||
throw new Exception("Variable " + identifier + " not found");
|
throw new Exception("Variable " + identifier + " not found");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
|
import CodeGen.CodeGenHelper;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckException;
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
@ -51,15 +52,8 @@ public class PrintStatement extends AbstractType implements IStatement {
|
|||||||
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
|
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
|
||||||
|
|
||||||
// Load the value of the variable onto the stack
|
// Load the value of the variable onto the stack
|
||||||
int index = -1;
|
int index = CodeGenHelper.GetLocalVarIndex(localVars, variableName);
|
||||||
int counter = 0;
|
|
||||||
for (String key : localVars.keySet()){
|
|
||||||
if (key.equals(variableName)){
|
|
||||||
index = counter+1; // +1 because the first local variable is at index 1, 0 is used for "this"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
// If not a localVar, maybe a class field of this class
|
// If not a localVar, maybe a class field of this class
|
||||||
if (index == -1){
|
if (index == -1){
|
||||||
String typeOfField = typeContext.get(thisClass).get(variableName);
|
String typeOfField = typeContext.get(thisClass).get(variableName);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package abstractSyntaxTree.StatementExpression;
|
package abstractSyntaxTree.StatementExpression;
|
||||||
|
|
||||||
|
import CodeGen.CodeGenHelper;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import TypeCheck.TypeCheckException;
|
import TypeCheck.TypeCheckException;
|
||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
@ -84,15 +85,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
String varName = localVar.getIdentifier();
|
String varName = localVar.getIdentifier();
|
||||||
|
|
||||||
//Get the index of the local variable
|
//Get the index of the local variable
|
||||||
int index = -1;
|
int index = CodeGenHelper.GetLocalVarIndex(localVars, varName);
|
||||||
int counter = 0;
|
|
||||||
for (String key : localVars.keySet()) {
|
|
||||||
if (key.equals(varName)) {
|
|
||||||
index = counter + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
String fieldType = typeContext.get(thisClass).get(varName);
|
String fieldType = typeContext.get(thisClass).get(varName);
|
||||||
@ -132,15 +125,8 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
// Determine if the reference is this or another object
|
// Determine if the reference is this or another object
|
||||||
if (instVar.receivers.get(0).identifier != null) {
|
if (instVar.receivers.get(0).identifier != null) {
|
||||||
// Load the local variable (another object) onto the stack
|
// Load the local variable (another object) onto the stack
|
||||||
int index = -1;
|
int index = CodeGenHelper.GetLocalVarIndex(localVars, instVar.receivers.get(0).identifier);
|
||||||
int counter = 0;
|
|
||||||
for (String key : localVars.keySet()) {
|
|
||||||
if (key.equals(instVar.receivers.get(0).identifier)) {
|
|
||||||
index = counter + 1; // Local variables start at index 1, 0 is "this"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
throw new Exception("Variable " + instVar.receivers.get(0).identifier + " not found");
|
throw new Exception("Variable " + instVar.receivers.get(0).identifier + " not found");
|
||||||
}
|
}
|
||||||
@ -152,10 +138,6 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the codeGen on the right expression which will push the value of the right expression onto the stack
|
|
||||||
//right.codeGen(mv, localVars, typeContext, methodContext);
|
|
||||||
|
|
||||||
|
|
||||||
//Now that the base ref is on the stack, I need to get the next field(s) and store the value in the last field
|
//Now that the base ref is on the stack, I need to get the next field(s) and store the value in the last field
|
||||||
|
|
||||||
String typeOfPrevious = "";
|
String typeOfPrevious = "";
|
||||||
@ -205,9 +187,6 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
//Now we have to implement the logic for the following fields in the chain as the above code
|
//Now we have to implement the logic for the following fields in the chain as the above code
|
||||||
// only handles the first field in the chain
|
// only handles the first field in the chain
|
||||||
|
|
||||||
// For the following fields I only have to call GETFIELD so I load the next reference onto the stack
|
|
||||||
// The fields must be present in "typeOfPrevious"
|
|
||||||
|
|
||||||
currentType = typeContext.get(typeOfPrevious).get(instVar.receivers.get(i).identifier);
|
currentType = typeContext.get(typeOfPrevious).get(instVar.receivers.get(i).identifier);
|
||||||
String descriptor = getFieldDescriptor(currentType, typeContext, instVar.receivers.get(i).identifier, typeOfPrevious);
|
String descriptor = getFieldDescriptor(currentType, typeContext, instVar.receivers.get(i).identifier, typeOfPrevious);
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, typeOfPrevious, instVar.receivers.get(i).identifier, descriptor);
|
mv.visitFieldInsn(Opcodes.GETFIELD, typeOfPrevious, instVar.receivers.get(i).identifier, descriptor);
|
||||||
@ -225,8 +204,7 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//This is finished and right
|
// When a field is accessed directly and without a "this."
|
||||||
// It's for when a field is accessed directly and without a "this."
|
|
||||||
|
|
||||||
//Load the value of the right expression on the stack
|
//Load the value of the right expression on the stack
|
||||||
right.codeGen(mv, localVars, typeContext, methodContext);
|
right.codeGen(mv, localVars, typeContext, methodContext);
|
||||||
@ -243,59 +221,6 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Field is called with "this.xxx"
|
|
||||||
if (instVar.receivers.get(0).thisExpression) {
|
|
||||||
|
|
||||||
// If the chain is only 1 long we can directly store the value in the field
|
|
||||||
// If not we have to load the reference of the field on the stack
|
|
||||||
if(instVar.receivers.size() > 1) {
|
|
||||||
// If first receiver is not this check local then fields of thisClass
|
|
||||||
if (isLocal) {
|
|
||||||
currentType = localVars.get(instVar.receivers.get(i).identifier);
|
|
||||||
} else {
|
|
||||||
currentType = typeContext.get(thisClass).get(instVar.receivers.get(i).identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentType = typeContext.get(thisClass).get(instVar.fieldName);
|
|
||||||
String descriptor = getFieldDescriptor(currentType, typeContext, instVar.fieldName, thisClass);
|
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, instVar.fieldName, descriptor);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// Chain is only 1 long, so we can call PUTFIELD directly
|
|
||||||
|
|
||||||
//Load the value of the right expression on the stack
|
|
||||||
right.codeGen(mv, localVars, typeContext, methodContext);
|
|
||||||
|
|
||||||
currentType = typeContext.get(thisClass).get(instVar.fieldName);
|
|
||||||
String descriptor = getFieldDescriptor(currentType, typeContext, instVar.fieldName, thisClass);
|
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, thisClass, instVar.fieldName, descriptor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If first receiver is not this check local then fields of thisClass
|
|
||||||
if (isLocal) {
|
|
||||||
currentType = localVars.get(instVar.receivers.get(i).identifier);
|
|
||||||
} else {
|
|
||||||
currentType = typeContext.get(thisClass).get(instVar.receivers.get(i).identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentType = typeContext.get(typeOfPrevious).get(instVar.fieldName);
|
|
||||||
String descriptor = getFieldDescriptor(currentType, typeContext, instVar.fieldName, typeOfPrevious);
|
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, instVar.fieldName, descriptor);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentType = typeContext.get(typeOfPrevious).get(instVar.receivers.get(i).identifier);
|
|
||||||
String descriptor = getFieldDescriptor(currentType, typeContext, instVar.receivers.get(i).identifier, typeOfPrevious);
|
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD, typeOfPrevious, instVar.receivers.get(i).identifier, descriptor);
|
|
||||||
typeOfPrevious = currentType;
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
|
||||||
private String getFieldDescriptor(String type, HashMap<String, HashMap<String, String>> typeContext, String varName, String classToSearchFieldIn) {
|
private String getFieldDescriptor(String type, HashMap<String, HashMap<String, String>> typeContext, String varName, String classToSearchFieldIn) {
|
||||||
StringBuilder descriptor = new StringBuilder();
|
StringBuilder descriptor = new StringBuilder();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -145,7 +145,6 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
owner = returnOfPreviousMethod;
|
owner = returnOfPreviousMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String descriptor = getMethodDescriptor(methodName, localVars, methodContext, arguments, returnOfPreviousMethod, owner);
|
String descriptor = getMethodDescriptor(methodName, localVars, methodContext, arguments, returnOfPreviousMethod, owner);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, methodName, descriptor, false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, methodName, descriptor, false);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user