From 6eb26e70d5f9e7813e10e97a4f8f52026b716c5a Mon Sep 17 00:00:00 2001 From: Jochen Seyfried Date: Tue, 14 May 2024 14:13:43 +0200 Subject: [PATCH] Deleted ICLass and updated the MethodDecl codeGen --- .../java/abstractSyntaxTree/Class/IClass.java | 16 ------ .../abstractSyntaxTree/Class/MethodDecl.java | 51 ++++++++++++++----- 2 files changed, 37 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/abstractSyntaxTree/Class/IClass.java diff --git a/src/main/java/abstractSyntaxTree/Class/IClass.java b/src/main/java/abstractSyntaxTree/Class/IClass.java deleted file mode 100644 index e71c991..0000000 --- a/src/main/java/abstractSyntaxTree/Class/IClass.java +++ /dev/null @@ -1,16 +0,0 @@ -package abstractSyntaxTree.Class; - -import TypeCheck.TypeCheckResult; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.TypeReference; - -import java.util.HashMap; -import java.util.List; - -public interface IClass { - // visit method for code generation - - - void codeGen(ClassWriter cw) throws Exception; - -} diff --git a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java index c1a30e0..c943cf6 100644 --- a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java @@ -44,6 +44,7 @@ public class MethodDecl implements Node { } + //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) throws Exception { @@ -54,11 +55,24 @@ public class MethodDecl implements Node { // check if the method is a constructor if (classThatContainsMethod.equals(name) && returnType == null) { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", getMethodDescriptor(), null, null); + String descriptor = getMethodDescriptor(methodContext); + + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", descriptor, null, null); //Call the superclass constructor mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); + + //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); + } + localVarIndex++; + } + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", descriptor, false); mv.visitCode(); codeBlock.codeGen(mv, localVars); @@ -66,7 +80,7 @@ public class MethodDecl implements Node { //automatically computed max stack and max locals mv.visitMaxs(0, 0); - mv.visitEnd(); + } else if (name.equals("main")) { int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC; @@ -80,7 +94,7 @@ public class MethodDecl implements Node { mv.visitEnd(); } else { - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(), null, null); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, name, getMethodDescriptor(methodContext), null, null); mv.visitCode(); codeBlock.codeGen(mv, localVars); @@ -95,7 +109,7 @@ public class MethodDecl implements Node { } } - private String getMethodDescriptor() { + private String getMethodDescriptor(HashMap>> methodContext) { // get the method descriptor StringBuilder descriptor = new StringBuilder("("); @@ -106,17 +120,18 @@ public class MethodDecl implements Node { case "boolean" -> descriptor.append("Z"); case "char" -> descriptor.append("C"); case "void" -> descriptor.append("V"); - default -> + default -> { // object - //TODO: This is not finished - descriptor.append("L").append(param.type).append(";"); + //TODO: This is not finished for objects --> classes and methods + if (returnType != null) descriptor.append("L").append(returnType).append(";"); + } } } descriptor.append(")"); // Get the return type - // If the return type is null, it is a constructor and we need to append V + // If the return type is null, it is a constructor, and we need to append V if (returnType == null) { descriptor.append("V"); } else { @@ -125,12 +140,20 @@ public class MethodDecl implements Node { case "boolean" -> descriptor.append("Z"); case "char" -> descriptor.append("C"); case "void" -> descriptor.append("V"); - - //TODO: This is not finished --> we need to append the fully qualified name of the object - // Need to make sure what we get - default -> + default -> { // object - descriptor.append("L").append(returnType).append(";"); + HashMap> classMethods = methodContext.get(classThatContainsMethod); + HashMap methodDetails = classMethods.get(name); + + String fullReturnType = null; + for (Map.Entry entry : methodDetails.entrySet()) { + fullReturnType = entry.getKey(); + } + // If it is a class reference replace the "." with "/" and return it + if (returnType.contains(".")) fullReturnType = fullReturnType.replaceAll("\\.", "/"); + + if (fullReturnType != null) descriptor.append("L").append(fullReturnType).append(";"); + } } } return descriptor.toString();