Updated the handling of fields
This commit is contained in:
parent
289231030a
commit
27ca4a978f
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user