X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fparser.cpp;h=8c10c443002e130fa01f42b32ceb18cbe5f4d772;hb=1a5dafe20e47c764f2914c341fb7b8f1fba59fb8;hp=46bee183f9c061330dc984efd3e88d7ef6773202;hpb=4d292eadc135b07e8e0996deb539b1984d7d38d3;p=libs%2Fgl.git diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index 46bee183..8c10c443 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -66,7 +66,14 @@ void Parser::parse_source(const string &name, int index) allow_stage_change = true; while(!tokenizer.peek_token().empty()) if(RefPtr statement = parse_with_recovery(&Parser::parse_global_declaration)) + { cur_stage->content.body.push_back(statement); + if(next_global_declaration) + { + cur_stage->content.body.push_back(next_global_declaration); + next_global_declaration = 0; + } + } if(!errors.empty()) throw invalid_shader_source(join(errors.begin(), errors.end(), "\n")); @@ -99,6 +106,11 @@ void Parser::stage_change(Stage::Type stage) cur_stage = &module->stages.back(); stage_types.clear(); + if(const Stage *builtin = get_builtins(stage)) + { + for(const auto &kvp: builtin->types) + stage_types.insert(kvp.first); + } for(const Module *m: imported_modules) { auto j = find_member(m->stages, stage, &Stage::type); @@ -275,9 +287,11 @@ RefPtr Parser::parse_global_declaration() } else if(is_interface_qualifier(token) && tokenizer.peek_token(2)=="{") { - RefPtr iface = parse_interface_block(); - iface->layout = layout; - return iface; + RefPtr iface_strct = parse_interface_block(); + VariableDeclaration *iface_var = iface_strct->block_declaration; + iface_var->layout = layout; + next_global_declaration = iface_var; + return iface_strct; } else { @@ -296,7 +310,11 @@ RefPtr Parser::parse_global_declaration() if(is_type(next) || is_qualifier(next)) return parse_variable_declaration(); else - return parse_interface_block(); + { + RefPtr iface_strct = parse_interface_block(); + next_global_declaration = iface_strct->block_declaration; + return iface_strct; + } } else if(is_qualifier(token)) return parse_variable_declaration(); @@ -811,29 +829,39 @@ RefPtr Parser::parse_function_declaration() return func; } -RefPtr Parser::parse_interface_block() +RefPtr Parser::parse_interface_block() { - RefPtr iface = create_node(); - - iface->interface = tokenizer.parse_token(); - if(!is_interface_qualifier(iface->interface)) - throw parse_error(tokenizer.get_location(), iface->interface, "an interface qualifier"); + RefPtr strct = create_node(); + RefPtr var = create_node(); - iface->block_name = expect_identifier(); - iface->members = new Block; - parse_block(*iface->members, true, &Parser::parse_variable_declaration_with_layout); + var->interface = tokenizer.parse_token(); + if(!is_interface_qualifier(var->interface)) + throw parse_error(tokenizer.get_location(), var->interface, "an interface qualifier"); + + strct->block_name = expect_identifier(); + string name_base = format("_%s_%s", var->interface, strct->block_name); + strct->name = name_base; + for(unsigned i=1; (stage_types.count(strct->name) || global_types.count(strct->name)); ++i) + strct->name = format("%s_%d", name_base, i); + var->type = strct->name; + parse_block(strct->members, true, &Parser::parse_variable_declaration_with_layout); if(!check(";")) { - iface->instance_name = expect_identifier(); + var->name = expect_identifier(); if(check("[")) { - iface->array = true; + var->array = true; tokenizer.expect("]"); } tokenizer.expect(";"); } + else + var->name = format("%s %s", var->interface, strct->block_name); + + strct->block_declaration = var.release(); + add_type(*strct); - return iface; + return strct; } RefPtr Parser::parse_conditional()