[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