X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fparser.cpp;h=cc0233eab702b468704cc2b9b8703e383aeee813;hp=8f2160a626674675b1f63b76ce5dc992d92451ff;hb=e2ed3de4cbbc682ff490a3b0b760b8a45260f611;hpb=2e0ed3f7d23f09de7b4b09c2f132c316ce703d9a diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index 8f2160a6..cc0233ea 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -1,9 +1,11 @@ +#include #include #include #include #include #include "builtin.h" #include "glsl_error.h" +#include "modulecache.h" #include "parser.h" #undef interface @@ -14,7 +16,8 @@ namespace Msp { namespace GL { namespace SL { -Parser::Parser(): +Parser::Parser(ModuleCache *s): + mod_cache(s), preprocessor(tokenizer), module(0) { @@ -25,20 +28,16 @@ Parser::Parser(): preprocessor.signal_line.connect(sigc::mem_fun(this, &Parser::line_change)); } -Parser::~Parser() -{ - delete module; -} - -Module &Parser::parse(const string &s, const string &n, int i) +void Parser::parse(Module &m, const string &s, const string &n, int i) { + SetForScope set_module(module, &m); source = s; parse_source(n, i); - return *module; } -Module &Parser::parse(IO::Base &io, const string &n, int i) +void Parser::parse(Module &m, IO::Base &io, const string &n, int i) { + SetForScope set_module(module, &m); source = string(); while(!io.eof()) { @@ -47,32 +46,20 @@ Module &Parser::parse(IO::Base &io, const string &n, int i) source.append(buffer, len); } parse_source(n, i); - return *module; } void Parser::parse_source(const string &name, int index) { - delete module; - module = new Module; - cur_stage = &module->shared; base_index = index; source_index = 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::const_iterator i=builtin->types.begin(); i!=builtin->types.end(); ++i) - declared_types.insert(i->first); - } - else - { - declared_types.insert("void"); - declared_types.insert("bool"); - declared_types.insert("int"); - declared_types.insert("float"); + for(const auto &kvp: builtin->types) + global_types.insert(kvp.first); } tokenizer.begin(source, name); @@ -110,6 +97,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(const Module *m: imported_modules) + { + auto j = find_member(m->stages, stage, &Stage::type); + if(j!=m->stages.end()) + { + for(const auto &kvp: j->types) + stage_types.insert(kvp.first); + } + } } void Parser::line_change(int index, unsigned line) @@ -190,7 +188,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) @@ -268,11 +266,19 @@ RefPtr Parser::parse_global_declaration() if(is_interface_qualifier(token) && tokenizer.peek_token(1)==";") { RefPtr iface_lo = create_node(); + iface_lo->layout.source = layout->source; + iface_lo->layout.line = layout->line; iface_lo->layout.qualifiers = layout->qualifiers; iface_lo->interface = tokenizer.parse_token(); tokenizer.expect(";"); return iface_lo; } + else if(is_interface_qualifier(token) && tokenizer.peek_token(2)=="{") + { + RefPtr iface = parse_interface_block(); + iface->layout = layout; + return iface; + } else { RefPtr var = parse_variable_declaration(); @@ -358,6 +364,15 @@ RefPtr Parser::parse_import() RefPtr import = create_node(); 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(const auto &kvp: imported_mod.shared.types) + global_types.insert(kvp.first); + } + return import; } @@ -389,9 +404,8 @@ RefPtr Parser::parse_layout() if(token==")") throw parse_error(tokenizer.get_location(), token, "a layout qualifier name"); - layout->qualifiers.push_back(Layout::Qualifier()); + layout->qualifiers.push_back(token); Layout::Qualifier &qual = layout->qualifiers.back(); - qual.name = token; if((qual.has_value = check("="))) { @@ -529,10 +543,14 @@ RefPtr Parser::parse_literal() if(isdigit(literal->token[0])) { // TODO have the tokenizer return the type of the token - if(isnumrc(literal->token)) - literal->value = lexical_cast(literal->token); - else + if(literal->token.back()=='u') + literal->value = lexical_cast(literal->token.substr(0, literal->token.size()-1)); + else if(literal->token.back()=='f') + literal->value = lexical_cast(literal->token.substr(0, literal->token.size()-1)); + else if(literal->token.find('.')!=string::npos) literal->value = lexical_cast(literal->token); + else + literal->value = lexical_cast(literal->token); } else if(literal->token=="true" || literal->token=="false") literal->value = (literal->token=="true"); @@ -598,7 +616,11 @@ RefPtr 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; } @@ -688,7 +710,11 @@ RefPtr 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; } @@ -792,7 +818,7 @@ RefPtr Parser::parse_interface_block() if(!is_interface_qualifier(iface->interface)) throw parse_error(tokenizer.get_location(), iface->interface, "an interface qualifier"); - iface->name = expect_identifier(); + iface->block_name = expect_identifier(); iface->members = new Block; parse_block(*iface->members, true, &Parser::parse_variable_declaration_with_layout); if(!check(";"))