[Yul] Adds break/continue statements and some general tests for for-loop syntax.

This commit is contained in:
Christian Parpart
2019-03-11 15:05:05 +01:00
committed by Christian Parpart
parent 4704ef843d
commit 05e2d362c8
24 changed files with 277 additions and 10 deletions
+36
View File
@@ -23,6 +23,7 @@
#include <libyul/AsmParser.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/ErrorReporter.h>
#include <libdevcore/Common.h>
#include <boost/algorithm/string.hpp>
@@ -104,6 +105,32 @@ Statement Parser::parseStatement()
}
case Token::For:
return parseForLoop();
case Token::Break:
if (m_insideForLoopBody)
{
auto stmt = Statement{ createWithLocation<Break>() };
m_scanner->next();
return stmt;
}
else
{
m_errorReporter.syntaxError(location(), "Keyword break outside for-loop body is not allowed.");
m_scanner->next();
return {};
}
case Token::Continue:
if (m_insideForLoopBody)
{
auto stmt = Statement{ createWithLocation<Continue>() };
m_scanner->next();
return stmt;
}
else
{
m_errorReporter.syntaxError(location(), "Keyword continue outside for-loop body is not allowed.");
m_scanner->next();
return {};
}
case Token::Assign:
{
if (m_dialect->flavour != AsmFlavour::Loose)
@@ -243,13 +270,19 @@ Case Parser::parseCase()
ForLoop Parser::parseForLoop()
{
bool outerForLoopBody = m_insideForLoopBody;
m_insideForLoopBody = false;
RecursionGuard recursionGuard(*this);
ForLoop forLoop = createWithLocation<ForLoop>();
expectToken(Token::For);
forLoop.pre = parseBlock();
forLoop.condition = make_unique<Expression>(parseExpression());
forLoop.post = parseBlock();
m_insideForLoopBody = true;
forLoop.body = parseBlock();
m_insideForLoopBody = outerForLoopBody;
forLoop.location.end = forLoop.body.location.end;
return forLoop;
}
@@ -455,6 +488,9 @@ VariableDeclaration Parser::parseVariableDeclaration()
FunctionDefinition Parser::parseFunctionDefinition()
{
RecursionGuard recursionGuard(*this);
auto outerForLoopBody = m_insideForLoopBody;
m_insideForLoopBody = false;
ScopeGuard restoreInsideForLoopBody{[&]() { m_insideForLoopBody = outerForLoopBody; }};
FunctionDefinition funDef = createWithLocation<FunctionDefinition>();
expectToken(Token::Function);
funDef.name = expectAsmIdentifier();