]> git.tdb.fi Git - libs/gl.git/commitdiff
Improve handling of types in GLSL parser
authorMikko Rasa <tdb@tdb.fi>
Fri, 23 Apr 2021 22:34:14 +0000 (01:34 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 23 Apr 2021 22:36:58 +0000 (01:36 +0300)
Types defined in imported modules are now recognized.

source/glsl/parser.cpp
source/glsl/parser.h

index cbfa593ac590671b04f077f4bd2e44136f1312c7..e2a6e1fb6c8dc65664cecd819e527995c7fb119a 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include <msp/core/raii.h>
 #include <msp/strings/format.h>
 #include <msp/strings/regex.h>
@@ -55,19 +56,18 @@ void Parser::parse_source(const string &name, int index)
        if(index>=0)
                source_reference(1, name);
 
-       // TODO Need to somehow get type names from imports
        if(const Stage *builtin = get_builtins(Stage::SHARED))
        {
                for(map<string, TypeDeclaration *>::const_iterator i=builtin->types.begin(); i!=builtin->types.end(); ++i)
-                       declared_types.insert(i->first);
+                       global_types.insert(i->first);
        }
        else
        {
-               declared_types.insert("void");
-               declared_types.insert("bool");
-               declared_types.insert("int");
-               declared_types.insert("uint");
-               declared_types.insert("float");
+               global_types.insert("void");
+               global_types.insert("bool");
+               global_types.insert("int");
+               global_types.insert("uint");
+               global_types.insert("float");
        }
 
        tokenizer.begin(source, name);
@@ -105,6 +105,17 @@ void Parser::stage_change(Stage::Type stage)
        if(cur_stage->type!=Stage::SHARED)
                module->stages.back().previous = cur_stage;
        cur_stage = &module->stages.back();
+
+       stage_types.clear();
+       for(vector<const Module *>::const_iterator i=imported_modules.begin(); i!=imported_modules.end(); ++i)
+       {
+               list<Stage>::const_iterator j = find_member((*i)->stages, stage, &Stage::type);
+               if(j!=(*i)->stages.end())
+               {
+                       for(map<string, TypeDeclaration *>::const_iterator k=j->types.begin(); k!=j->types.end(); ++k)
+                               stage_types.insert(k->first);
+               }
+       }
 }
 
 void Parser::line_change(int index, unsigned line)
@@ -185,7 +196,7 @@ bool Parser::is_qualifier(const string &token)
 
 bool Parser::is_type(const string &token)
 {
-       return declared_types.count(token);
+       return global_types.count(token) || stage_types.count(token);
 }
 
 bool Parser::is_identifier(const string &token)
@@ -361,6 +372,15 @@ RefPtr<Import> Parser::parse_import()
        RefPtr<Import> import = create_node<Import>();
        import->module = expect_identifier();
        tokenizer.expect(";");
+
+       if(mod_cache)
+       {
+               const Module &imported_mod = mod_cache->get_module(import->module);
+               imported_modules.push_back(&imported_mod);
+               for(map<string, TypeDeclaration *>::const_iterator i=imported_mod.shared.types.begin(); i!=imported_mod.shared.types.end(); ++i)
+                       global_types.insert(i->first);
+       }
+
        return import;
 }
 
@@ -604,7 +624,11 @@ RefPtr<TypeDeclaration> Parser::parse_type_declaration()
                type = parse_basic_type_declaration();
 
        tokenizer.expect(";");
-       declared_types.insert(type->name);
+       cur_stage->types[type->name] = type.get();
+       if(cur_stage->type==Stage::SHARED)
+               global_types.insert(type->name);
+       else
+               stage_types.insert(type->name);
        return type;
 }
 
@@ -694,7 +718,11 @@ RefPtr<StructDeclaration> Parser::parse_struct_declaration()
        parse_block(strct->members, true, &Parser::parse_variable_declaration);
        tokenizer.expect(";");
 
-       declared_types.insert(strct->name);
+       cur_stage->types[strct->name] = strct.get();
+       if(cur_stage->type==Stage::SHARED)
+               global_types.insert(strct->name);
+       else
+               stage_types.insert(strct->name);
        return strct;
 }
 
index e087f27f9d0578bd6e23be8fee0c44e841cd3cb3..a935356ecd1339e68e6bb82f2752a5d47e6a25fb 100644 (file)
@@ -25,8 +25,10 @@ private:
        Preprocessor preprocessor;
        bool allow_stage_change;
        Module *module;
+       std::vector<const Module *> imported_modules;
        Stage *cur_stage;
-       std::set<std::string> declared_types;
+       std::set<std::string> global_types;
+       std::set<std::string> stage_types;
        std::vector<std::string> errors;
 
 public: