Assembly: Removing some more strict-assembly syntax from parser.

This commit is contained in:
Christian Parpart 2019-09-10 11:37:29 +02:00
parent e23998fc6e
commit fdbbf75e78

View File

@ -206,8 +206,7 @@ Statement Parser::parseStatement()
return Statement{std::move(assignment)};
}
default:
if (m_dialect.flavour != AsmFlavour::Loose)
fatalParserError("Call or assignment expected.");
fatalParserError("Call or assignment expected.");
break;
}
@ -279,45 +278,8 @@ Expression Parser::parseExpression()
ElementaryOperation operation = parseElementaryOperation();
if (operation.type() == typeid(FunctionCall))
return parseCall(std::move(operation));
else if (operation.type() == typeid(Instruction))
{
solAssert(m_dialect.flavour == AsmFlavour::Loose, "");
Instruction const& instr = boost::get<Instruction>(operation);
// 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 (m_dialect.flavour != AsmFlavour::Loose && currentToken() != Token::LParen)
fatalParserError(
"Non-functional instructions are not allowed in this context."
);
// Enforce functional notation for instructions requiring multiple arguments.
int args = instructionInfo(instr.instruction).args;
if (args > 0 && currentToken() != Token::LParen)
fatalParserError(string(
"Expected '(' (instruction \"" +
instructionNames().at(instr.instruction) +
"\" expects " +
to_string(args) +
" arguments)"
));
}
if (currentToken() == Token::LParen)
else if (currentToken() == Token::LParen)
return parseCall(std::move(operation));
else if (operation.type() == typeid(Instruction))
{
// Instructions not taking arguments are allowed as expressions.
solAssert(m_dialect.flavour == AsmFlavour::Loose, "");
Instruction& instr = boost::get<Instruction>(operation);
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
}
else if (operation.type() == typeid(Identifier))
return boost::get<Identifier>(operation);
else
@ -359,21 +321,7 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
{
Identifier identifier{location(), literal};
advance();
// If the builtin is not followed by `(` and we are in loose mode,
// fall back to instruction.
if (
m_dialect.flavour == AsmFlavour::Loose &&
instructions().count(identifier.name.str()) &&
m_scanner->currentToken() != Token::LParen
)
return Instruction{identifier.location, instructions().at(identifier.name.str())};
else
return FunctionCall{identifier.location, identifier, {}};
}
else if (m_dialect.flavour == AsmFlavour::Loose && instructions().count(literal.str()))
{
dev::eth::Instruction const& instr = instructions().at(literal.str());
ret = Instruction{location(), instr};
return FunctionCall{identifier.location, identifier, {}};
}
else
ret = Identifier{location(), literal};
@ -623,8 +571,6 @@ YulString Parser::expectAsmIdentifier()
if (m_dialect.builtin(name))
fatalParserError("Cannot use builtin function name \"" + name.str() + "\" as identifier name.");
else if (m_dialect.flavour == AsmFlavour::Loose && instructions().count(name.str()))
fatalParserError("Cannot use instruction name \"" + name.str() + "\" as identifier name.");
advance();
return name;
}