Deleted ICLass and updated the MethodDecl codeGen
This commit is contained in:
parent
7ff84e5ad7
commit
6eb26e70d5
@ -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;
|
||||
|
||||
}
|
@ -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<String, HashMap<String, HashMap<String, ParameterList>>> 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, "<init>", getMethodDescriptor(), null, null);
|
||||
String descriptor = getMethodDescriptor(methodContext);
|
||||
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", descriptor, null, null);
|
||||
|
||||
//Call the superclass constructor
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()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", "<init>", 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<String, HashMap<String, HashMap<String, ParameterList>>> 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<String, HashMap<String, ParameterList>> classMethods = methodContext.get(classThatContainsMethod);
|
||||
HashMap<String, ParameterList> methodDetails = classMethods.get(name);
|
||||
|
||||
String fullReturnType = null;
|
||||
for (Map.Entry<String, ParameterList> 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();
|
||||
|
Loading…
Reference in New Issue
Block a user