[Sol -> Yul] Implement unary -, +

This commit is contained in:
Mathias Baumann
2019-05-20 16:14:46 +02:00
parent 7dbcb80523
commit 86000fdcce
4 changed files with 69 additions and 6 deletions
+22
View File
@@ -1088,6 +1088,28 @@ std::string YulUtilFunctions::incrementCheckedFunction(Type const& _type)
});
}
string YulUtilFunctions::negateNumberCheckedFunction(Type const& _type)
{
IntegerType const& type = dynamic_cast<IntegerType const&>(_type);
solAssert(type.isSigned(), "Expected signed type!");
string const functionName = "negate_" + _type.identifier();
u256 const minintval = 0 - (u256(1) << (type.numBits() - 1)) + 1;
return m_functionCollector->createFunction(functionName, [&]() {
return Whiskers(R"(
function <functionName>(_value) -> ret {
if slt(_value, <minval>) { revert(0,0) }
ret := sub(0, _value)
}
)")
("functionName", functionName)
("minval", toCompactHexWithPrefix(minintval))
.render();
});
}
string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const& _to)
{
string functionName =
+2
View File
@@ -179,6 +179,8 @@ public:
std::string incrementCheckedFunction(Type const& _type);
std::string decrementCheckedFunction(Type const& _type);
std::string negateNumberCheckedFunction(Type const& _type);
private:
/// Special case of conversionFunction - handles everything that does not
/// use exactly one variable to hold the value.
@@ -265,24 +265,40 @@ void IRGeneratorForStatements::endVisit(UnaryOperation const& _unaryOperation)
) <<
"(" <<
originalValue <<
")\n" <<
m_currentLValue->storeValue(modifiedValue, resultType);
")\n";
m_code << m_currentLValue->storeValue(modifiedValue, resultType);
m_currentLValue.reset();
defineExpression(_unaryOperation) <<
(_unaryOperation.isPrefixOperation() ? modifiedValue : originalValue) <<
"\n";
m_code << m_currentLValue->storeValue(modifiedValue, resultType);
m_currentLValue.reset();
}
else if (op == Token::BitNot)
appendSimpleUnaryOperation(_unaryOperation, _unaryOperation.subExpression());
else if (op == Token::Add)
// According to SyntaxChecker...
solAssert(false, "Use of unary + is disallowed.");
else if (op == Token::Sub)
{
IntegerType const& intType = *dynamic_cast<IntegerType const*>(&resultType);
defineExpression(_unaryOperation) <<
m_utils.negateNumberCheckedFunction(intType) <<
"(" <<
m_context.variable(_unaryOperation.subExpression()) <<
")\n";
}
else
solUnimplementedAssert(false, "Unary operator not yet implemented");
}
else if (resultType.category() == Type::Category::Bool)
{
appendSimpleUnaryOperation(_unaryOperation, _unaryOperation.subExpression());
solAssert(
_unaryOperation.getOperator() != Token::BitNot,
"Bitwise Negation can't be done on bool!"
);
appendSimpleUnaryOperation(_unaryOperation, _unaryOperation.subExpression());
}
else
solUnimplementedAssert(false, "Unary operator not yet implemented");