aboutsummaryrefslogtreecommitdiffstats
path: root/AST.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-12-19 01:53:43 +0800
committerChristian <c@ethdev.com>2014-12-19 07:12:04 +0800
commit7dc7827907087c25d89589244f7fa57f5a66e48d (patch)
treefa011514eb4cc8f56e4fec008422e19d6bb0901c /AST.cpp
parent59835e9df19332397d6e16b25bfe0dac4807996c (diff)
downloaddexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar
dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.gz
dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.bz2
dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.lz
dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.xz
dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.zst
dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.zip
Possibility for binary operators to yield types different from their operands'.
Diffstat (limited to 'AST.cpp')
-rw-r--r--AST.cpp35
1 files changed, 15 insertions, 20 deletions
diff --git a/AST.cpp b/AST.cpp
index 1fa6d8f6..c7d617b4 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -180,12 +180,18 @@ void Assignment::checkTypeRequirements()
//@todo later, assignments to structs might be possible, but not to mappings
if (!m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue())
BOOST_THROW_EXCEPTION(createTypeError("Assignment to non-local non-value lvalue."));
- m_rightHandSide->expectType(*m_leftHandSide->getType());
m_type = m_leftHandSide->getType();
- if (m_assigmentOperator != Token::ASSIGN)
+ if (m_assigmentOperator == Token::ASSIGN)
+ m_rightHandSide->expectType(*m_type);
+ else
+ {
// compound assignment
- if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator)))
+ m_rightHandSide->checkTypeRequirements();
+ TypePointer resultType = Type::binaryOperatorResult(Token::AssignmentToBinaryOp(m_assigmentOperator),
+ m_type, m_rightHandSide->getType());
+ if (!resultType || *resultType != *m_type)
BOOST_THROW_EXCEPTION(createTypeError("Operator not compatible with type."));
+ }
}
void ExpressionStatement::checkTypeRequirements()
@@ -225,24 +231,13 @@ void BinaryOperation::checkTypeRequirements()
{
m_left->checkTypeRequirements();
m_right->checkTypeRequirements();
- if (m_right->getType()->isImplicitlyConvertibleTo(*m_left->getType()))
- m_commonType = m_left->getType();
- else if (m_left->getType()->isImplicitlyConvertibleTo(*m_right->getType()))
- m_commonType = m_right->getType();
- else
- BOOST_THROW_EXCEPTION(createTypeError("No common type found in binary operation: " +
- m_left->getType()->toString() + " vs. " +
+ m_commonType = Type::binaryOperatorResult(m_operator, m_left->getType(), m_right->getType());
+ if (!m_commonType)
+ BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) +
+ " not compatible with types " +
+ m_left->getType()->toString() + " and " +
m_right->getType()->toString()));
- if (Token::isCompareOp(m_operator))
- m_type = make_shared<BoolType>();
- else
- {
- m_type = m_commonType;
- if (!m_commonType->acceptsBinaryOperator(m_operator))
- BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) +
- " not compatible with type " +
- m_commonType->toString()));
- }
+ m_type = Token::isCompareOp(m_operator) ? make_shared<BoolType>() : m_commonType;
}
void FunctionCall::checkTypeRequirements()