From 27ca4a978f90629bdf298dfc932bd75ef6c27018 Mon Sep 17 00:00:00 2001 From: Jochen Seyfried Date: Fri, 28 Jun 2024 20:16:19 +0200 Subject: [PATCH] Updated the handling of fields --- .../abstractSyntaxTree/Class/FieldDecl.java | 2 +- .../abstractSyntaxTree/Class/MethodDecl.java | 45 +++++++++++++++++-- .../abstractSyntaxTree/Class/RefType.java | 4 +- .../Expression/LocalVarIdentifier.java | 11 ++++- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/main/java/abstractSyntaxTree/Class/FieldDecl.java b/src/main/java/abstractSyntaxTree/Class/FieldDecl.java index a7c500f..d1bba33 100644 --- a/src/main/java/abstractSyntaxTree/Class/FieldDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/FieldDecl.java @@ -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; diff --git a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java index 2a6373d..d991c86 100644 --- a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java @@ -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>> methodContext, HashMap> typeContext) throws Exception { + // typeContext (class, (type, identifier)) + public void codeGen(ClassWriter cw, HashMap>> methodContext, HashMap> typeContext, List 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", "", "()V", false); + + //TODO: Initialize the fields of the class + HashMap classFields = typeContext.get(classThatContainsMethod); + + for (Map.Entry 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", "", 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; diff --git a/src/main/java/abstractSyntaxTree/Class/RefType.java b/src/main/java/abstractSyntaxTree/Class/RefType.java index 4e72eda..580aca9 100644 --- a/src/main/java/abstractSyntaxTree/Class/RefType.java +++ b/src/main/java/abstractSyntaxTree/Class/RefType.java @@ -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(); } diff --git a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java index f38f767..a4ccd73 100644 --- a/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java +++ b/src/main/java/abstractSyntaxTree/Expression/LocalVarIdentifier.java @@ -47,11 +47,20 @@ 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 = 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;