Fixed usage of fields

This commit is contained in:
Jochen Seyfried 2024-06-28 20:29:58 +02:00
parent 27ca4a978f
commit b787b333fb

View File

@ -46,46 +46,60 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{
@Override
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 {
// Check if the variable is in the list of local variables
String type = null;
if (localVars.containsKey(identifier)){
// if it's a local variable
if (localVars.containsKey(identifier)) {
type = localVars.get(identifier);
} else {
// check if instvar
type = typeContext.get(thisClass).get(identifier);
}
if (type == null){
throw new Exception("Variable " + identifier + " not declared");
}
//TODO: What if field
// Find the index of the variable
int index = -1;
int counter = 0;
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;
// Find the index of the variable
int index = -1;
int counter = 0;
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++;
}
counter++;
}
if (index == -1){
if (index == -1) {
throw new Exception("Variable " + identifier + " not found");
}
// Load the variable onto the stack
switch (type) {
case "int", "boolean", "char":
mv.visitVarInsn(Opcodes.ILOAD, index);
break;
case "void":
break;
default:
mv.visitVarInsn(Opcodes.ALOAD, index);
break;
}
// If it's a field
} else if (typeContext.get(thisClass).get(identifier) != null){
type = typeContext.get(thisClass).get(identifier);
// Load "this" onto the stack
mv.visitVarInsn(Opcodes.ALOAD, 0);
// Get the field from "this"
mv.visitFieldInsn(Opcodes.GETFIELD, thisClass, identifier, getFieldDescriptor(type));
} else
throw new Exception("Variable " + identifier + " not found");
}
}
// Load the variable onto the stack
switch (type){
case "int", "boolean", "char":
mv.visitVarInsn(Opcodes.ILOAD, index);
break;
case "void":
break;
//TODO move this to a helper class and remove the doubled code in MethodDecl and in other places
private String getFieldDescriptor(String type) {
switch (type) {
case "int":
return "I";
case "boolean":
return "Z";
case "char":
return "C";
default:
mv.visitVarInsn(Opcodes.ALOAD, index);
break;
return "L" + type + ";";
}
}