Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0f61e843a4
@ -17,7 +17,7 @@ public class BoolDatatype extends AbstractType implements IDatatype{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
if(value) {
|
if(value) {
|
||||||
mv.visitInsn(Opcodes.ICONST_1); // Pushes the int 1 on the stack (true)
|
mv.visitInsn(Opcodes.ICONST_1); // Pushes the int 1 on the stack (true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,7 +17,7 @@ public class CharDatatype extends AbstractType implements IDatatype{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
// Possible use of BIPUSH and SIPUSH if the value is small enough
|
// Possible use of BIPUSH and SIPUSH if the value is small enough
|
||||||
//This saves space in the bytecode which is not very relevant at this point, but could be implemented anyway
|
//This saves space in the bytecode which is not very relevant at this point, but could be implemented anyway
|
||||||
|
@ -9,7 +9,7 @@ public interface IDatatype {
|
|||||||
|
|
||||||
// visit method for code generation
|
// visit method for code generation
|
||||||
|
|
||||||
void CodeGen(MethodVisitor mv) throws Exception;
|
void codeGen(MethodVisitor mv) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Check if we need to differentiate between primitive types and reference types --> for example in "=="
|
//TODO: Check if we need to differentiate between primitive types and reference types --> for example in "=="
|
@ -21,7 +21,7 @@ public class IntDatatype extends AbstractType implements IDatatype{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
//Example of using BIPUSH and SIPUSH for optimizing bytecode size
|
//Example of using BIPUSH and SIPUSH for optimizing bytecode size
|
||||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
||||||
|
@ -6,6 +6,7 @@ import abstractSyntaxTree.Class.FieldDecl;
|
|||||||
import abstractSyntaxTree.Class.MethodDecl;
|
import abstractSyntaxTree.Class.MethodDecl;
|
||||||
import abstractSyntaxTree.Program;
|
import abstractSyntaxTree.Program;
|
||||||
import jdk.jshell.spi.ExecutionControl;
|
import jdk.jshell.spi.ExecutionControl;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -50,7 +51,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(MethodVisitor mv) throws Exception {
|
||||||
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for RefType");
|
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for RefType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
// Label for the jump instruction
|
// Label for the jump instruction
|
||||||
Label operationFalse = new Label(); //Operation is false
|
Label operationFalse = new Label(); //Operation is false
|
||||||
Label operationTrue = new Label(); //Operation is true
|
Label operationTrue = new Label(); //Operation is true
|
||||||
@ -69,88 +69,88 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
|||||||
// Bytecode for the binary operation
|
// Bytecode for the binary operation
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case "&&":
|
case "&&":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // IFEQ --> "if equals to zero" (false) --> if left exp is false
|
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // IFEQ --> "if equals to zero" (false) --> if left exp is false
|
||||||
|
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // If right exp is false, jump to the end of the whole expression
|
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // If right exp is false, jump to the end of the whole expression
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, operationTrue); // If it reaches this point, the right exp is true
|
mv.visitJumpInsn(Opcodes.GOTO, operationTrue); // If it reaches this point, the right exp is true
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "||":
|
case "||":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
mv.visitJumpInsn(Opcodes.IFNE, operationTrue); // IFNE --> "if not equals to zero" (true) --> if left exp is true
|
mv.visitJumpInsn(Opcodes.IFNE, operationTrue); // IFNE --> "if not equals to zero" (true) --> if left exp is true
|
||||||
|
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
mv.visitJumpInsn(Opcodes.IFNE, operationTrue);
|
mv.visitJumpInsn(Opcodes.IFNE, operationTrue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "==":
|
case "==":
|
||||||
// Keep in mind that only primitive types are allowed in this case (at this time)
|
// Keep in mind that only primitive types are allowed in this case (at this time)
|
||||||
|
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression
|
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "<":
|
case "<":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPLT, operationTrue); // Checks only on less than, not equal
|
mv.visitJumpInsn(Opcodes.IF_ICMPLT, operationTrue); // Checks only on less than, not equal
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ">":
|
case ">":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPGT, operationTrue); // Checks only on greater than, not equal
|
mv.visitJumpInsn(Opcodes.IF_ICMPGT, operationTrue); // Checks only on greater than, not equal
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "<=":
|
case "<=":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPLE, operationTrue); // Checks on less than OR equal
|
mv.visitJumpInsn(Opcodes.IF_ICMPLE, operationTrue); // Checks on less than OR equal
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ">=":
|
case ">=":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPGE, operationTrue); // Checks on greater than OR equal
|
mv.visitJumpInsn(Opcodes.IF_ICMPGE, operationTrue); // Checks on greater than OR equal
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "!=":
|
case "!=":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IF_ICMPNE, operationTrue); // Checks on not equal
|
mv.visitJumpInsn(Opcodes.IF_ICMPNE, operationTrue); // Checks on not equal
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "+":
|
case "+":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
mv.visitInsn(Opcodes.IADD);
|
mv.visitInsn(Opcodes.IADD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "-":
|
case "-":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
mv.visitInsn(Opcodes.ISUB);
|
mv.visitInsn(Opcodes.ISUB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "*":
|
case "*":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
mv.visitInsn(Opcodes.IMUL);
|
mv.visitInsn(Opcodes.IMUL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "/":
|
case "/":
|
||||||
left.CodeGen(mv);
|
left.codeGen(mv);
|
||||||
right.CodeGen(mv);
|
right.codeGen(mv);
|
||||||
mv.visitInsn(Opcodes.IDIV);
|
mv.visitInsn(Opcodes.IDIV);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -8,5 +8,5 @@ public interface IExpression {
|
|||||||
TypeCheckResult typeCheck() throws Exception;
|
TypeCheckResult typeCheck() throws Exception;
|
||||||
|
|
||||||
// visit method for code generation
|
// visit method for code generation
|
||||||
void CodeGen(MethodVisitor mv) throws Exception;
|
void codeGen(MethodVisitor mv) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public class InstVarExpression implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for InstVarExpression");
|
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for InstVarExpression");
|
||||||
|
|
||||||
//ALOAD the index of the var
|
//ALOAD the index of the var
|
||||||
|
@ -42,9 +42,9 @@ public class UnaryExpression extends AbstractType implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
operand.CodeGen(mv);
|
operand.codeGen(mv);
|
||||||
|
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case "!":
|
case "!":
|
||||||
|
@ -17,7 +17,7 @@ public class VarRefExpression implements IExpression{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
throw new Exception("CodeGen not implemented for VarRefExpression");
|
throw new Exception("CodeGen not implemented for VarRefExpression");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package abstractSyntaxTree;
|
|||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import abstractSyntaxTree.Class.FieldDecl;
|
import abstractSyntaxTree.Class.FieldDecl;
|
||||||
import abstractSyntaxTree.Datatype.RefType;
|
import abstractSyntaxTree.Datatype.RefType;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -2,6 +2,7 @@ package abstractSyntaxTree.Statement;
|
|||||||
|
|
||||||
import TypeCheck.TypeCheckResult;
|
import TypeCheck.TypeCheckResult;
|
||||||
import TypeCheck.AbstractType;
|
import TypeCheck.AbstractType;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -40,9 +41,9 @@ public class BlockStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
for (IStatement statement : statements) {
|
for (IStatement statement : statements) {
|
||||||
statement.CodeGen(mv); //TODO: I think we need to pass the symbol table here
|
statement.codeGen(mv); //TODO: I think we need to pass the symbol table here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ public class EmptyStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
//An empty statement does not generate any code
|
//An empty statement does not generate any code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,5 @@ public interface IStatement {
|
|||||||
|
|
||||||
TypeCheckResult typeCheck() throws Exception;
|
TypeCheckResult typeCheck() throws Exception;
|
||||||
|
|
||||||
void CodeGen(MethodVisitor mv) throws Exception;
|
void codeGen(MethodVisitor mv) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
Label conditionFalse = new Label();
|
Label conditionFalse = new Label();
|
||||||
Label statementEnd = new Label();
|
Label statementEnd = new Label();
|
||||||
@ -46,11 +46,11 @@ public class IfElseStatement extends AbstractType implements IStatement{
|
|||||||
condition.CodeGen(mv);
|
condition.CodeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
||||||
ifStatement.CodeGen(mv); //If the condition is true, execute the ifBlock
|
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.visitJumpInsn(Opcodes.GOTO, statementEnd); //Jump to the end of the if-else statement
|
||||||
|
|
||||||
mv.visitLabel(conditionFalse);
|
mv.visitLabel(conditionFalse);
|
||||||
elseStatement.CodeGen(mv); //If the condition is false, execute the elseBlock
|
elseStatement.codeGen(mv); //If the condition is false, execute the elseBlock
|
||||||
|
|
||||||
mv.visitLabel(statementEnd); //End of the if-else statement
|
mv.visitLabel(statementEnd); //End of the if-else statement
|
||||||
|
|
||||||
|
@ -31,14 +31,14 @@ public class IfStatement extends AbstractType implements IStatement{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
Label conditionFalse = new Label();
|
Label conditionFalse = new Label();
|
||||||
|
|
||||||
condition.CodeGen(mv);
|
condition.CodeGen(mv);
|
||||||
|
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); //Checks if the condition is false (0)
|
||||||
ifStatement.CodeGen(mv);
|
ifStatement.codeGen(mv);
|
||||||
|
|
||||||
mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed
|
mv.visitLabel(conditionFalse); // If the condition is false, the Statements in the ifBlock will not be executed
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public class ReturnStatement extends AbstractType implements IStatement{
|
|||||||
// This is a problem at "BinaryExpression" and here because we need to know the type to return
|
// 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
|
// At this point in time we can either return reference types or have an error message
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
expression.CodeGen(mv);
|
expression.CodeGen(mv);
|
||||||
|
@ -31,16 +31,16 @@ public class WhileStatement extends AbstractType implements IStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
public void codeGen(MethodVisitor mv) throws Exception {
|
||||||
Label conditionFalse = new Label();
|
Label conditionFalse = new Label();
|
||||||
Label LoopStart = new Label();
|
Label LoopStart = new Label();
|
||||||
|
|
||||||
mv.visitLabel(LoopStart);
|
mv.visitLabel(LoopStart);
|
||||||
|
|
||||||
condition.CodeGen(mv);
|
condition.codeGen(mv);
|
||||||
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0)
|
mv.visitJumpInsn(Opcodes.IFEQ, conditionFalse); // Checks if the condition is false (0)
|
||||||
|
|
||||||
statement.CodeGen(mv);
|
statement.codeGen(mv);
|
||||||
//TODO: If the block ends with a return statement, we might have to pop it from the stack
|
//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
|
// So the next iteration starts with a clean stack
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop
|
mv.visitJumpInsn(Opcodes.GOTO, LoopStart); // Jump to the start of the while loop
|
||||||
|
Loading…
Reference in New Issue
Block a user