Merge pull request #6714 from ethereum/finishERC20

Finish ERC20
This commit is contained in:
chriseth
2019-05-13 10:00:38 +02:00
committed by GitHub
7 changed files with 172 additions and 28 deletions
@@ -294,17 +294,19 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
}
else
{
solUnimplementedAssert(_binOp.getOperator() == Token::Add, "");
if (IntegerType const* type = dynamic_cast<IntegerType const*>(commonType))
{
solUnimplementedAssert(!type->isSigned(), "");
defineExpression(_binOp) <<
m_utils.overflowCheckedUIntAddFunction(type->numBits()) <<
"(" <<
expressionAsType(_binOp.leftExpression(), *commonType) <<
", " <<
expressionAsType(_binOp.rightExpression(), *commonType) <<
")\n";
string left = expressionAsType(_binOp.leftExpression(), *commonType);
string right = expressionAsType(_binOp.rightExpression(), *commonType);
string fun;
if (_binOp.getOperator() == Token::Add)
fun = m_utils.overflowCheckedUIntAddFunction(type->numBits());
else if (_binOp.getOperator() == Token::Sub)
fun = m_utils.overflowCheckedUIntSubFunction();
else
solUnimplementedAssert(false, "");
defineExpression(_binOp) << fun << "(" << left << ", " << right << ")\n";
}
else
solUnimplementedAssert(false, "");
@@ -375,7 +377,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(!functionType->bound(), "");
if (auto functionDef = dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
{
// @TODO The function can very well return multiple vars.
defineExpression(_functionCall) <<
m_context.virtualFunctionName(*functionDef) <<
"(" <<
@@ -385,7 +386,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
}
}
// @TODO The function can very well return multiple vars.
args = vector<string>{m_context.variable(_functionCall.expression())} + args;
defineExpression(_functionCall) <<
m_context.internalDispatch(functionType->parameterTypes().size(), functionType->returnParameterTypes().size()) <<
@@ -973,7 +973,10 @@ string IRGeneratorForStatements::expressionAsType(Expression const& _expression,
ostream& IRGeneratorForStatements::defineExpression(Expression const& _expression)
{
return m_code << "let " << m_context.variable(_expression) << " := ";
string vars = m_context.variable(_expression);
if (!vars.empty())
m_code << "let " << move(vars) << " := ";
return m_code;
}
ostream& IRGeneratorForStatements::defineExpressionPart(Expression const& _expression, size_t _part)