From 66c77227287b8c5a288c8cfa28cd711fa3c5fc36 Mon Sep 17 00:00:00 2001 From: Jochen Seyfried Date: Fri, 28 Jun 2024 18:23:19 +0200 Subject: [PATCH] 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 --- .../abstractSyntaxTree/Class/MethodDecl.java | 1 - .../abstractSyntaxTree/Class/RefType.java | 16 +++++++++- src/main/java/abstractSyntaxTree/Program.java | 32 ++++--------------- .../Statement/LocalVarDecl.java | 10 +++++- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java index c1143b8..0026c58 100644 --- a/src/main/java/abstractSyntaxTree/Class/MethodDecl.java +++ b/src/main/java/abstractSyntaxTree/Class/MethodDecl.java @@ -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 //Need to get the returnType of the method if it is an object // methodContext (class, (returnType, (identifier, parameter))) diff --git a/src/main/java/abstractSyntaxTree/Class/RefType.java b/src/main/java/abstractSyntaxTree/Class/RefType.java index 76cc208..4e72eda 100644 --- a/src/main/java/abstractSyntaxTree/Class/RefType.java +++ b/src/main/java/abstractSyntaxTree/Class/RefType.java @@ -6,6 +6,7 @@ import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Node; import abstractSyntaxTree.Parameter.ParameterList; +import abstractSyntaxTree.Statement.BlockStatement; import org.objectweb.asm.ClassWriter; 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 // and method declarations and calls their CodeGen methods - public void codeGen(ClassWriter cw, HashMap>> methodContext, HashMap> typeContext) throws Exception { + public void codeGen(ClassWriter cw, HashMap>> methodContext, HashMap> typeContext) throws Exception { cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object", null); @@ -88,6 +89,19 @@ public class RefType extends AbstractType implements Node { 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) { method.codeGen(cw, methodContext, typeContext); } diff --git a/src/main/java/abstractSyntaxTree/Program.java b/src/main/java/abstractSyntaxTree/Program.java index 2582f18..51ba338 100644 --- a/src/main/java/abstractSyntaxTree/Program.java +++ b/src/main/java/abstractSyntaxTree/Program.java @@ -52,8 +52,8 @@ public class Program implements Node { } methodContext.put(oneClass.name, identifierAndMethod); } - - + //TODO: uncomment this code + /* int mainCounter = 0; // check if main exists for(RefType oneClass : classes){ @@ -62,6 +62,7 @@ public class Program implements Node { } if(mainCounter != 1) throw new TypeCheckException("There is not 1 Main method."); + */ // typecheck each class TypeCheckResult result = new TypeCheckResult(); @@ -73,7 +74,7 @@ public class Program implements Node { } public void codeGen() throws Exception{ - try (JarOutputStream jos = new JarOutputStream(new FileOutputStream("output.jar"))) { + try { 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); @@ -89,30 +90,9 @@ public class Program implements Node { 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 diff --git a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java index 5413556..53e1dd8 100644 --- a/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java +++ b/src/main/java/abstractSyntaxTree/Statement/LocalVarDecl.java @@ -50,7 +50,15 @@ public class LocalVarDecl extends AbstractType implements IStatement{ public void codeGen(MethodVisitor mv, LinkedHashMap localVars, HashMap> typeContext, HashMap>> methodContext) throws Exception { 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) { expression.codeGen(mv, localVars, typeContext,methodContext);