Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0a81315366
@ -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)))
|
// methodContext (class, (returnType, (identifier, parameter)))
|
||||||
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext) throws Exception {
|
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
|
// check if the method is a constructor
|
||||||
if (classThatContainsMethod.equals(name) && returnType == null) {
|
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
|
//Call the superclass constructor
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
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();
|
mv.visitCode();
|
||||||
codeBlock.codeGen(mv, localVars);
|
codeBlock.codeGen(mv, localVars);
|
||||||
@ -66,7 +80,7 @@ public class MethodDecl implements Node {
|
|||||||
|
|
||||||
//automatically computed max stack and max locals
|
//automatically computed max stack and max locals
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
|
||||||
} else if (name.equals("main")) {
|
} else if (name.equals("main")) {
|
||||||
int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC;
|
int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC;
|
||||||
|
|
||||||
@ -80,7 +94,7 @@ public class MethodDecl implements Node {
|
|||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
|
|
||||||
} else {
|
} 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();
|
mv.visitCode();
|
||||||
codeBlock.codeGen(mv, localVars);
|
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
|
// get the method descriptor
|
||||||
StringBuilder descriptor = new StringBuilder("(");
|
StringBuilder descriptor = new StringBuilder("(");
|
||||||
|
|
||||||
@ -106,17 +120,18 @@ public class MethodDecl implements Node {
|
|||||||
case "boolean" -> descriptor.append("Z");
|
case "boolean" -> descriptor.append("Z");
|
||||||
case "char" -> descriptor.append("C");
|
case "char" -> descriptor.append("C");
|
||||||
case "void" -> descriptor.append("V");
|
case "void" -> descriptor.append("V");
|
||||||
default ->
|
default -> {
|
||||||
// object
|
// object
|
||||||
//TODO: This is not finished
|
//TODO: This is not finished for objects --> classes and methods
|
||||||
descriptor.append("L").append(param.type).append(";");
|
if (returnType != null) descriptor.append("L").append(returnType).append(";");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
descriptor.append(")");
|
descriptor.append(")");
|
||||||
|
|
||||||
|
|
||||||
// Get the return type
|
// 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) {
|
if (returnType == null) {
|
||||||
descriptor.append("V");
|
descriptor.append("V");
|
||||||
} else {
|
} else {
|
||||||
@ -125,12 +140,20 @@ public class MethodDecl implements Node {
|
|||||||
case "boolean" -> descriptor.append("Z");
|
case "boolean" -> descriptor.append("Z");
|
||||||
case "char" -> descriptor.append("C");
|
case "char" -> descriptor.append("C");
|
||||||
case "void" -> descriptor.append("V");
|
case "void" -> descriptor.append("V");
|
||||||
|
default -> {
|
||||||
//TODO: This is not finished --> we need to append the fully qualified name of the object
|
|
||||||
// Need to make sure what we get
|
|
||||||
default ->
|
|
||||||
// object
|
// 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();
|
return descriptor.toString();
|
||||||
|
Loading…
Reference in New Issue
Block a user