Support while loops in GLSL
authorMikko Rasa <tdb@tdb.fi>
Sat, 25 May 2019 21:58:17 +0000 (00:58 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 25 May 2019 21:58:17 +0000 (00:58 +0300)
Loops with only a condition expression present are now emitted as while
loops, even if they were originally for loops.

source/programcompiler.cpp
source/programparser.cpp
source/programparser.h

index fd9c50dbbb5c2879e55fb528035f7527aef126ff..afb2a3c32ecac3465cfe8620e74f816beeb84473 100644 (file)
@@ -543,23 +543,32 @@ void ProgramCompiler::Formatter::visit(Conditional &cond)
 
 void ProgramCompiler::Formatter::visit(Iteration &iter)
 {
-       formatted += "for(";
-       if(iter.init_statement)
-               iter.init_statement->visit(*this);
-       else
-               formatted += ';';
-       if(iter.condition)
+       if(!iter.init_statement && iter.condition && !iter.loop_expression)
        {
-               formatted += ' ';
+               formatted += "while(";
                iter.condition->visit(*this);
+               formatted += ')';
        }
-       formatted += ';';
-       if(iter.loop_expression)
+       else
        {
-               formatted += ' ';
-               iter.loop_expression->visit(*this);
+               formatted += "for(";
+               if(iter.init_statement)
+                       iter.init_statement->visit(*this);
+               else
+                       formatted += ';';
+               if(iter.condition)
+               {
+                       formatted += ' ';
+                       iter.condition->visit(*this);
+               }
+               formatted += ';';
+               if(iter.loop_expression)
+               {
+                       formatted += ' ';
+                       iter.loop_expression->visit(*this);
+               }
+               formatted += ')';
        }
-       formatted += ')';
 
        if(iter.body.body.empty())
                formatted += " { }";
index b607e1cfb8f063abfec2127b7c57247809677a81..c02adb325c25eaba6d4df7f31d9b8963506a5cd4 100644 (file)
@@ -484,7 +484,9 @@ RefPtr<Node> ProgramParser::parse_statement()
        if(token=="if")
                return parse_conditional();
        else if(token=="for")
-               return parse_iteration();
+               return parse_for();
+       else if(token=="while")
+               return parse_while();
        else if(token=="passthrough")
                return parse_passthrough();
        else if(token=="return")
@@ -843,7 +845,7 @@ RefPtr<Conditional> ProgramParser::parse_conditional()
        return cond;
 }
 
-RefPtr<Iteration> ProgramParser::parse_iteration()
+RefPtr<Iteration> ProgramParser::parse_for()
 {
        expect("for");
        expect("(");
@@ -873,6 +875,19 @@ RefPtr<Iteration> ProgramParser::parse_iteration()
        return loop;
 }
 
+RefPtr<Iteration> ProgramParser::parse_while()
+{
+       expect("while");
+       expect("(");
+       RefPtr<Iteration> loop = new Iteration;
+       loop->condition = parse_expression();
+       expect(")");
+
+       parse_block(loop->body, false);
+
+       return loop;
+}
+
 RefPtr<Passthrough> ProgramParser::parse_passthrough()
 {
        expect("passthrough");
index 903e58346f7a425a365cccfcf162f56caa75fa6e..707815405684252f1fc06c33341ea19b5ba5199c 100644 (file)
@@ -104,7 +104,8 @@ private:
        RefPtr<ProgramSyntax::FunctionDeclaration> parse_function_declaration();
        RefPtr<ProgramSyntax::InterfaceBlock> parse_interface_block();
        RefPtr<ProgramSyntax::Conditional> parse_conditional();
-       RefPtr<ProgramSyntax::Iteration> parse_iteration();
+       RefPtr<ProgramSyntax::Iteration> parse_for();
+       RefPtr<ProgramSyntax::Iteration> parse_while();
        RefPtr<ProgramSyntax::Passthrough> parse_passthrough();
        RefPtr<ProgramSyntax::Return> parse_return();
 };