Updated the handling of fields

This commit is contained in:
Jochen Seyfried 2024-06-28 20:16:19 +02:00
parent 289231030a
commit 27ca4a978f
4 changed files with 54 additions and 8 deletions

View File

@ -20,7 +20,7 @@ public class FieldDecl extends AbstractType implements Node {
public String type; // from parser
public String identifier;// from parser
public IExpression expression;
public IExpression expression; // value of the field
public FieldDecl(String type, String identifier, IExpression expression){
this.type = type;

View File

@ -57,7 +57,8 @@ public class MethodDecl implements Node {
//TODO: Stack computing schlägt fehl --> Reihenfolge aufruf? --> Sobald if-else / if / while drin sind? --> vllt auch schon bei MethodenDecl
//Need to get the returnType of the method if it is an object
// methodContext (class, (returnType, (identifier, parameter)))
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
// typeContext (class, (type, identifier))
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext, List<FieldDecl> fieldDecls) throws Exception {
localVars.put("this", classThatContainsMethod);
for (Parameter param : parameters.parameterList) {
@ -72,18 +73,41 @@ public class MethodDecl implements Node {
//Call the superclass constructor
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
//TODO: Initialize the fields of the class
HashMap<String, String> classFields = typeContext.get(classThatContainsMethod);
for (Map.Entry<String, String> entry : classFields.entrySet()) {
String fieldName = entry.getKey();
for (FieldDecl field : fieldDecls) {
if (field.identifier.equals(fieldName)) {
mv.visitVarInsn(Opcodes.ALOAD, 0);
field.expression.codeGen(mv, localVars, typeContext, methodContext);
descriptor = getFieldDescriptor(field.type);
mv.visitFieldInsn(Opcodes.PUTFIELD, classThatContainsMethod, fieldName, descriptor);
} else {
throw new Exception("Field " + fieldName + " not found");
}
}
}
//Load the parameters onto the stack
int localVarIndex = 1;
for (Parameter param : parameters.parameterList) {
String paramType = param.type;
switch(paramType) {
case "int", "boolean", "char" -> mv.visitVarInsn(Opcodes.ILOAD, localVarIndex);
default -> mv.visitVarInsn(Opcodes.ALOAD, localVarIndex);
case "int", "boolean", "char" -> {
mv.visitVarInsn(Opcodes.ILOAD, localVarIndex);
mv.visitVarInsn(Opcodes.ISTORE, localVarIndex);
}
default -> {
mv.visitVarInsn(Opcodes.ALOAD, localVarIndex);
mv.visitVarInsn(Opcodes.ASTORE, localVarIndex);
}
}
localVarIndex++;
}
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", descriptor, false);
mv.visitCode();
codeBlock.codeGen(mv, localVars, typeContext, methodContext);
@ -170,6 +194,19 @@ public class MethodDecl implements Node {
return descriptor.toString();
}
private String getFieldDescriptor(String type) {
switch (type) {
case "int":
return "I";
case "boolean":
return "Z";
case "char":
return "C";
default:
return "L" + type + ";";
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@ -99,11 +99,11 @@ public class RefType extends AbstractType implements Node {
if (!hasCustomConstructor) {
MethodDecl standardConstructor = new MethodDecl(name, null, name, new ParameterList(new ArrayList<>()), new BlockStatement(new ArrayList<>(), "void"));
standardConstructor.codeGen(cw, methodContext, typeContext);
standardConstructor.codeGen(cw, methodContext, typeContext, fieldDecls);
}
for (MethodDecl method : methodDecls) {
method.codeGen(cw, methodContext, typeContext);
method.codeGen(cw, methodContext, typeContext, fieldDecls);
}
cw.visitEnd();
}

View File

@ -47,11 +47,20 @@ 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 = localVars.get(identifier);
String type = null;
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;