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 @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 { 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; String type = null;
if (localVars.containsKey(identifier)){
// if it's a local variable
if (localVars.containsKey(identifier)) {
type = localVars.get(identifier); type = localVars.get(identifier);
} else { // Find the index of the variable
// check if instvar int index = -1;
type = typeContext.get(thisClass).get(identifier); int counter = 0;
} for (String key : localVars.keySet()) {
if (type == null){ if (key.equals(identifier)) {
throw new Exception("Variable " + identifier + " not declared"); index = counter + 1; // +1 because the first local variable is at index 1, 0 is used for "this"
} break;
}
//TODO: What if field counter++;
// 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++;
}
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"); throw new Exception("Variable " + identifier + " not found");
} }
// Load the variable onto the stack //TODO move this to a helper class and remove the doubled code in MethodDecl and in other places
switch (type){ private String getFieldDescriptor(String type) {
case "int", "boolean", "char": switch (type) {
mv.visitVarInsn(Opcodes.ILOAD, index); case "int":
break; return "I";
case "void": case "boolean":
break; return "Z";
case "char":
return "C";
default: default:
mv.visitVarInsn(Opcodes.ALOAD, index); return "L" + type + ";";
break;
} }
} }