Allow implicit type conversions for comparisons.

This commit is contained in:
Christian 2014-11-04 15:01:07 +01:00
parent de493c673f
commit 29c9a7aed9
2 changed files with 10 additions and 14 deletions

3
AST.h
View File

@ -565,12 +565,15 @@ public:
Expression& getLeftExpression() const { return *m_left; }
Expression& getRightExpression() const { return *m_right; }
Token::Value getOperator() const { return m_operator; }
Type const& getCommonType() const { return *m_commonType; }
private:
ASTPointer<Expression> m_left;
Token::Value m_operator;
ASTPointer<Expression> m_right;
/// The common type that is used for the operation, not necessarily the result type (e.g. for
/// comparisons, this is always bool).
std::shared_ptr<Type const> m_commonType;
};

View File

@ -113,7 +113,7 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
{
Expression& leftExpression = _binaryOperation.getLeftExpression();
Expression& rightExpression = _binaryOperation.getRightExpression();
Type const& resultType = *_binaryOperation.getType();
Type const& commonType = _binaryOperation.getCommonType();
Token::Value const op = _binaryOperation.getOperator();
if (op == Token::AND || op == Token::OR)
@ -121,23 +121,16 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
// special case: short-circuiting
appendAndOrOperatorCode(_binaryOperation);
}
else if (Token::isCompareOp(op))
{
leftExpression.accept(*this);
rightExpression.accept(*this);
// the types to compare have to be the same, but the resulting type is always bool
if (asserts(*leftExpression.getType() == *rightExpression.getType()))
BOOST_THROW_EXCEPTION(InternalCompilerError());
appendCompareOperatorCode(op, *leftExpression.getType());
}
else
{
leftExpression.accept(*this);
cleanHigherOrderBitsIfNeeded(*leftExpression.getType(), resultType);
cleanHigherOrderBitsIfNeeded(*leftExpression.getType(), commonType);
rightExpression.accept(*this);
cleanHigherOrderBitsIfNeeded(*rightExpression.getType(), resultType);
appendOrdinaryBinaryOperatorCode(op, resultType);
cleanHigherOrderBitsIfNeeded(*rightExpression.getType(), commonType);
if (Token::isCompareOp(op))
appendCompareOperatorCode(op, commonType);
else
appendOrdinaryBinaryOperatorCode(op, commonType);
}
// do not visit the child nodes, we already did that explicitly