Added Bytecode generation Logic for datatypes and binary expressions
This commit is contained in:
parent
261cf2f6fa
commit
bd3988004c
@ -2,6 +2,7 @@ package abstractSyntaxTree.Datatype;
|
||||
|
||||
import TypeCheck.AbstractType;
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class BoolDatatype extends AbstractType implements IDatatype{
|
||||
boolean value;
|
||||
@ -14,4 +15,13 @@ public class BoolDatatype extends AbstractType implements IDatatype{
|
||||
setTypeCheckResult(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||
if(value) {
|
||||
mv.visitInsn(Opcodes.ICONST_1); // Pushes the int 1 on the stack (true)
|
||||
} else {
|
||||
mv.visitInsn(Opcodes.ICONST_0); // 0 for false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package abstractSyntaxTree.Datatype;
|
||||
|
||||
import TypeCheck.AbstractType;
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
public class CharDatatype extends AbstractType implements IDatatype{
|
||||
char value;
|
||||
@ -14,4 +15,13 @@ public class CharDatatype extends AbstractType implements IDatatype{
|
||||
setTypeCheckResult(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||
|
||||
// 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
|
||||
|
||||
mv.visitLdcInsn((int)value);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
package abstractSyntaxTree.Datatype;
|
||||
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
public interface IDatatype {
|
||||
// typeCheck method
|
||||
TypeCheckResult typeCheck() throws Exception;
|
||||
|
||||
// visit method for code generation
|
||||
|
||||
void CodeGen(MethodVisitor mv) throws Exception;
|
||||
}
|
||||
|
||||
//TODO: Check if we need to differentiate between primitive types and reference types --> for example in "=="
|
@ -2,6 +2,8 @@ package abstractSyntaxTree.Datatype;
|
||||
|
||||
import TypeCheck.AbstractType;
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class IntDatatype extends AbstractType implements IDatatype{
|
||||
int value;
|
||||
@ -14,4 +16,19 @@ public class IntDatatype extends AbstractType implements IDatatype{
|
||||
setTypeCheckResult(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// visit method for code generation
|
||||
|
||||
|
||||
@Override
|
||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||
|
||||
//Example of using BIPUSH and SIPUSH for optimizing bytecode size
|
||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
||||
mv.visitIntInsn(Opcodes.BIPUSH, value);
|
||||
else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
|
||||
mv.visitIntInsn(Opcodes.SIPUSH, value);
|
||||
else
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import TypeCheck.AbstractType;
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import abstractSyntaxTree.Class.FieldDecl;
|
||||
import abstractSyntaxTree.Class.MethodDecl;
|
||||
import jdk.jshell.spi.ExecutionControl;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -31,4 +33,13 @@ public class RefType extends AbstractType implements IDatatype {
|
||||
setTypeCheckResult(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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 {
|
||||
throw new ExecutionControl.NotImplementedException("CodeGen not implemented for RefType");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package abstractSyntaxTree.Expression;
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import TypeCheck.TypeCheckHelper;
|
||||
import TypeCheck.AbstractType;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.beans.Expression;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BinaryExpression extends AbstractType implements IExpression{
|
||||
@ -54,4 +56,115 @@ public class BinaryExpression extends AbstractType implements IExpression{
|
||||
setTypeCheckResult(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void CodeGen(MethodVisitor mv) throws Exception {
|
||||
// Label for the jump instruction
|
||||
Label operationFalse = new Label(); //Operation is false
|
||||
Label operationTrue = new Label(); //Operation is true
|
||||
// Labels are placed at the end of this method
|
||||
Label expressionEnd = new Label(); //End of the whole expression
|
||||
|
||||
// Bytecode for the binary operation
|
||||
switch (operator) {
|
||||
case "&&":
|
||||
left.CodeGen(mv);
|
||||
mv.visitJumpInsn(Opcodes.IFEQ, operationFalse); // IFEQ --> "if equals to zero" (false) --> if left exp is false
|
||||
|
||||
right.CodeGen(mv);
|
||||
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
|
||||
break;
|
||||
|
||||
case "||":
|
||||
left.CodeGen(mv);
|
||||
mv.visitJumpInsn(Opcodes.IFNE, operationTrue); // IFNE --> "if not equals to zero" (true) --> if left exp is true
|
||||
|
||||
right.CodeGen(mv);
|
||||
mv.visitJumpInsn(Opcodes.IFNE, operationTrue);
|
||||
break;
|
||||
|
||||
case "==":
|
||||
// Keep in mind that only primitive types are allowed in this case (at this time)
|
||||
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPEQ, operationTrue); // If the two values are equal, jump to the end of the expression
|
||||
break;
|
||||
|
||||
case "<":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPLT, operationTrue); // Checks only on less than, not equal
|
||||
break;
|
||||
|
||||
case ">":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPGT, operationTrue); // Checks only on greater than, not equal
|
||||
break;
|
||||
|
||||
case "<=":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPLE, operationTrue); // Checks on less than OR equal
|
||||
break;
|
||||
|
||||
case ">=":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPGE, operationTrue); // Checks on greater than OR equal
|
||||
break;
|
||||
|
||||
case "!=":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
|
||||
mv.visitJumpInsn(Opcodes.IF_ICMPNE, operationTrue); // Checks on not equal
|
||||
break;
|
||||
|
||||
case "+":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
mv.visitInsn(Opcodes.IADD);
|
||||
break;
|
||||
|
||||
case "-":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
mv.visitInsn(Opcodes.ISUB);
|
||||
break;
|
||||
|
||||
case "*":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
mv.visitInsn(Opcodes.IMUL);
|
||||
break;
|
||||
|
||||
case "/":
|
||||
left.CodeGen(mv);
|
||||
right.CodeGen(mv);
|
||||
mv.visitInsn(Opcodes.IDIV);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Unknown operator: " + operator);
|
||||
}
|
||||
|
||||
mv.visitLabel(operationFalse);
|
||||
mv.visitInsn(Opcodes.ICONST_0); // Push false on the stack
|
||||
mv.visitJumpInsn(Opcodes.GOTO, expressionEnd); // Jump to the end of the expression (skip the true push)
|
||||
|
||||
mv.visitLabel(operationTrue);
|
||||
mv.visitInsn(Opcodes.ICONST_1); // Push true on the stack
|
||||
|
||||
mv.visitLabel(expressionEnd);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package abstractSyntaxTree.Expression;
|
||||
|
||||
import TypeCheck.TypeCheckResult;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
public interface IExpression {
|
||||
// typeCheck method
|
||||
TypeCheckResult typeCheck() throws Exception;
|
||||
|
||||
// visit method for code generation
|
||||
void CodeGen(MethodVisitor mv) throws Exception;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user