diff --git a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index a4ccd73..772eef6 100644 --- a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -46,46 +46,60 @@ public class LocalVarIdentifier extends AbstractType implements IExpression{ @Override public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> 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 + ";"; } }