diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-04 10:56:19 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-09 20:47:27 +0000 |
commit | 128485ccdb4f1c6f1bf1ebea85c5bed749cacd7a (patch) | |
tree | 350c795726910498f2a2ee7f9caa71018ae7ad5a /src/qml/parser | |
parent | 20a5d1ab3f47b4da6ba39143beaafedb26dbad6a (diff) |
Add some basic support for for-of loops
The support is basically at the same level as for for-in
at the moment.
Currently unimplemented:
* Destructuring
* Proper lexical scoping
* calling iterator.throw()/return() when required
Change-Id: If193ce0b054c4315fc16b7e174334a31b2730dcf
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/parser')
-rw-r--r-- | src/qml/parser/qqmljs.g | 31 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 11 | ||||
-rw-r--r-- | src/qml/parser/qqmljskeywords_p.h | 5 | ||||
-rw-r--r-- | src/qml/parser/qqmljslexer.cpp | 1 |
4 files changed, 35 insertions, 13 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index c25f3395e2..8e71b8a42b 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -262,6 +262,7 @@ public: int ival; double dval; AST::VariableScope scope; + AST::ForEachType forEachType; AST::ArgumentList *ArgumentList; AST::CaseBlock *CaseBlock; AST::CaseClause *CaseClause; @@ -3125,37 +3126,47 @@ IterationStatement: T_FOR T_LPAREN LexicalDeclaration T_SEMICOLON ExpressionOpt_ } break; ./ -IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression_In T_RPAREN Statement; +InOrOf: T_IN; +/. + case $rule_number: { + sym(1).forEachType = AST::ForEachType::In; + } break; +./ + +InOrOf: T_OF; +/. + case $rule_number: { + sym(1).forEachType = AST::ForEachType::Of; + } break; +./ + +IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T_RPAREN Statement; /. case $rule_number: { AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement); node->forToken = loc(1); node->lparenToken = loc(2); - node->inToken = loc(4); + node->inOfToken = loc(4); node->rparenToken = loc(6); + node->type = sym(4).forEachType; sym(1).Node = node; } break; ./ -IterationStatement: T_FOR T_LPAREN ForDeclaration T_IN Expression_In T_RPAREN Statement; +IterationStatement: T_FOR T_LPAREN ForDeclaration InOrOf Expression_In T_RPAREN Statement; /. case $rule_number: { AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(sym(3).PatternElement, sym(5).Expression, sym(7).Statement); node->forToken = loc(1); node->lparenToken = loc(2); node->varToken = loc(3); - node->inToken = loc(4); + node->inOfToken = loc(4); node->rparenToken = loc(6); + node->type = sym(4).forEachType; sym(1).Node = node; } break; ./ - -IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_OF AssignmentExpression_In T_RPAREN Statement; -- [lookahead ≠ let] -/. case $rule_number: { UNIMPLEMENTED; } ./ -IterationStatement: T_FOR T_LPAREN ForDeclaration T_OF Expression_In T_RPAREN Statement; -/. case $rule_number: { UNIMPLEMENTED; } ./ - ForDeclaration: LetOrConst ForBinding; /. case $rule_number: Q_FALLTHROUGH(); ./ ForDeclaration: Var ForBinding; diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index c83a459506..e54d1aea31 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -1701,6 +1701,11 @@ public: SourceLocation rparenToken; }; +enum class ForEachType { + In, + Of +}; + class QML_PARSER_EXPORT ForEachStatement: public Statement { public: @@ -1724,8 +1729,9 @@ public: Statement *statement; SourceLocation forToken; SourceLocation lparenToken; - SourceLocation inToken; + SourceLocation inOfToken; SourceLocation rparenToken; + ForEachType type; }; class QML_PARSER_EXPORT LocalForEachStatement: public Statement @@ -1752,8 +1758,9 @@ public: SourceLocation forToken; SourceLocation lparenToken; SourceLocation varToken; - SourceLocation inToken; + SourceLocation inOfToken; SourceLocation rparenToken; + ForEachType type; }; class QML_PARSER_EXPORT ContinueStatement: public Statement diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h index 9cc47469e5..40094ecdf8 100644 --- a/src/qml/parser/qqmljskeywords_p.h +++ b/src/qml/parser/qqmljskeywords_p.h @@ -76,10 +76,13 @@ static inline int classify2(const QChar *s, int parseModeFlags) { return Lexer::T_IN; } } - else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'o') { + else if (s[0].unicode() == 'o') { if (s[1].unicode() == 'n') { return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_ON : Lexer::T_IDENTIFIER; } + else if (s[1].unicode() == 'f') { + return Lexer::T_OF; + } } return Lexer::T_IDENTIFIER; } diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp index 3dbe535bcf..69e73f1374 100644 --- a/src/qml/parser/qqmljslexer.cpp +++ b/src/qml/parser/qqmljslexer.cpp @@ -1343,6 +1343,7 @@ static const int uriTokens[] = { QQmlJSGrammar::T_FUNCTION, QQmlJSGrammar::T_IF, QQmlJSGrammar::T_IN, + QQmlJSGrammar::T_OF, QQmlJSGrammar::T_INSTANCEOF, QQmlJSGrammar::T_NEW, QQmlJSGrammar::T_NULL, |