Added Bytecodegeneration to the missing classes
Also included some TODOs in areas where parameters and some connections are missing
This commit is contained in:
parent
95585d357a
commit
2527d15467
@ -1,10 +1,32 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import abstractSyntaxTree.Datatype.RefType;
|
||||||
|
import jdk.jshell.spi.ExecutionControl;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public class InstVarExpression implements IExpression{
|
public class InstVarExpression implements IExpression{
|
||||||
|
|
||||||
|
//TODO: We have to decide upon more parameters and where they come from, for
|
||||||
|
// example here we need the index of the field, the class reference and the field name
|
||||||
|
private RefType classRef;
|
||||||
|
private String fieldName;
|
||||||
|
|
||||||
|
/* public InstVarExpression(RefType classRef, String fieldName){
|
||||||
|
this.classRef = classRef;
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
}*/
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for InstVarExpression");
|
||||||
|
|
||||||
|
//ALOAD the index of the var
|
||||||
|
//GETFIELD the field
|
||||||
|
//visitFieldInsn(Opcodes.GETFIELD, "class reference", "field name", type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import TypeCheck.AbstractType;
|
|||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Datatype.IDatatype;
|
import abstractSyntaxTree.Datatype.IDatatype;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -38,4 +40,26 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
|
operand.CodeGen(mv);
|
||||||
|
|
||||||
|
switch (operator) {
|
||||||
|
case "!":
|
||||||
|
//XOR with 1 to get the negation
|
||||||
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
|
mv.visitInsn(Opcodes.IXOR);
|
||||||
|
break;
|
||||||
|
case "-":
|
||||||
|
mv.visitInsn(Opcodes.INEG);
|
||||||
|
break;
|
||||||
|
case "+":
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: throw new Exception("Unknown operator :" + operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
package abstractSyntaxTree.Expression;
|
package abstractSyntaxTree.Expression;
|
||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class VarRefExpression implements IExpression{
|
public class VarRefExpression implements IExpression{
|
||||||
|
|
||||||
|
//Parameters that are needed here
|
||||||
|
private String varName;
|
||||||
|
private Map<String, Integer> localVars;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
throw new Exception("CodeGen not implemented for VarRefExpression");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package abstractSyntaxTree.Modifier;
|
package abstractSyntaxTree.Modifier;
|
||||||
|
|
||||||
public interface IModifier {
|
public interface IModifier {
|
||||||
|
|
||||||
|
//TODO: Maybe we can just use an enum for the Modifier
|
||||||
|
// if there is no typeCheck and no CodeGen
|
||||||
|
|
||||||
// not type or type check
|
// not type or type check
|
||||||
|
|
||||||
// visit method for code generation
|
// visit method for code generation
|
||||||
|
@ -3,10 +3,13 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BlockStatement extends AbstractType implements IStatement{
|
public class BlockStatement extends AbstractType implements IStatement{
|
||||||
|
|
||||||
|
//We will need a parameter which holds the symbol table
|
||||||
List<IStatement> statements;
|
List<IStatement> statements;
|
||||||
public BlockStatement(List<IStatement> statements){
|
public BlockStatement(List<IStatement> statements){
|
||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
@ -31,4 +34,11 @@ public class BlockStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
for (IStatement statement : statements) {
|
||||||
|
statement.CodeGen(mv); //TODO: I think we need to pass the symbol table here
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public class EmptyStatement extends AbstractType implements IStatement{
|
public class EmptyStatement extends AbstractType implements IStatement{
|
||||||
@Override
|
@Override
|
||||||
@ -10,4 +11,9 @@ public class EmptyStatement extends AbstractType implements IStatement{
|
|||||||
result.type = "void";
|
result.type = "void";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
//An empty statement does not generate any code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package abstractSyntaxTree.Statement;
|
package abstractSyntaxTree.Statement;
|
||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public interface IStatement {
|
public interface IStatement {
|
||||||
|
|
||||||
TypeCheckResult typeCheck() throws Exception;
|
TypeCheckResult typeCheck() throws Exception;
|
||||||
|
|
||||||
// visit method for code generation
|
void CodeGen(MethodVisitor mv) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
public class IfElseStatement extends AbstractType implements IStatement{
|
public class IfElseStatement extends AbstractType implements IStatement{
|
||||||
IExpression condition;
|
IExpression condition;
|
||||||
@ -35,4 +36,23 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
result.type = elseStatementType.type;
|
result.type = elseStatementType.type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
|
Label conditionFalse = new Label();
|
||||||
|
Label statementEnd = new Label();
|
||||||
|
|
||||||
|
condition.CodeGen(mv);
|
||||||
|
|
||||||
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
||||||
|
ifStatement.CodeGen(mv); //If the condition is true, execute the ifBlock
|
||||||
|
mv.visitJumpInsn(Opcodes.GOTO, statementEnd); //Jump to the end of the if-else statement
|
||||||
|
|
||||||
|
mv.visitLabel(conditionFalse);
|
||||||
|
elseStatement.CodeGen(mv); //If the condition is false, execute the elseBlock
|
||||||
|
|
||||||
|
mv.visitLabel(statementEnd); //End of the if-else statement
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,12 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
public class IfStatement extends AbstractType implements IStatement{
|
public class IfStatement extends AbstractType implements IStatement{
|
||||||
IExpression condition;
|
IExpression condition;
|
||||||
|
|
||||||
|
//Do we need a block statement here?
|
||||||
IStatement ifStatement;
|
IStatement ifStatement;
|
||||||
|
|
||||||
public IfStatement(IExpression condition, IStatement ifStatement) {
|
public IfStatement(IExpression condition, IStatement ifStatement) {
|
||||||
@ -27,6 +30,18 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
|
Label conditionFalse = new Label();
|
||||||
|
|
||||||
|
condition.CodeGen(mv);
|
||||||
|
|
||||||
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
||||||
|
ifStatement.CodeGen(mv);
|
||||||
|
|
||||||
|
mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
public class ReturnStatement extends AbstractType implements IStatement{
|
public class ReturnStatement extends AbstractType implements IStatement{
|
||||||
IExpression expression;
|
IExpression expression;
|
||||||
@ -24,4 +25,27 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: We do not differentiate between primitive types and reference types
|
||||||
|
// This is a problem at "BinaryExpression" and here because we need to know the type to return
|
||||||
|
// At this point in time we can either return reference types or have an error message
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
|
if (expression != null) {
|
||||||
|
expression.CodeGen(mv);
|
||||||
|
//Get the Type of the expression
|
||||||
|
String type = expression.typeCheck().type;
|
||||||
|
|
||||||
|
if (type.equals("int") || type.equals("bool")) {
|
||||||
|
mv.visitInsn(Opcodes.IRETURN);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(Opcodes.ARETURN);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,17 @@ package abstractSyntaxTree.Statement;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
public class WhileStatement extends AbstractType implements IStatement {
|
public class WhileStatement extends AbstractType implements IStatement {
|
||||||
IExpression condition;
|
IExpression condition;
|
||||||
IStatement statement;
|
IStatement statement;
|
||||||
|
|
||||||
public WhileStatement(IExpression condition, IStatement statement) {
|
public WhileStatement(IExpression condition, IStatement statement) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.statement = statement;
|
this.statement = statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
TypeCheckResult result = new TypeCheckResult();
|
TypeCheckResult result = new TypeCheckResult();
|
||||||
@ -26,4 +29,22 @@ public class WhileStatement extends AbstractType implements IStatement{
|
|||||||
result.type = statementType.type;
|
result.type = statementType.type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
Label conditionFalse = new Label();
|
||||||
|
Label LoopStart = new Label();
|
||||||
|
|
||||||
|
mv.visitLabel(LoopStart);
|
||||||
|
|
||||||
|
condition.CodeGen(mv);
|
||||||
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0)
|
||||||
|
|
||||||
|
statement.CodeGen(mv);
|
||||||
|
//TODO: If the block ends with a return statement, we might have to pop it from the stack
|
||||||
|
// So the next iteration starts with a clean stack
|
||||||
|
mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop
|
||||||
|
|
||||||
|
mv.visitLabel(conditionFalse);
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,7 +4,10 @@ import TypeCheck.AbstractType;
|
|||||||
import TypeCheck.TypeCheckHelper;
|
import TypeCheck.TypeCheckHelper;
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
|
import abstractSyntaxTree.Expression.InstVarExpression;
|
||||||
|
import abstractSyntaxTree.Expression.VarRefExpression;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -28,4 +31,20 @@ public class AssignStatementExpression extends AbstractType implements IExpressi
|
|||||||
setTypeCheckResult(result);
|
setTypeCheckResult(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
left.CodeGen(mv);
|
||||||
|
right.CodeGen(mv);
|
||||||
|
|
||||||
|
if (left instanceof VarRefExpression varRef) {
|
||||||
|
//TODO: Implement the handling of a variable reference --> I need a lis of local variables
|
||||||
|
// for that to determine if the variable is a local or field variable
|
||||||
|
} else if (left instanceof InstVarExpression instVar) {
|
||||||
|
mv.visitInsn(Opcodes.DUP_X1);
|
||||||
|
|
||||||
|
// We now again need the owner (class reference), name (of the Field in the owner) and type of the field
|
||||||
|
//mv.visitFieldInsn(Opcodes.PUTFIELD, instVar.className, instVar.varName, instVar.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import abstractSyntaxTree.Class.MethodDecl;
|
|||||||
import abstractSyntaxTree.Datatype.RefType;
|
import abstractSyntaxTree.Datatype.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.Opcodes;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -39,4 +41,22 @@ public class MethodCallStatementExpression extends AbstractType implements IExpr
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
//Generate Bytecode for the receiver
|
||||||
|
if(classThatHasTheMethodIfNotThis != null){
|
||||||
|
classThatHasTheMethodIfNotThis.CodeGen(mv);
|
||||||
|
} else {
|
||||||
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IExpression argument : arguments) {
|
||||||
|
argument.CodeGen(mv);
|
||||||
|
}
|
||||||
|
|
||||||
|
//We need the class reference and the return type of the method
|
||||||
|
//mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, thisClass.name, methodName, return type);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,16 @@ import TypeCheck.AbstractType;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Expression.IExpression;
|
import abstractSyntaxTree.Expression.IExpression;
|
||||||
import abstractSyntaxTree.Statement.IStatement;
|
import abstractSyntaxTree.Statement.IStatement;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
public class NewStatementExpression extends AbstractType implements IExpression, IStatement {
|
public class NewStatementExpression extends AbstractType implements IExpression, IStatement {
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult typeCheck() throws Exception {
|
public TypeCheckResult typeCheck() throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||||
|
throw new Exception("CodeGen not implemented for NewStatementExpression");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user