mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simplify parseElementaryOperation in regards to special instructions
This commit is contained in:
parent
bca01f8f68
commit
fcbdaa32b9
@ -123,7 +123,7 @@ assembly::Statement Parser::parseStatement()
|
|||||||
// Simple instruction (might turn into functional),
|
// Simple instruction (might turn into functional),
|
||||||
// literal,
|
// literal,
|
||||||
// identifier (might turn into label or functional assignment)
|
// identifier (might turn into label or functional assignment)
|
||||||
ElementaryOperation elementary(parseElementaryOperation(false));
|
ElementaryOperation elementary(parseElementaryOperation());
|
||||||
switch (currentToken())
|
switch (currentToken())
|
||||||
{
|
{
|
||||||
case Token::LParen:
|
case Token::LParen:
|
||||||
@ -145,7 +145,7 @@ assembly::Statement Parser::parseStatement()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
expectToken(Token::Comma);
|
expectToken(Token::Comma);
|
||||||
elementary = parseElementaryOperation(false);
|
elementary = parseElementaryOperation();
|
||||||
if (elementary.type() != typeid(assembly::Identifier))
|
if (elementary.type() != typeid(assembly::Identifier))
|
||||||
fatalParserError("Variable name expected in multiple assignemnt.");
|
fatalParserError("Variable name expected in multiple assignemnt.");
|
||||||
assignment.variableNames.emplace_back(boost::get<assembly::Identifier>(elementary));
|
assignment.variableNames.emplace_back(boost::get<assembly::Identifier>(elementary));
|
||||||
@ -247,10 +247,11 @@ assembly::ForLoop Parser::parseForLoop()
|
|||||||
assembly::Expression Parser::parseExpression()
|
assembly::Expression Parser::parseExpression()
|
||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ElementaryOperation operation = parseElementaryOperation(true);
|
ElementaryOperation operation = parseElementaryOperation();
|
||||||
if (operation.type() == typeid(Instruction))
|
if (operation.type() == typeid(Instruction))
|
||||||
{
|
{
|
||||||
Instruction const& instr = boost::get<Instruction>(operation);
|
Instruction const& instr = boost::get<Instruction>(operation);
|
||||||
|
// Enforce functional notation for instructions requiring multiple arguments.
|
||||||
int args = instructionInfo(instr.instruction).args;
|
int args = instructionInfo(instr.instruction).args;
|
||||||
if (args > 0 && currentToken() != Token::LParen)
|
if (args > 0 && currentToken() != Token::LParen)
|
||||||
fatalParserError(string(
|
fatalParserError(string(
|
||||||
@ -260,11 +261,23 @@ assembly::Expression Parser::parseExpression()
|
|||||||
boost::lexical_cast<string>(args) +
|
boost::lexical_cast<string>(args) +
|
||||||
" arguments)"
|
" arguments)"
|
||||||
));
|
));
|
||||||
|
// Disallow instructions returning multiple values (and DUP/SWAP) as expression.
|
||||||
|
if (
|
||||||
|
instructionInfo(instr.instruction).ret != 1 ||
|
||||||
|
isDupInstruction(instr.instruction) ||
|
||||||
|
isSwapInstruction(instr.instruction)
|
||||||
|
)
|
||||||
|
fatalParserError(
|
||||||
|
"Instruction \"" +
|
||||||
|
instructionNames().at(instr.instruction) +
|
||||||
|
"\" not allowed in this context."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (currentToken() == Token::LParen)
|
if (currentToken() == Token::LParen)
|
||||||
return parseCall(std::move(operation));
|
return parseCall(std::move(operation));
|
||||||
else if (operation.type() == typeid(Instruction))
|
else if (operation.type() == typeid(Instruction))
|
||||||
{
|
{
|
||||||
|
// Instructions not taking arguments are allowed as expressions.
|
||||||
Instruction& instr = boost::get<Instruction>(operation);
|
Instruction& instr = boost::get<Instruction>(operation);
|
||||||
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
|
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
|
||||||
}
|
}
|
||||||
@ -317,7 +330,7 @@ std::map<dev::solidity::Instruction, string> const& Parser::instructionNames()
|
|||||||
return s_instructionNames;
|
return s_instructionNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::ElementaryOperation Parser::parseElementaryOperation(bool _onlySinglePusher)
|
Parser::ElementaryOperation Parser::parseElementaryOperation()
|
||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ElementaryOperation ret;
|
ElementaryOperation ret;
|
||||||
@ -341,12 +354,6 @@ Parser::ElementaryOperation Parser::parseElementaryOperation(bool _onlySinglePus
|
|||||||
if (!m_julia && instructions().count(literal))
|
if (!m_julia && instructions().count(literal))
|
||||||
{
|
{
|
||||||
dev::solidity::Instruction const& instr = instructions().at(literal);
|
dev::solidity::Instruction const& instr = instructions().at(literal);
|
||||||
if (_onlySinglePusher)
|
|
||||||
{
|
|
||||||
InstructionInfo info = dev::solidity::instructionInfo(instr);
|
|
||||||
if (info.ret != 1)
|
|
||||||
fatalParserError("Instruction \"" + literal + "\" not allowed in this context.");
|
|
||||||
}
|
|
||||||
ret = Instruction{location(), instr};
|
ret = Instruction{location(), instr};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -70,7 +70,7 @@ protected:
|
|||||||
assembly::Expression parseExpression();
|
assembly::Expression parseExpression();
|
||||||
static std::map<std::string, dev::solidity::Instruction> const& instructions();
|
static std::map<std::string, dev::solidity::Instruction> const& instructions();
|
||||||
static std::map<dev::solidity::Instruction, std::string> const& instructionNames();
|
static std::map<dev::solidity::Instruction, std::string> const& instructionNames();
|
||||||
ElementaryOperation parseElementaryOperation(bool _onlySinglePusher = false);
|
ElementaryOperation parseElementaryOperation();
|
||||||
VariableDeclaration parseVariableDeclaration();
|
VariableDeclaration parseVariableDeclaration();
|
||||||
FunctionDefinition parseFunctionDefinition();
|
FunctionDefinition parseFunctionDefinition();
|
||||||
assembly::Expression parseCall(ElementaryOperation&& _initialOp);
|
assembly::Expression parseCall(ElementaryOperation&& _initialOp);
|
||||||
|
Loading…
Reference in New Issue
Block a user