]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programparser.cpp
Refactor module and stage management
[libs/gl.git] / source / programparser.cpp
index c6cdfd06246f1c14683919fcfec637b8adf85058..16299d20cf157f8281fc2face34d55a21712eee1 100644 (file)
@@ -58,11 +58,20 @@ ProgramParser::Operator ProgramParser::operators[] =
        { { 0 }, 18, NO_OPERATOR, LEFT_TO_RIGHT }
 };
 
+ProgramParser::ProgramParser():
+       module(0)
+{ }
+
+ProgramParser::~ProgramParser()
+{
+       delete module;
+}
+
 Module &ProgramParser::parse(const string &s)
 {
        source = s;
-       parse_source(main_module);
-       return main_module;
+       parse_source();
+       return *module;
 }
 
 Module &ProgramParser::parse(IO::Base &io)
@@ -74,35 +83,37 @@ Module &ProgramParser::parse(IO::Base &io)
                unsigned len = io.read(buffer, sizeof(buffer));
                source.append(buffer, len);
        }
-       parse_source(main_module);
-       return main_module;
+       parse_source();
+       return *module;
 }
 
-void ProgramParser::parse_source(Module &module)
+void ProgramParser::parse_source()
 {
-       cur_module = &module;
+       delete module;
+       module = new Module;
+       cur_stage = &module->shared;
        iter = source.begin();
-       Context *cur_context = &module.global_context;
        while(1)
        {
                while(Node *statement = parse_global_declaration())
-                       cur_context->content.body.push_back(statement);
-               cur_context->present = !cur_context->content.body.empty();
+                       cur_stage->content.body.push_back(statement);
 
                parse_token();
                string token = parse_token();
                if(token.empty())
                        break;
-               else if(token=="global")
-                       cur_context = &module.global_context;
                else if(token=="vertex")
-                       cur_context = &module.vertex_context;
+                       module->stages.push_back(VERTEX);
                else if(token=="geometry")
-                       cur_context = &module.geometry_context;
+                       module->stages.push_back(GEOMETRY);
                else if(token=="fragment")
-                       cur_context = &module.fragment_context;
+                       module->stages.push_back(FRAGMENT);
                else
-                       throw runtime_error(format("Parse error at '%s': expected context identifier", token));
+                       throw runtime_error(format("Parse error at '%s': expected stage identifier", token));
+
+               if(cur_stage->type!=SHARED)
+                       module->stages.back().previous = cur_stage;
+               cur_stage = &module->stages.back();
 
                for(; (iter!=source.end() && *iter!='\n'); ++iter) ;
        }
@@ -355,6 +366,8 @@ Node *ProgramParser::parse_statement()
                return parse_conditional();
        else if(token=="for")
                return parse_iteration();
+       else if(token=="passthrough")
+               return parse_passthrough();
        else if(token=="return")
                return parse_return();
        else if(is_qualifier(token) || is_type(token))
@@ -693,6 +706,20 @@ Iteration *ProgramParser::parse_iteration()
        return loop.release();
 }
 
+Passthrough *ProgramParser::parse_passthrough()
+{
+       expect("passthrough");
+       RefPtr<Passthrough> pass = new Passthrough;
+       if(cur_stage->type==GEOMETRY)
+       {
+               expect("[");
+               pass->subscript = parse_expression();
+               expect("]");
+       }
+       expect(";");
+       return pass.release();
+}
+
 Return *ProgramParser::parse_return()
 {
        expect("return");