[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [qmlweb/development/qmlweb2] /: [Compiler] Implement loops
From:       Jan Marker <jan () jangmarker ! de>
Date:       2015-09-30 20:44:34
Message-ID: E1ZhOEs-0000CB-TD () scm ! kde ! org
[Download RAW message or body]

Git commit 3152b13f9033570a2bd14b4004da21b79f64101e by Jan Marker.
Committed on 30/09/2015 at 20:41.
Pushed by jangmarker into branch 'development/qmlweb2'.

[Compiler] Implement loops

* local and global for
* local and global for each
* while
* do while

M  +43   -0    src/qmljsc/purejavascriptgenerator.cpp
M  +6    -0    src/qmljsc/purejavascriptgenerator.h
A  +1    -0    tests/auto/data/javascript/loops.compiled.js
A  +14   -0    tests/auto/data/javascript/loops.js
M  +26   -0    tests/auto/qmljsc/testpurejavascriptgenerator.cpp
M  +5    -4    tests/auto/qmljsc/testpurejavascriptgenerator_integration.cpp

http://commits.kde.org/qmlweb/3152b13f9033570a2bd14b4004da21b79f64101e

diff --git a/src/qmljsc/purejavascriptgenerator.cpp \
b/src/qmljsc/purejavascriptgenerator.cpp index 0ec9859..ae1fd2e 100644
--- a/src/qmljsc/purejavascriptgenerator.cpp
+++ b/src/qmljsc/purejavascriptgenerator.cpp
@@ -212,6 +212,13 @@ void PureJavaScriptGenerator::endVisit(AST::CaseBlock \
                *caseBlock) {
     m_outputStack << '{' + clausesLeft + defaultClause + clausesRight + '}';
 }
 
+void PureJavaScriptGenerator::endVisit(AST::DoWhileStatement *) {
+    const QString expression = m_outputStack.pop();
+    const QString statement = m_outputStack.pop();
+    m_outputStack << "do " + statement + "while" + '(' + expression + ')' + ';';
+    // space after do: do var i;while(false); is a valid statement and requires a \
space +}
+
 void PureJavaScriptGenerator::endVisit(AST::CaseClause *) {
     const QString statement = m_outputStack.pop();
     const QString expression = m_outputStack.pop();
@@ -271,6 +278,21 @@ void \
PureJavaScriptGenerator::endVisit(AST::FieldMemberExpression *fieldMemberEx  \
m_outputStack << objectExpression + '.' + memberName;  }
 
+void PureJavaScriptGenerator::endVisit(AST::ForEachStatement *) {
+    const QString statement = m_outputStack.pop();
+    const QString objectExpression = m_outputStack.pop();
+    const QString variableExpression = m_outputStack.pop();
+    m_outputStack << "for(" + variableExpression + " in " + objectExpression + ')' + \
statement; +}
+
+void PureJavaScriptGenerator::endVisit(AST::ForStatement *forStatement) {
+    const QString statement = m_outputStack.pop();
+    const QString incrementExpression = \
(forStatement->expression)?m_outputStack.pop():""; +    const QString condition = \
(forStatement->condition)?m_outputStack.pop():""; +    const QString initialisation = \
(forStatement->initialiser)?m_outputStack.pop():""; +    m_outputStack << "for(" + \
initialisation + ';' + condition + ';' + incrementExpression + ')' + statement; +}
+
 void PureJavaScriptGenerator::endVisit(AST::FunctionBody *) {
     const QString body = m_outputStack.pop();
     m_outputStack << '{' + body + '}';
@@ -298,6 +320,21 @@ void PureJavaScriptGenerator::endVisit(AST::IfStatement \
*ifExpression) {  m_outputStack << code;
 }
 
+void PureJavaScriptGenerator::endVisit(AST::LocalForEachStatement *) {
+    const QString statement = m_outputStack.pop();
+    const QString objectExpression = m_outputStack.pop();
+    const QString declaredVariableName = m_outputStack.pop();
+    m_outputStack << "for(var " + declaredVariableName + " in " + objectExpression + \
')' + statement; +}
+
+void PureJavaScriptGenerator::endVisit(AST::LocalForStatement *localForStatement) {
+    const QString statement = m_outputStack.pop();
+    const QString incrementExpression = \
(localForStatement->expression)?m_outputStack.pop():""; +    const QString condition \
= (localForStatement->condition)?m_outputStack.pop():""; +    const QString \
declaration = (localForStatement->declarations)?m_outputStack.pop():""; +    \
m_outputStack << "for(" + declaration + ';' + condition + ';' + incrementExpression + \
')' + statement; +}
+
 void PureJavaScriptGenerator::endVisit(AST::NumericLiteral *) {
 }
 
@@ -386,6 +423,12 @@ void PureJavaScriptGenerator::endVisit(AST::VariableStatement *) \
{  m_outputStack << m_outputStack.pop() + ';';
 }
 
+void PureJavaScriptGenerator::endVisit(AST::WhileStatement *) {
+    const QString statement = m_outputStack.pop();
+    const QString expression = m_outputStack.pop();
+    m_outputStack << "while(" + expression + ')' + statement;
+}
+
 void PureJavaScriptGenerator::reduceJumpStatement(const char *keyword, QStringRef \
label) {  QString labelStatementCode(keyword);
     if (label.length() > 0) {
diff --git a/src/qmljsc/purejavascriptgenerator.h \
b/src/qmljsc/purejavascriptgenerator.h index ea64b2f..35dfa35 100644
--- a/src/qmljsc/purejavascriptgenerator.h
+++ b/src/qmljsc/purejavascriptgenerator.h
@@ -58,14 +58,19 @@ public:
     virtual void endVisit(QQmlJS::AST::CaseClause *) override;
     virtual void endVisit(QQmlJS::AST::CaseClauses *) override;
     virtual void endVisit(QQmlJS::AST::DefaultClause *) override;
+    virtual void endVisit(QQmlJS::AST::DoWhileStatement *) override;
     virtual void endVisit(QQmlJS::AST::ElementList *) override;
     virtual void endVisit(QQmlJS::AST::EmptyStatement *) override;
     virtual void endVisit(QQmlJS::AST::ExpressionStatement *) override;
     virtual void endVisit(QQmlJS::AST::FieldMemberExpression *) override;
+    virtual void endVisit(QQmlJS::AST::ForEachStatement *) override;
+    virtual void endVisit(QQmlJS::AST::ForStatement *) override;
     virtual void endVisit(QQmlJS::AST::FunctionBody *) override;
     virtual void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
     virtual void endVisit(QQmlJS::AST::IdentifierExpression *) override;
     virtual void endVisit(QQmlJS::AST::IfStatement *) override;
+    virtual void endVisit(QQmlJS::AST::LocalForEachStatement *) override;
+    virtual void endVisit(QQmlJS::AST::LocalForStatement *) override;
     virtual void endVisit(QQmlJS::AST::NumericLiteral *) override;
     virtual void endVisit(QQmlJS::AST::ObjectLiteral *) override;
     virtual void endVisit(QQmlJS::AST::PostDecrementExpression *) override;
@@ -83,6 +88,7 @@ public:
     virtual void endVisit(QQmlJS::AST::VariableDeclaration *) override;
     virtual void endVisit(QQmlJS::AST::VariableDeclarationList *) override;
     virtual void endVisit(QQmlJS::AST::VariableStatement *) override;
+    virtual void endVisit(QQmlJS::AST::WhileStatement *) override;
 
 private:
     template<typename ListType> void reduceListStack(ListType* list, const char* \
                separator = "");
diff --git a/tests/auto/data/javascript/loops.compiled.js \
b/tests/auto/data/javascript/loops.compiled.js new file mode 100644
index 0000000..03cae8b
--- /dev/null
+++ b/tests/auto/data/javascript/loops.compiled.js
@@ -0,0 +1 @@
+while(true){;}do {;}while(true);for(i=5;i<10;++i);for(var i=5;i;++i);for(i in \
o){;}for(var i in o){;} \ No newline at end of file
diff --git a/tests/auto/data/javascript/loops.js \
b/tests/auto/data/javascript/loops.js new file mode 100644
index 0000000..79f39c9
--- /dev/null
+++ b/tests/auto/data/javascript/loops.js
@@ -0,0 +1,14 @@
+while(true) {
+    ;
+}
+do{
+   ;
+} while(true);
+for(i=5;i<10;++i);
+for(var i=5;i;++i);
+for(i in o) {
+    ;
+}
+for(var i in o) {
+    ;
+}
\ No newline at end of file
diff --git a/tests/auto/qmljsc/testpurejavascriptgenerator.cpp \
b/tests/auto/qmljsc/testpurejavascriptgenerator.cpp index b194a6d..67573fe 100644
--- a/tests/auto/qmljsc/testpurejavascriptgenerator.cpp
+++ b/tests/auto/qmljsc/testpurejavascriptgenerator.cpp
@@ -178,6 +178,14 @@ public:
         , m_caseBlockCasesDefaultCases(&m_twoCaseClauses, &m_defaultClause, \
&m_twoCaseClauses)  , m_caseClause(&m_trueLiteral, &m_threeStatementsList)
         , m_switchStatement(&m_trueLiteral, &m_caseBlock)
+        , m_whileStatement(nullptr, nullptr)
+        , m_doWhileStatement(nullptr, nullptr)
+        , m_forStatementAllParts(&m_trueLiteral, &m_falseLiteral, &m_trueLiteral, \
&m_block) +        , m_forStatementNoPart(nullptr, nullptr, nullptr, &m_block)
+        , m_localForStatementAllParts(&m_twoVarDeclarations, &m_falseLiteral, \
&m_trueLiteral, &m_block) +        , m_localForStatementNoPart(nullptr, nullptr, \
nullptr, &m_block) +        , m_forEachStatement(&m_trueLiteral, &m_trueLiteral, \
&m_block) +        , m_localForEachStatement(&m_variableDeclarationWithoutAssignment, \
&m_trueLiteral, &m_block)  {
         m_elisionsPart2.finish();
         m_arrayElementsExp.finish();
@@ -316,6 +324,16 @@ private:
     AST::CaseClause m_caseClause;
     AST::SwitchStatement m_switchStatement;
 
+    /* Loops */
+    AST::WhileStatement m_whileStatement;
+    AST::DoWhileStatement m_doWhileStatement;
+    AST::ForStatement m_forStatementAllParts;
+    AST::ForStatement m_forStatementNoPart;
+    AST::LocalForStatement m_localForStatementAllParts;
+    AST::LocalForStatement m_localForStatementNoPart;
+    AST::ForEachStatement m_forEachStatement;
+    AST::LocalForEachStatement m_localForEachStatement;
+
 private slots:
     void init() {
         m_generator = new PureJavaScriptGenerator();
@@ -398,6 +416,7 @@ private slots:
     TEST_ENDVISIT_REDUCES(CaseClause              , CaseWithStatement , "case \
                exp:stm;"   , ({"case", "exp", "stm;"})    , m_caseClause)
     TEST_ENDVISIT_REDUCES(CaseClauses             , TwoClauses        , "case \
                e:s;case e2:s2;", ({"case e:s;", "case e2:s2;"}), m_twoCaseClauses)
     TEST_ENDVISIT_REDUCES(DefaultClause           , AnyCase           , \
"default:stm"     , ({"default", "stm"})         , m_defaultClause) +    \
TEST_ENDVISIT_REDUCES(DoWhileStatement        , AnyCase           , "do \
                stm;while(e);", ({"stm;", "e"})               , m_doWhileStatement)
     TEST_ENDVISIT_REDUCES(ElementList             , Expression        , "expr,"      \
                , ({"expr"})                   , m_arrayElementsExp)
     TEST_ENDVISIT_REDUCES(ElementList             , TwoExpressions    , "expr,expr," \
                , ({"expr", "expr"})           , m_arrayElementsExpExp)
     TEST_ENDVISIT_REDUCES(ElementList             , ElisionExpression , \
"elisionexpr,"    , ({"elision", "expr"})        , m_arrayElementsElisionExp) @@ \
                -406,6 +425,9 @@ private slots:
     TEST_ENDVISIT_REDUCES(ExpressionStatement     , AnyCase           , \
                "expression;"     , ({"expression"})             , \
                m_expressionStatement)
     TEST_ENDVISIT_REDUCES(FieldMemberExpression   , AnyCase           , \
                "obj.property"    , ({"obj"})                    , \
                m_fieldMemberExpression)
     TEST_ENDVISIT_REDUCES(FormalParameterList     , AnyCase           , "i"          \
, ({"i"})                      , m_twoParameters) // does nothing +    \
TEST_ENDVISIT_REDUCES(ForEachStatement        , AnyCase           , "for(i in o)stm;" \
, ({"i", "o", "stm;"})         , m_forEachStatement) +    \
TEST_ENDVISIT_REDUCES(ForStatement            , AllParts          , "for(i;c;++)stm;" \
, ({"i", "c", "++", "stm;"})   , m_forStatementAllParts) +    \
TEST_ENDVISIT_REDUCES(ForStatement            , NoPart            , "for(;;)stm;"     \
                , ({"stm;"})                   , m_forStatementNoPart)
     TEST_ENDVISIT_REDUCES(FunctionBody            , ClosesCorrectly   , "{func}"     \
                , ({"func"})                   , m_functionBody)
     TEST_ENDVISIT_REDUCES(FunctionDeclaration     , BodyNoParameters  , "function \
                i(){body}"    , ({"{body}"})           , \
                m_functionDeclarationWithoutParameters)
     TEST_ENDVISIT_REDUCES(FunctionDeclaration     , BodyParameters    , "function \
i(para){body}", ({"para", "{body}"})   , m_functionDeclarationWithParameters) @@ \
                -413,6 +435,9 @@ private slots:
     TEST_ENDVISIT_REDUCES(IdentifierExpression    , AnyCase           , "abc"        \
                , ({"abc"})                    , m_identifierExpression)
     TEST_ENDVISIT_REDUCES(IfStatement             , OnlyIf            , \
                "if(exp)stm;"     , ({"exp", "stm;"})            , \
                m_ifStatementWithoutElse)
     TEST_ENDVISIT_REDUCES(IfStatement             , IfElse            , \
"if(exp)s;else s;", ({"exp", "s;", "s;"})        , m_ifStatementWithElse) +    \
TEST_ENDVISIT_REDUCES(LocalForEachStatement   , AnyCase           , "for(var i in \
o)stm;", ({"i", "o", "stm;"})      , m_localForEachStatement) +    \
TEST_ENDVISIT_REDUCES(LocalForStatement       , AllParts          , "for(var \
i;c;++)stm;", ({"var i", "c", "++", "stm;"}), m_localForStatementAllParts) +    \
TEST_ENDVISIT_REDUCES(LocalForStatement       , NoPart            , "for(;;)stm;"     \
                , ({"stm;"})                   , m_localForStatementNoPart)
     TEST_ENDVISIT_REDUCES(NumericLiteral          , AnyCase           , "2.7"        \
                , ({"2.7"})                    , m_numericalExpressionPi)
     TEST_ENDVISIT_REDUCES(ObjectLiteral           , AnyCase           , \
                "{properties}"    , ({"properties"})             , m_objectLiteral)
     TEST_ENDVISIT_REDUCES(PostDecrementExpression , AnyCase           , "2.7--"      \
, ({"2.7"})                    , m_postDecrementExpression) @@ -437,6 +462,7 @@ \
                private slots:
     TEST_ENDVISIT_REDUCES(VariableDeclarationList , OneDeclaration    , "var e=5"    \
                , ({"e=5"})                    , m_twoVarDeclarationsPart2)
     TEST_ENDVISIT_REDUCES(VariableDeclarationList , ConstDeclaration  , "const e=5"  \
                , ({"e=5"})                    , m_twoConstDeclarationsPart2)
     TEST_ENDVISIT_REDUCES(VariableStatement       , AnyCase           , "x;"         \
, ({"x"})                      , m_variableStatement) +    \
TEST_ENDVISIT_REDUCES(WhileStatement          , AnyCase           , "while(e)stm"     \
, ({"e", "stm"})               , m_whileStatement)  
     TEST_VISIT_BINARYOP_PUTS_ON_STACK(Assign, "=")
     TEST_VISIT_BINARYOP_PUTS_ON_STACK(InplaceAdd, "+=")
diff --git a/tests/auto/qmljsc/testpurejavascriptgenerator_integration.cpp \
b/tests/auto/qmljsc/testpurejavascriptgenerator_integration.cpp index \
                e88c8dd..9ec3227 100644
--- a/tests/auto/qmljsc/testpurejavascriptgenerator_integration.cpp
+++ b/tests/auto/qmljsc/testpurejavascriptgenerator_integration.cpp
@@ -60,16 +60,16 @@ private:
         return QString(inputFile.readAll());
     }
 
+    void addRowForFile(QString fileName) {
+        addRowForFileWithCompiled(fileName, fileName);
+    }
+
     void addRowForFileWithCompiled(QString sourceFileName, QString compiledFileName) \
{  const QString folder(":/test/%1.js");
         QTest::newRow(sourceFileName.toLocal8Bit()) << \
astForFile(folder.arg(sourceFileName)) << fileContent(folder.arg(compiledFileName));  \
  }
 
-    void addRowForFile(QString fileName) {
-        addRowForFileWithCompiled(fileName, fileName);
-    }
-
     void addRowForFileWithCompiled(QString fileName) {
         addRowForFileWithCompiled(fileName, QString("%1.compiled").arg(fileName));
     }
@@ -92,6 +92,7 @@ private slots:
         addRowForFileWithCompiled("objectliterals");
         addRowForFileWithCompiled("propertyaccess");
         addRowForFileWithCompiled("functioncalls");
+        addRowForFileWithCompiled("loops");
     }
 
     void test_compileJavaScriptFile() {


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic