From 7cbde86ca30ba6712f94ffd6dba06ba6cec98da2 Mon Sep 17 00:00:00 2001 From: David Mueller Date: Wed, 8 May 2024 13:54:32 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Decaf=20Changes=20-=20Pl=C3=BCmi=20Patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/Decaf.g4 | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/Source/Decaf.g4 b/Source/Decaf.g4 index 2dde8dd..2af8297 100644 --- a/Source/Decaf.g4 +++ b/Source/Decaf.g4 @@ -3,11 +3,11 @@ grammar Decaf; program: classdecl+; //class identifier{...} -classdecl: AccessModifierPublic? 'class' Identifier OpenCurlyBracket (constuctorDecl|fieldDecl|methodDecl)* ClosedCurlyBracket; -constuctorDecl: AccessModifierPublic? Identifier OpenRoundBracket parameterList? ClosedRoundBracket block; //Maybe not needed +classdecl: AccessModifierPublic? 'class' Identifier OpenCurlyBracket (constuctorDecl|fieldDecl|methodDecl)*(MainMethodDecl block)? ClosedCurlyBracket; +constuctorDecl: AccessModifierPublic? Identifier OpenRoundBracket parameterList? ClosedRoundBracket block; //Method without //Method and FieldVar -methodDecl: MainMethodDecl block | AccessModifierPublic? (type | Void) Identifier OpenRoundBracket parameterList? ClosedRoundBracket block; +methodDecl: AccessModifierPublic? (type | Void) Identifier OpenRoundBracket parameterList? ClosedRoundBracket block; fieldDecl: AccessModifierPublic? type Identifier Semicolon; //Parameters @@ -17,16 +17,20 @@ parameter: type Identifier; //property, object.a, 3+1, a = 3 expression: subExpression | binaryExpr; //subExpression to dissolve left-recusion -subExpression: This | Identifier | instVar | value | stmtExpr | notExpr | OpenRoundBracket expression ClosedRoundBracket; -notExpr: Not expression; +subExpression: This | assignableExpr | stmtExpr | OpenRoundBracket subExpression ClosedRoundBracket; assignableExpr: Identifier | instVar; -instVar: This Dot Identifier | (This Dot)? (Identifier Dot)+ Identifier; +instVar: subReceiver? receivingMethod* Identifier; //.trim().toLength().toLowerCase().count ... methodCall: receiver? receivingMethod* Identifier OpenRoundBracket argumentList ClosedRoundBracket; -argumentList: expression? | expression (Comma expression)*?; +argumentList: expression? | expression (Comma expression)+; -binaryExpr: calcExpr | nonCalcExpr; +subReceiver: ((This | newDecl | Identifier) Dot); +receiver: ((This | instVar | newDecl | Identifier) Dot); +receivingMethod: Identifier OpenRoundBracket argumentList ClosedRoundBracket Dot; + + +binaryExpr: calcExpr | nonCalcExpr| value | Not binaryExpr; calcExpr: calcExpr LineOperator dotExpr | dotExpr; dotExpr: dotExpr DotOperator dotSubExpr | dotSubExpr; @@ -44,14 +48,14 @@ statement: returnStmt Semicolon | localVarDecl Semicolon | block | whileStmt | i returnStmt: Return (expression)?; localVarDecl: type Identifier (Assign expression)?; block: OpenCurlyBracket statement* ClosedCurlyBracket; -whileStmt: While OpenRoundBracket expression ClosedRoundBracket block; +whileStmt: While OpenRoundBracket expression ClosedRoundBracket statement; ifElseStmt: ifStmt elseStmt?; ifStmt: If OpenRoundBracket expression ClosedRoundBracket statement; elseStmt: Else statement; assign: assignableExpr Assign expression; newDecl: New Identifier OpenRoundBracket argumentList ClosedRoundBracket; -receiver: ((This | instVar | newDecl | Identifier) Dot); -receivingMethod: Identifier OpenRoundBracket argumentList ClosedRoundBracket Dot; + + type: Int | Boolean | Char | Identifier; value: IntValue | BooleanValue | CharValue | NullValue; @@ -59,11 +63,7 @@ value: IntValue | BooleanValue | CharValue | NullValue; AccessModifierPublic : 'public' ; MainMethodDecl : 'public static void main(String[] args)'; -//Types -Void : 'void'; -Int : 'int'; -Boolean : 'bool'; -Char : 'char'; + //Operators DotOperator : Multipilkation | Division | Modulo; @@ -102,7 +102,6 @@ This : 'this'; While : 'while'; If : 'if'; Else : 'else'; -For : 'for'; Return : 'return'; New : 'new'; @@ -112,6 +111,12 @@ fragment Numeric: [0-9]; fragment ValidIdentSymbols : Alpabetic|Numeric|'$'|'_'; Identifier: Alpabetic ValidIdentSymbols*; +//Types +Void : 'void'; +Int : 'int'; +Boolean : 'bool'; +Char : 'char'; + //Values IntValue : ('+'|'-')*[0-9]+; CharValue: '\''~[\r\n]?'\''; From 103e80e31828066b06b304ea51a88e0d53aef785 Mon Sep 17 00:00:00 2001 From: Jochen Seyfried Date: Wed, 8 May 2024 14:15:11 +0200 Subject: [PATCH 2/3] Moved the RefType class to the class package --- Source/abstractSyntaxTree/Class/FieldDecl.java | 6 ++++++ Source/abstractSyntaxTree/Class/IClass.java | 4 ++++ Source/abstractSyntaxTree/Class/MethodDecl.java | 5 +++++ .../{Datatype => Class}/RefType.java | 3 ++- .../Expression/InstVarExpression.java | 2 +- Source/abstractSyntaxTree/Program.java | 13 ++++++++++--- .../MethodCallStatementExpression.java | 2 +- 7 files changed, 29 insertions(+), 6 deletions(-) rename Source/abstractSyntaxTree/{Datatype => Class}/RefType.java (96%) diff --git a/Source/abstractSyntaxTree/Class/FieldDecl.java b/Source/abstractSyntaxTree/Class/FieldDecl.java index 98e2225..e0a4675 100644 --- a/Source/abstractSyntaxTree/Class/FieldDecl.java +++ b/Source/abstractSyntaxTree/Class/FieldDecl.java @@ -4,6 +4,7 @@ import TypeCheck.AbstractType; import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Program; +import org.objectweb.asm.ClassWriter; import java.util.ArrayList; import java.util.HashMap; @@ -32,4 +33,9 @@ public class FieldDecl extends AbstractType implements IClass{ //write field table } + + @Override + public void codeGen(ClassWriter cw) { + + } } diff --git a/Source/abstractSyntaxTree/Class/IClass.java b/Source/abstractSyntaxTree/Class/IClass.java index 85803f2..158cf7e 100644 --- a/Source/abstractSyntaxTree/Class/IClass.java +++ b/Source/abstractSyntaxTree/Class/IClass.java @@ -1,9 +1,13 @@ package abstractSyntaxTree.Class; import TypeCheck.TypeCheckResult; +import org.objectweb.asm.ClassWriter; import java.util.List; public interface IClass { // visit method for code generation + + void codeGen(ClassWriter cw); + } diff --git a/Source/abstractSyntaxTree/Class/MethodDecl.java b/Source/abstractSyntaxTree/Class/MethodDecl.java index 10b2fa1..be6aeee 100644 --- a/Source/abstractSyntaxTree/Class/MethodDecl.java +++ b/Source/abstractSyntaxTree/Class/MethodDecl.java @@ -2,6 +2,7 @@ package abstractSyntaxTree.Class; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Program; +import org.objectweb.asm.ClassWriter; import java.util.HashMap; import java.util.List; @@ -27,4 +28,8 @@ public class MethodDecl implements IClass { return null; } + @Override + public void codeGen(ClassWriter cw) { + + } } diff --git a/Source/abstractSyntaxTree/Datatype/RefType.java b/Source/abstractSyntaxTree/Class/RefType.java similarity index 96% rename from Source/abstractSyntaxTree/Datatype/RefType.java rename to Source/abstractSyntaxTree/Class/RefType.java index 1c3d0ab..43a54e8 100644 --- a/Source/abstractSyntaxTree/Datatype/RefType.java +++ b/Source/abstractSyntaxTree/Class/RefType.java @@ -1,9 +1,10 @@ -package abstractSyntaxTree.Datatype; +package abstractSyntaxTree.Class; import TypeCheck.AbstractType; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.FieldDecl; import abstractSyntaxTree.Class.MethodDecl; +import abstractSyntaxTree.Datatype.IDatatype; import abstractSyntaxTree.Program; import jdk.jshell.spi.ExecutionControl; import org.objectweb.asm.MethodVisitor; diff --git a/Source/abstractSyntaxTree/Expression/InstVarExpression.java b/Source/abstractSyntaxTree/Expression/InstVarExpression.java index 7b45d3a..f7d58e3 100644 --- a/Source/abstractSyntaxTree/Expression/InstVarExpression.java +++ b/Source/abstractSyntaxTree/Expression/InstVarExpression.java @@ -1,7 +1,7 @@ package abstractSyntaxTree.Expression; import TypeCheck.TypeCheckResult; -import abstractSyntaxTree.Datatype.RefType; +import abstractSyntaxTree.Class.RefType; import jdk.jshell.spi.ExecutionControl; import org.objectweb.asm.MethodVisitor; diff --git a/Source/abstractSyntaxTree/Program.java b/Source/abstractSyntaxTree/Program.java index 0c9aa5d..0ca3840 100644 --- a/Source/abstractSyntaxTree/Program.java +++ b/Source/abstractSyntaxTree/Program.java @@ -2,8 +2,9 @@ package abstractSyntaxTree; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.FieldDecl; -import abstractSyntaxTree.Datatype.RefType; -import org.objectweb.asm.MethodVisitor; +import abstractSyntaxTree.Class.RefType; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; import java.util.HashMap; import java.util.List; @@ -26,7 +27,13 @@ public class Program { public void codeGen() throws Exception{ for(RefType oneClass : classes){ - oneClass.codeGen(); + //Get the name of the class + typeContext.get() + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, + ); + oneClass.codeGen(ClassWriter cw); } } } diff --git a/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index bffaa94..93d7347 100644 --- a/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -3,7 +3,7 @@ package abstractSyntaxTree.StatementExpression; import TypeCheck.AbstractType; import TypeCheck.TypeCheckResult; import abstractSyntaxTree.Class.MethodDecl; -import abstractSyntaxTree.Datatype.RefType; +import abstractSyntaxTree.Class.RefType; import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Statement.IStatement; import org.objectweb.asm.MethodVisitor; From 9cda409dd35f814a9d59132ebc3c2d0f27701537 Mon Sep 17 00:00:00 2001 From: Jochen Seyfried Date: Wed, 8 May 2024 14:28:01 +0200 Subject: [PATCH 3/3] Added Programm codeGen logic --- Source/abstractSyntaxTree/Class/IClass.java | 4 +- Source/abstractSyntaxTree/Class/RefType.java | 7 ++-- Source/abstractSyntaxTree/Program.java | 40 +++++++++++++++---- .../MethodCallStatementExpression.java | 5 ++- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/Source/abstractSyntaxTree/Class/IClass.java b/Source/abstractSyntaxTree/Class/IClass.java index 158cf7e..6af7dec 100644 --- a/Source/abstractSyntaxTree/Class/IClass.java +++ b/Source/abstractSyntaxTree/Class/IClass.java @@ -2,12 +2,14 @@ package abstractSyntaxTree.Class; import TypeCheck.TypeCheckResult; import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.TypeReference; import java.util.List; public interface IClass { // visit method for code generation - void codeGen(ClassWriter cw); + TypeCheckResult typeCheck() throws Exception; + void codeGen(ClassWriter cw) throws Exception; } diff --git a/Source/abstractSyntaxTree/Class/RefType.java b/Source/abstractSyntaxTree/Class/RefType.java index 43a54e8..db4b3f9 100644 --- a/Source/abstractSyntaxTree/Class/RefType.java +++ b/Source/abstractSyntaxTree/Class/RefType.java @@ -7,14 +7,15 @@ import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Datatype.IDatatype; import abstractSyntaxTree.Program; import jdk.jshell.spi.ExecutionControl; +import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import java.util.HashMap; import java.util.List; -public class RefType extends AbstractType implements IDatatype { +public class RefType extends AbstractType implements IClass { - String name; + public String name; public List fieldDecls; public List methodDecls; private HashMap> typeContext; // (class, (type, identifier)) @@ -52,7 +53,7 @@ public class RefType extends AbstractType implements IDatatype { // Method for code generation which iterates over all the field declarations // and method declarations and calls their CodeGen methods @Override - public void codeGen(MethodVisitor mv) throws Exception { + public void codeGen(ClassWriter cw) throws Exception { throw new ExecutionControl.NotImplementedException("CodeGen not implemented for RefType"); } diff --git a/Source/abstractSyntaxTree/Program.java b/Source/abstractSyntaxTree/Program.java index 0ca3840..33589c1 100644 --- a/Source/abstractSyntaxTree/Program.java +++ b/Source/abstractSyntaxTree/Program.java @@ -6,8 +6,12 @@ import abstractSyntaxTree.Class.RefType; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.HashMap; import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; public class Program { public List classes; @@ -26,14 +30,36 @@ public class Program { } public void codeGen() throws Exception{ - for(RefType oneClass : classes){ - //Get the name of the class - typeContext.get() + try (JarOutputStream jos = new JarOutputStream(new FileOutputStream("output.jar"))) { + 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); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, - ); - oneClass.codeGen(ClassWriter cw); + oneClass.codeGen(cw); + + cw.visitEnd(); + byte[] bytecode = cw.toByteArray(); + + // 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(); + } + */ } } diff --git a/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java b/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java index 93d7347..7eb133c 100644 --- a/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java +++ b/Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java @@ -42,17 +42,18 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr return result; } + //Errors occur due to the change in parameter in the RefType class @Override public void CodeGen(MethodVisitor mv) throws Exception { //Generate Bytecode for the receiver if(classThatHasTheMethodIfNotThis != null){ - classThatHasTheMethodIfNotThis.CodeGen(mv); + classThatHasTheMethodIfNotThis.codeGen(); } else { mv.visitVarInsn(Opcodes.ALOAD, 0); } for (IExpression argument : arguments) { - argument.CodeGen(mv); + argument.codeGen(mv); } //We need the class reference and the return type of the method