Show restricted instruction warning before argument mismatch issue

This commit is contained in:
Alex Beregszaszi 2018-01-08 00:39:22 +00:00
parent 767052f2f7
commit 42f8875770
2 changed files with 15 additions and 15 deletions

View File

@ -254,17 +254,6 @@ assembly::Expression Parser::parseExpression()
if (operation.type() == typeid(Instruction))
{
Instruction const& instr = boost::get<Instruction>(operation);
// Enforce functional notation for instructions requiring multiple arguments.
int args = instructionInfo(instr.instruction).args;
bool requireFunctionalNotation = (args > 0 || m_flavour != AsmFlavour::Loose);
if (requireFunctionalNotation && currentToken() != Token::LParen)
fatalParserError(string(
"Expected token \"(\" (\"" +
instructionNames().at(instr.instruction) +
"\" expects " +
boost::lexical_cast<string>(args) +
" arguments)"
));
// Disallow instructions returning multiple values (and DUP/SWAP) as expression.
if (
instructionInfo(instr.instruction).ret != 1 ||
@ -276,6 +265,17 @@ assembly::Expression Parser::parseExpression()
instructionNames().at(instr.instruction) +
"\" not allowed in this context."
);
// Enforce functional notation for instructions requiring multiple arguments.
int args = instructionInfo(instr.instruction).args;
bool requireFunctionalNotation = (args > 0 || m_flavour != AsmFlavour::Loose);
if (requireFunctionalNotation && currentToken() != Token::LParen)
fatalParserError(string(
"Expected token \"(\" (\"" +
instructionNames().at(instr.instruction) +
"\" expects " +
boost::lexical_cast<string>(args) +
" arguments)"
));
}
if (currentToken() == Token::LParen)
return parseCall(std::move(operation));

View File

@ -480,11 +480,11 @@ BOOST_AUTO_TEST_CASE(no_opcodes_in_strict)
{
BOOST_CHECK(successParse("{ pop(callvalue) }"));
BOOST_CHECK(successParse("{ callvalue pop }"));
CHECK_STRICT_ERROR("{ pop(callvalue) }", ParserError, "Expected token \"(\" (\"callvalue\" expects 0 arguments)");
CHECK_STRICT_ERROR("{ pop(callvalue) }", ParserError, "Instruction \"callvalue\" not allowed in this context");
CHECK_STRICT_ERROR("{ callvalue pop }", ParserError, "Call or assignment expected");
SUCCESS_STRICT("{ pop(callvalue()) }");
BOOST_CHECK(successParse("{ switch callvalue case 0 {} }"));
CHECK_STRICT_ERROR("{ switch callvalue case 0 {} }", ParserError, "Expected token \"(\" (\"callvalue\" expects 0 arguments)");
CHECK_STRICT_ERROR("{ switch callvalue case 0 {} }", ParserError, "Instruction \"callvalue\" not allowed in this context");
}
BOOST_AUTO_TEST_CASE(no_labels_in_strict)
@ -509,8 +509,8 @@ BOOST_AUTO_TEST_CASE(no_dup_swap_in_strict)
CHECK_STRICT_ERROR("{ swap2 }", ParserError, "Call or assignment expected.");
BOOST_CHECK(successParse("{ dup2 pop }"));
CHECK_STRICT_ERROR("{ dup2 pop }", ParserError, "Call or assignment expected.");
CHECK_PARSE_ERROR("{ switch dup1 case 0 {} }", ParserError, "Expected token \"(\" (\"dup1\" expects 1 arguments)");
CHECK_STRICT_ERROR("{ switch dup1 case 0 {} }", ParserError, "Expected token \"(\" (\"dup1\" expects 1 arguments)");
CHECK_PARSE_ERROR("{ switch dup1 case 0 {} }", ParserError, "Instruction \"dup1\" not allowed in this context");
CHECK_STRICT_ERROR("{ switch dup1 case 0 {} }", ParserError, "Instruction \"dup1\" not allowed in this context");
}
BOOST_AUTO_TEST_SUITE_END()