if(var.layout && !supports_interface_layouts())
{
vector<Layout::Qualifier>::iterator i;
- for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->identifier!="location"); ++i) ;
+ for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->name!="location"); ++i) ;
if(i!=var.layout->qualifiers.end())
{
- unsigned location = lexical_cast<unsigned>(i->value);
if(stage->type==Stage::VERTEX && var.interface=="in")
{
- stage->locations[var.name] = location;
+ stage->locations[var.name] = i->value;
var.layout->qualifiers.erase(i);
}
else if(stage->type==Stage::FRAGMENT && var.interface=="out")
{
- if(location!=0 && !check_extension(&Features::ext_gpu_shader4))
+ if(i->value!=0 && !check_extension(&Features::ext_gpu_shader4))
throw unsupported_shader("EXT_gpu_shader4 is required");
- stage->locations[var.name] = location;
+ stage->locations[var.name] = i->value;
var.layout->qualifiers.erase(i);
}
for(vector<Layout::Qualifier>::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); )
{
vector<Layout::Qualifier>::const_iterator j = increment(i, layout.qualifiers);
- string qualifier = j->identifier;
- if(!j->value.empty())
- qualifier += format("=%s", j->value);
+ string qualifier = j->name;
+ if(j->has_value)
+ qualifier += format("=%d", j->value);
append(qualifier);
}
end_sub();
{
bool found = false;
for(vector<Layout::Qualifier>::iterator j=ptr->layout->qualifiers.begin(); (!found && j!=ptr->layout->qualifiers.end()); ++j)
- if(j->identifier==i->identifier)
+ if(j->name==i->name)
{
+ j->has_value = i->value;
j->value = i->value;
found = true;
}
{
if(i!=layout.qualifiers.begin())
append(", ");
- append(i->identifier);
- if(!i->value.empty())
- append(format("=%s", i->value));
+ append(i->name);
+ if(i->has_value)
+ append(format("=%d", i->value));
}
append(')');
}
#include <msp/strings/format.h>
#include <msp/strings/regex.h>
+#include <msp/strings/utils.h>
#include "glsl_error.h"
#include "parser.h"
return token;
}
+int Parser::expect_integer()
+{
+ string token = tokenizer.parse_token();
+ if(!isnumrc(token))
+ throw parse_error(tokenizer.get_location(), token, "an integer literal");
+ return lexical_cast<int>(token);
+}
+
bool Parser::check(const string &token)
{
bool result = (tokenizer.peek_token()==token);
layout->qualifiers.push_back(Layout::Qualifier());
Layout::Qualifier &qual = layout->qualifiers.back();
- qual.identifier = token;
+ qual.name = token;
- if(check("="))
- qual.value = tokenizer.parse_token();
+ if((qual.has_value = check("=")))
+ qual.value = expect_integer();
if(tokenizer.peek_token()==")")
break;
std::string expect_type();
std::string expect_identifier();
+ int expect_integer();
bool check(const std::string &);
static bool is_interface_qualifier(const std::string &);
{
struct Qualifier
{
- // TODO the standard calls this name, not identifier
- std::string identifier;
- std::string value;
+ std::string name;
+ bool has_value;
+ int value;
};
std::vector<Qualifier> qualifiers;