private Rvalue compileImpl(IntermediateCompiler ic, Scope scope, CType leftType, CType rightType)
      throws SyntaxException {
    // Compile operands.
    Rvalue rhs = right.compileWithConversion(ic, scope, rightType);
    Lvalue lhs = left.compileAsLvalue(ic, scope, false);

    // Load LHS to register.
    Rvalue lhsVal = new Rvalue(new VirtualRegister());
    ic.emit("load", lhsVal.getRegister(), "0", lhs.getRegister());
    lhsVal = left.getType(scope).compileConversion(ic, scope, lhsVal, leftType);

    // Compile the binary operator.
    String binOp = operator.binaryOperator;
    Rvalue retVal;
    if (leftType.isPointer()) {
      // Scale integer operand if necessary.
      int leftIncrSize = left.getType(scope).decay().getIncrementSize();
      if (leftIncrSize > 1) ic.emit("mul", rhs.getRegister(), "=" + leftIncrSize);
      ic.emit(operator.mnemonic, lhsVal.getRegister(), rhs.getRegister());
      retVal = lhsVal;
    } else if (operator.type == BinaryExpression.Type.BITWISE)
      retVal = leftType.compileBinaryBitwiseOperator(ic, scope, lhsVal, rhs, binOp);
    else if (operator.type == BinaryExpression.Type.SHIFT)
      retVal = leftType.compileBinaryShiftOperator(ic, scope, lhsVal, rhs, binOp);
    else // if (operator.type == BinaryExpression.Type.ARITHMETIC)
    retVal = leftType.compileBinaryArithmeticOperator(ic, scope, lhsVal, rhs, binOp);

    // Convert to the original type of the left operand.
    retVal = leftType.compileConversion(ic, scope, retVal, left.getType(scope));

    // Assign result back to lvalue.
    ic.emit("store", retVal.getRegister(), "0", lhs.getRegister());

    return retVal;
  }
  @Override
  public Rvalue compile(IntermediateCompiler ic, Scope scope) throws SyntaxException {
    FunctionType funcType = getFunctionType(scope);

    // Reserve space for return value.
    if (!funcType.getReturnType().equals(CType.VOID))
      ic.emit("add", VirtualRegister.SP, "=" + funcType.getReturnType().getSize());

    // Push arguments to stack.
    argumentList.compile(ic, scope, funcType.getParameterTypes());

    // Evaluate the function pointer.
    Rvalue funcPtrVal = functionPointer.compile(ic, scope);

    // Make the call.
    ic.emit("call", VirtualRegister.SP, funcPtrVal.getRegister());

    // Read the return value.
    VirtualRegister retReg = null;
    if (!funcType.getReturnType().equals(CType.VOID)) {
      retReg = new VirtualRegister();
      ic.emit("pop", VirtualRegister.SP, retReg);
    }

    return new Rvalue(retReg);
  }
 private Rvalue compileSimpleAssignment(IntermediateCompiler ic, Scope scope)
     throws SyntaxException {
   Rvalue rhs = right.compileWithConversion(ic, scope, left.getType(scope).decay());
   Lvalue lhs = left.compileAsLvalue(ic, scope, false);
   ic.emit("store", rhs.getRegister(), "0", lhs.getRegister());
   return rhs;
 }
Beispiel #4
0
  @Override
  public void compile(IntermediateCompiler ic, Scope scope, StackAllocator stack)
      throws SyntaxException {
    Symbol jumpPosition = scope.find("__Brk");

    if (jumpPosition == null)
      throw new SyntaxException("Break used outside loop or switch.", getPosition());

    // Jump to end of the loop/switch
    ic.emit("jump", VirtualRegister.NONE, jumpPosition.getReference());
  }