]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programparser.cpp
Support precision qualifiers in shaders
[libs/gl.git] / source / programparser.cpp
index bf5d5dffb103fea9b554afa0940f607d12b21ac4..453eb18d31db554f0dd1fc47241a5c770db858dd 100644 (file)
@@ -307,9 +307,14 @@ bool ProgramParser::is_sampling_qualifier(const string &token)
        return token=="centroid";
 }
 
+bool ProgramParser::is_precision_qualifier(const string &token)
+{
+       return (token=="highp" || token=="mediump" || token=="lowp");
+}
+
 bool ProgramParser::is_qualifier(const string &token)
 {
-       return (token=="const" || is_interface_qualifier(token) || is_sampling_qualifier(token));
+       return (token=="const" || is_interface_qualifier(token) || is_sampling_qualifier(token) || is_precision_qualifier(token));
 }
 
 bool ProgramParser::is_builtin_type(const string &token)
@@ -334,6 +339,8 @@ RefPtr<Node> ProgramParser::parse_global_declaration()
        string token = peek_token();
        if(token=="import")
                return parse_import();
+       else if(token=="precision")
+               return parse_precision();
        else if(token=="layout")
        {
                RefPtr<Layout> layout = parse_layout();
@@ -355,15 +362,16 @@ RefPtr<Node> ProgramParser::parse_global_declaration()
        }
        else if(token=="struct")
                return parse_struct_declaration();
-       else if(is_sampling_qualifier(token) || token=="const")
-               return parse_variable_declaration();
        else if(is_interface_qualifier(token))
        {
-               if(is_type(peek_token(1)))
+               string next = peek_token(1);
+               if(is_type(next) || is_precision_qualifier(next))
                        return parse_variable_declaration();
                else
                        return parse_interface_block();
        }
+       else if(is_qualifier(token))
+               return parse_variable_declaration();
        else if(is_type(token))
        {
                if(peek_token(2)=="(")
@@ -422,6 +430,25 @@ RefPtr<Import> ProgramParser::parse_import()
        return import;
 }
 
+RefPtr<Precision> ProgramParser::parse_precision()
+{
+       expect("precision");
+       RefPtr<Precision> precision = new Precision;
+
+       precision->precision = parse_token();
+       if(!is_precision_qualifier(precision->precision))
+               throw runtime_error(format("Parse error at '%s': expected a precision qualifier", precision->precision));
+
+       precision->type = parse_token();
+       // Not entirely accurate; only float, int and sampler types are allowed
+       if(!is_builtin_type(precision->type))
+               throw runtime_error(format("Parse error at '%s': expected a builtin type", precision->type));
+
+       expect(";");
+
+       return precision;
+}
+
 RefPtr<Layout> ProgramParser::parse_layout()
 {
        expect("layout");
@@ -623,6 +650,9 @@ RefPtr<VariableDeclaration> ProgramParser::parse_variable_declaration()
                parse_token();
        }
 
+       if(is_precision_qualifier(token))
+               var->precision = parse_token();
+
        var->type = expect_type();
        var->name = expect_identifier();