After the realization that there was a mixup with the produced .class files we once again fix the codeGen

In this commit the standard constructors, mainMethod and standard variable declations were fixed and validated
This commit is contained in:
Jochen Seyfried 2024-06-28 18:23:19 +02:00
parent 4b7cb0b150
commit 66c7722728
4 changed files with 30 additions and 29 deletions

View File

@ -51,7 +51,6 @@ public class MethodDecl implements Node {
} }
//TODO: Es wird kein Bytecode für Standardkonstruktoren für die Klassen generiert
//TODO: Stack computing schlägt fehl --> Reihenfolge aufruf? --> Sobald if-else / if / while drin sind? --> vllt auch schon bei MethodenDecl //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 //Need to get the returnType of the method if it is an object
// methodContext (class, (returnType, (identifier, parameter))) // methodContext (class, (returnType, (identifier, parameter)))

View File

@ -6,6 +6,7 @@ import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Node; import abstractSyntaxTree.Node;
import abstractSyntaxTree.Parameter.ParameterList; import abstractSyntaxTree.Parameter.ParameterList;
import abstractSyntaxTree.Statement.BlockStatement;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
@ -79,7 +80,7 @@ public class RefType extends AbstractType implements Node {
// Method for code generation which iterates over all the field declarations // Method for code generation which iterates over all the field declarations
// and method declarations and calls their CodeGen methods // and method declarations and calls their CodeGen methods
public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception { public void codeGen(ClassWriter cw, HashMap<String, HashMap<String, HashMap<String, ParameterList>>> methodContext, HashMap<String, HashMap<String, String>> typeContext) throws Exception {
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null,
"java/lang/Object", null); "java/lang/Object", null);
@ -88,6 +89,19 @@ public class RefType extends AbstractType implements Node {
field.codeGen(cw); field.codeGen(cw);
} }
boolean hasCustomConstructor = false;
for (MethodDecl method : methodDecls) {
if (method.name.equals(name) && method.returnType == null) {
hasCustomConstructor = true;
break;
}
}
if (!hasCustomConstructor) {
MethodDecl standardConstructor = new MethodDecl(name, null, name, new ParameterList(new ArrayList<>()), new BlockStatement(new ArrayList<>(), "void"));
standardConstructor.codeGen(cw, methodContext, typeContext);
}
for (MethodDecl method : methodDecls) { for (MethodDecl method : methodDecls) {
method.codeGen(cw, methodContext, typeContext); method.codeGen(cw, methodContext, typeContext);
} }

View File

@ -52,8 +52,8 @@ public class Program implements Node {
} }
methodContext.put(oneClass.name, identifierAndMethod); methodContext.put(oneClass.name, identifierAndMethod);
} }
//TODO: uncomment this code
/*
int mainCounter = 0; int mainCounter = 0;
// check if main exists // check if main exists
for(RefType oneClass : classes){ for(RefType oneClass : classes){
@ -62,6 +62,7 @@ public class Program implements Node {
} }
if(mainCounter != 1) if(mainCounter != 1)
throw new TypeCheckException("There is not 1 Main method."); throw new TypeCheckException("There is not 1 Main method.");
*/
// typecheck each class // typecheck each class
TypeCheckResult result = new TypeCheckResult(); TypeCheckResult result = new TypeCheckResult();
@ -73,7 +74,7 @@ public class Program implements Node {
} }
public void codeGen() throws Exception{ public void codeGen() throws Exception{
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream("output.jar"))) { try {
for (RefType oneClass : classes) { for (RefType oneClass : classes) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null); cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, oneClass.name, null, "java/lang/Object", null);
@ -89,30 +90,9 @@ public class Program implements Node {
e.printStackTrace(); e.printStackTrace();
} }
} }
} catch (Exception e) {
throw new RuntimeException(e);
} }
/*// Write the bytecode to a .class file in the .jar file
JarEntry entry = new JarEntry(oneClass.name + ".class");
jos.putNextEntry(entry);
jos.write(bytecode);
jos.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
}*/
/*
for(RefType oneClass : classes){
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC,oneClass.name, null,
"java/lang/Object", null);
oneClass.codeGen(cw);
cw.visitEnd();
byte[] bytecode = cw.toByteArray();
}
*/
} }
@Override @Override

View File

@ -50,7 +50,15 @@ public class LocalVarDecl extends AbstractType implements IStatement{
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 { 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 {
localVars.put(identifier, type); localVars.put(identifier, type);
int index = localVars.size() - 1; int index = -1;
int counter = 0;
// Get the index of the local variable
for (String key : localVars.keySet()) {
counter++;
if (key.equals(identifier)) {
index = counter;
}
}
if (expression != null) { if (expression != null) {
expression.codeGen(mv, localVars, typeContext,methodContext); expression.codeGen(mv, localVars, typeContext,methodContext);