Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Source/abstractSyntaxTree/Class/MethodDecl.java
#	Source/abstractSyntaxTree/Program.java
#	Source/abstractSyntaxTree/StatementExpression/MethodCallStatementExpression.java
This commit is contained in:
Krauß, Josefine 2024-05-08 14:31:39 +02:00
commit f273c74693
8 changed files with 85 additions and 29 deletions

View File

@ -3,11 +3,11 @@ grammar Decaf;
program: classdecl+; program: classdecl+;
//class identifier{...} //class identifier{...}
classdecl: AccessModifierPublic? 'class' Identifier OpenCurlyBracket (constuctorDecl|fieldDecl|methodDecl)* ClosedCurlyBracket; classdecl: AccessModifierPublic? 'class' Identifier OpenCurlyBracket (constuctorDecl|fieldDecl|methodDecl)*(MainMethodDecl block)? ClosedCurlyBracket;
constuctorDecl: AccessModifierPublic? Identifier OpenRoundBracket parameterList? ClosedRoundBracket block; //Maybe not needed constuctorDecl: AccessModifierPublic? Identifier OpenRoundBracket parameterList? ClosedRoundBracket block; //Method without
//Method and FieldVar //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; fieldDecl: AccessModifierPublic? type Identifier Semicolon;
//Parameters //Parameters
@ -17,16 +17,20 @@ parameter: type Identifier;
//property, object.a, 3+1, a = 3 //property, object.a, 3+1, a = 3
expression: subExpression | binaryExpr; expression: subExpression | binaryExpr;
//subExpression to dissolve left-recusion //subExpression to dissolve left-recusion
subExpression: This | Identifier | instVar | value | stmtExpr | notExpr | OpenRoundBracket expression ClosedRoundBracket; subExpression: This | assignableExpr | stmtExpr | OpenRoundBracket subExpression ClosedRoundBracket;
notExpr: Not expression;
assignableExpr: Identifier | instVar; assignableExpr: Identifier | instVar;
instVar: This Dot Identifier | (This Dot)? (Identifier Dot)+ Identifier; instVar: subReceiver? receivingMethod* Identifier;
//.trim().toLength().toLowerCase().count ... //.trim().toLength().toLowerCase().count ...
methodCall: receiver? receivingMethod* Identifier OpenRoundBracket argumentList ClosedRoundBracket; 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; calcExpr: calcExpr LineOperator dotExpr | dotExpr;
dotExpr: dotExpr DotOperator dotSubExpr | dotSubExpr; dotExpr: dotExpr DotOperator dotSubExpr | dotSubExpr;
@ -44,14 +48,14 @@ statement: returnStmt Semicolon | localVarDecl Semicolon | block | whileStmt | i
returnStmt: Return (expression)?; returnStmt: Return (expression)?;
localVarDecl: type Identifier (Assign expression)?; localVarDecl: type Identifier (Assign expression)?;
block: OpenCurlyBracket statement* ClosedCurlyBracket; block: OpenCurlyBracket statement* ClosedCurlyBracket;
whileStmt: While OpenRoundBracket expression ClosedRoundBracket block; whileStmt: While OpenRoundBracket expression ClosedRoundBracket statement;
ifElseStmt: ifStmt elseStmt?; ifElseStmt: ifStmt elseStmt?;
ifStmt: If OpenRoundBracket expression ClosedRoundBracket statement; ifStmt: If OpenRoundBracket expression ClosedRoundBracket statement;
elseStmt: Else statement; elseStmt: Else statement;
assign: assignableExpr Assign expression; assign: assignableExpr Assign expression;
newDecl: New Identifier OpenRoundBracket argumentList ClosedRoundBracket; newDecl: New Identifier OpenRoundBracket argumentList ClosedRoundBracket;
receiver: ((This | instVar | newDecl | Identifier) Dot);
receivingMethod: Identifier OpenRoundBracket argumentList ClosedRoundBracket Dot;
type: Int | Boolean | Char | Identifier; type: Int | Boolean | Char | Identifier;
value: IntValue | BooleanValue | CharValue | NullValue; value: IntValue | BooleanValue | CharValue | NullValue;
@ -59,11 +63,7 @@ value: IntValue | BooleanValue | CharValue | NullValue;
AccessModifierPublic : 'public' ; AccessModifierPublic : 'public' ;
MainMethodDecl : 'public static void main(String[] args)'; MainMethodDecl : 'public static void main(String[] args)';
//Types
Void : 'void';
Int : 'int';
Boolean : 'bool';
Char : 'char';
//Operators //Operators
DotOperator : Multipilkation | Division | Modulo; DotOperator : Multipilkation | Division | Modulo;
@ -102,7 +102,6 @@ This : 'this';
While : 'while'; While : 'while';
If : 'if'; If : 'if';
Else : 'else'; Else : 'else';
For : 'for';
Return : 'return'; Return : 'return';
New : 'new'; New : 'new';
@ -112,6 +111,12 @@ fragment Numeric: [0-9];
fragment ValidIdentSymbols : Alpabetic|Numeric|'$'|'_'; fragment ValidIdentSymbols : Alpabetic|Numeric|'$'|'_';
Identifier: Alpabetic ValidIdentSymbols*; Identifier: Alpabetic ValidIdentSymbols*;
//Types
Void : 'void';
Int : 'int';
Boolean : 'bool';
Char : 'char';
//Values //Values
IntValue : ('+'|'-')*[0-9]+; IntValue : ('+'|'-')*[0-9]+;
CharValue: '\''~[\r\n]?'\''; CharValue: '\''~[\r\n]?'\'';

View File

@ -4,6 +4,7 @@ import TypeCheck.AbstractType;
import TypeCheck.TypeCheckHelper; import TypeCheck.TypeCheckHelper;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Program; import abstractSyntaxTree.Program;
import org.objectweb.asm.ClassWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -32,4 +33,9 @@ public class FieldDecl extends AbstractType implements IClass{
//write field table //write field table
} }
@Override
public void codeGen(ClassWriter cw) {
}
} }

View File

@ -1,9 +1,15 @@
package abstractSyntaxTree.Class; package abstractSyntaxTree.Class;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.TypeReference;
import java.util.List; import java.util.List;
public interface IClass { public interface IClass {
// visit method for code generation // visit method for code generation
TypeCheckResult typeCheck() throws Exception;
void codeGen(ClassWriter cw) throws Exception;
} }

View File

@ -1,6 +1,8 @@
package abstractSyntaxTree.Class; package abstractSyntaxTree.Class;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Program;
import org.objectweb.asm.ClassWriter;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -23,4 +25,5 @@ public class MethodDecl implements IClass {
// jede methode als block statement aufrufen // jede methode als block statement aufrufen
return null; return null;
} }
} }

View File

@ -1,17 +1,19 @@
package abstractSyntaxTree.Datatype; package abstractSyntaxTree.Class;
import TypeCheck.AbstractType; import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Class.FieldDecl; import abstractSyntaxTree.Class.FieldDecl;
import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.MethodDecl;
import abstractSyntaxTree.Datatype.IDatatype;
import abstractSyntaxTree.Program; import abstractSyntaxTree.Program;
import jdk.jshell.spi.ExecutionControl; import jdk.jshell.spi.ExecutionControl;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
public class RefType extends AbstractType implements IDatatype { public class RefType extends AbstractType implements IClass {
public String name; public String name;
public List<FieldDecl> fieldDecls; public List<FieldDecl> fieldDecls;
@ -51,7 +53,7 @@ public class RefType extends AbstractType implements IDatatype {
// 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
@Override @Override
public void codeGen(MethodVisitor mv) throws Exception { public void codeGen(ClassWriter cw) throws Exception {
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for RefType"); throw new ExecutionControl.NotImplementedException("CodeGen not implemented for RefType");
} }

View File

@ -1,7 +1,7 @@
package abstractSyntaxTree.Expression; package abstractSyntaxTree.Expression;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Datatype.RefType; import abstractSyntaxTree.Class.RefType;
import jdk.jshell.spi.ExecutionControl; import jdk.jshell.spi.ExecutionControl;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;

View File

@ -5,8 +5,17 @@ import abstractSyntaxTree.Class.FieldDecl;
import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.MethodDecl;
import abstractSyntaxTree.Datatype.RefType; import abstractSyntaxTree.Datatype.RefType;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import abstractSyntaxTree.Class.RefType;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import java.util.*; import java.util.*;
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 class Program {
public List<RefType> classes; public List<RefType> classes;
@ -37,8 +46,36 @@ public class Program {
} }
public void codeGen() throws Exception{ public void codeGen() throws Exception{
for(RefType oneClass : classes){ try (JarOutputStream jos = new JarOutputStream(new FileOutputStream("output.jar"))) {
//oneClass.codeGen(); 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();
// 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();
}
*/
} }
} }

View File

@ -3,7 +3,7 @@ package abstractSyntaxTree.StatementExpression;
import TypeCheck.AbstractType; import TypeCheck.AbstractType;
import TypeCheck.TypeCheckResult; import TypeCheck.TypeCheckResult;
import abstractSyntaxTree.Class.MethodDecl; import abstractSyntaxTree.Class.MethodDecl;
import abstractSyntaxTree.Datatype.RefType; import abstractSyntaxTree.Class.RefType;
import abstractSyntaxTree.Expression.IExpression; import abstractSyntaxTree.Expression.IExpression;
import abstractSyntaxTree.Statement.IStatement; import abstractSyntaxTree.Statement.IStatement;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@ -42,15 +42,12 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
return result; return result;
} }
//Errors occur due to the change in parameter in the RefType class
@Override @Override
public void codeGen(MethodVisitor mv) throws Exception {
}
public void CodeGen(MethodVisitor mv) throws Exception { public void CodeGen(MethodVisitor mv) throws Exception {
//Generate Bytecode for the receiver //Generate Bytecode for the receiver
if(classThatHasTheMethodIfNotThis != null){ if(classThatHasTheMethodIfNotThis != null){
classThatHasTheMethodIfNotThis.codeGen(mv); classThatHasTheMethodIfNotThis.codeGen();
} else { } else {
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);
} }