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{ public String operator; public IExpression left; public IExpression right; @Override public TypeCheckResult typeCheck() throws Exception { TypeCheckHelper helper = new TypeCheckHelper(); TypeCheckResult result = new TypeCheckResult(); TypeCheckResult leftType = left.typeCheck(); TypeCheckResult rightType = right.typeCheck(); switch (operator) { case "&&": case "||" :{ if (Objects.equals(helper.upperBound(leftType.type, rightType.type), "bool")){ result.type = "bool"; } break; } case "==": case "<": case ">": case "<=": case ">=": case "!=": result.type = helper.upperBound(leftType.type, rightType.type); break; case "-": case "+": case "*": case "/": if (Objects.equals(helper.upperBound(leftType.type, rightType.type), "int")){ result.type = "int"; } break; //case "&" ist für logisches und auf bit level //case "|" ist für logisches oder auf bit level } 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); } }