]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/syntax.cpp
Even more validation for uniform mismatches
[libs/gl.git] / source / glsl / syntax.cpp
index 025af2710bb55da807fb686b6876eaef41d4ce22..d0273909d68db900e0d95e79c08f1d2cf9f140cd 100644 (file)
@@ -10,51 +10,50 @@ namespace SL {
 
 const Operator Operator::operators[] =
 {
-       { "[", 2, BINARY, LEFT_TO_RIGHT },
-       { "(", 2, POSTFIX, LEFT_TO_RIGHT },
-       { ".", 2, BINARY, LEFT_TO_RIGHT },
-       { "++", 2, POSTFIX, LEFT_TO_RIGHT },
-       { "--", 2, POSTFIX, LEFT_TO_RIGHT },
-       { "++", 3, PREFIX, RIGHT_TO_LEFT },
-       { "--", 3, PREFIX, RIGHT_TO_LEFT },
-       { "+", 3, PREFIX, RIGHT_TO_LEFT },
-       { "-", 3, PREFIX, RIGHT_TO_LEFT },
-       { "~", 3, PREFIX, RIGHT_TO_LEFT },
-       { "!", 3, PREFIX, RIGHT_TO_LEFT },
-       { "*", 4, BINARY, ASSOCIATIVE },
-       { "/", 4, BINARY, LEFT_TO_RIGHT },
-       { "%", 4, BINARY, LEFT_TO_RIGHT },
-       { "+", 5, BINARY, ASSOCIATIVE },
-       { "-", 5, BINARY, LEFT_TO_RIGHT },
-       { "<<", 6, BINARY, LEFT_TO_RIGHT },
-       { ">>", 6, BINARY, LEFT_TO_RIGHT },
-       { "<", 7, BINARY, LEFT_TO_RIGHT },
-       { ">", 7, BINARY, LEFT_TO_RIGHT },
-       { "<=", 7, BINARY, LEFT_TO_RIGHT },
-       { ">=", 7, BINARY, LEFT_TO_RIGHT },
-       { "==", 8, BINARY, LEFT_TO_RIGHT },
-       { "!=", 8, BINARY, LEFT_TO_RIGHT },
-       { "&", 9, BINARY, ASSOCIATIVE },
-       { "^", 10, BINARY, ASSOCIATIVE },
-       { "|", 11, BINARY, ASSOCIATIVE },
-       { "&&", 12, BINARY, ASSOCIATIVE },
-       { "^^", 13, BINARY, ASSOCIATIVE },
-       { "||", 14, BINARY, ASSOCIATIVE },
-       { "?", 15, TERNARY, RIGHT_TO_LEFT },
-       { ":", 15, TERNARY, RIGHT_TO_LEFT },
-       { "=", 16, BINARY, RIGHT_TO_LEFT },
-       { "+=", 16, BINARY, RIGHT_TO_LEFT },
-       { "-=", 16, BINARY, RIGHT_TO_LEFT },
-       { "*=", 16, BINARY, RIGHT_TO_LEFT },
-       { "/=", 16, BINARY, RIGHT_TO_LEFT },
-       { "%=", 16, BINARY, RIGHT_TO_LEFT },
-       { "<<=", 16, BINARY, RIGHT_TO_LEFT },
-       { ">>=", 16, BINARY, RIGHT_TO_LEFT },
-       { "&=", 16, BINARY, RIGHT_TO_LEFT },
-       { "^=", 16, BINARY, RIGHT_TO_LEFT },
-       { "|=", 16, BINARY, RIGHT_TO_LEFT },
-       { ",", 17, BINARY, LEFT_TO_RIGHT },
-       { { 0 }, 18, NO_OPERATOR, LEFT_TO_RIGHT }
+       { "[", "]", 2, BINARY, LEFT_TO_RIGHT },
+       { "(", ")", 2, POSTFIX, LEFT_TO_RIGHT },
+       { ".", { }, 2, POSTFIX, LEFT_TO_RIGHT },
+       { "++", { }, 2, POSTFIX, LEFT_TO_RIGHT },
+       { "--", { }, 2, POSTFIX, LEFT_TO_RIGHT },
+       { "++", { }, 3, PREFIX, RIGHT_TO_LEFT },
+       { "--", { }, 3, PREFIX, RIGHT_TO_LEFT },
+       { "+", { }, 3, PREFIX, RIGHT_TO_LEFT },
+       { "-", { }, 3, PREFIX, RIGHT_TO_LEFT },
+       { "~", { }, 3, PREFIX, RIGHT_TO_LEFT },
+       { "!", { }, 3, PREFIX, RIGHT_TO_LEFT },
+       { "*", { }, 4, BINARY, ASSOCIATIVE },
+       { "/", { }, 4, BINARY, LEFT_TO_RIGHT },
+       { "%", { }, 4, BINARY, LEFT_TO_RIGHT },
+       { "+", { }, 5, BINARY, ASSOCIATIVE },
+       { "-", { }, 5, BINARY, LEFT_TO_RIGHT },
+       { "<<", { }, 6, BINARY, LEFT_TO_RIGHT },
+       { ">>", { }, 6, BINARY, LEFT_TO_RIGHT },
+       { "<", { }, 7, BINARY, LEFT_TO_RIGHT },
+       { ">", { }, 7, BINARY, LEFT_TO_RIGHT },
+       { "<=", { }, 7, BINARY, LEFT_TO_RIGHT },
+       { ">=", { }, 7, BINARY, LEFT_TO_RIGHT },
+       { "==", { }, 8, BINARY, LEFT_TO_RIGHT },
+       { "!=", { }, 8, BINARY, LEFT_TO_RIGHT },
+       { "&", { }, 9, BINARY, ASSOCIATIVE },
+       { "^", { }, 10, BINARY, ASSOCIATIVE },
+       { "|", { }, 11, BINARY, ASSOCIATIVE },
+       { "&&", { }, 12, BINARY, ASSOCIATIVE },
+       { "^^", { }, 13, BINARY, ASSOCIATIVE },
+       { "||", { }, 14, BINARY, ASSOCIATIVE },
+       { "?", ":", 15, TERNARY, RIGHT_TO_LEFT },
+       { "=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "+=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "-=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "*=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "/=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "%=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "<<=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { ">>=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "&=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "^=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { "|=", { }, 16, BINARY, RIGHT_TO_LEFT },
+       { ",", { }, 17, BINARY, LEFT_TO_RIGHT },
+       { { 0 }, { }, 18, NO_OPERATOR, LEFT_TO_RIGHT }
 };
 
 const Operator &Operator::get_operator(const string &token, Type type)
@@ -106,12 +105,6 @@ void Literal::visit(NodeVisitor &visitor)
 }
 
 
-void ParenthesizedExpression::visit(NodeVisitor &visitor)
-{
-       visitor.visit(*this);
-}
-
-
 VariableReference::VariableReference():
        declaration(0)
 { }
@@ -376,7 +369,7 @@ InterfaceBlock::InterfaceBlock():
 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
        Statement(other),
        interface(other.interface),
-       name(other.name),
+       block_name(other.block_name),
        members(other.members),
        instance_name(other.instance_name),
        array(other.array),
@@ -471,6 +464,95 @@ Module::Module():
        shared(Stage::SHARED)
 { }
 
+
+string get_unused_variable_name(const Block &block, const string &base)
+{
+       string name = base;
+
+       unsigned number = 1;
+       unsigned base_size = name.size();
+       while(1)
+       {
+               bool unused = true;
+               for(const Block *b=&block; (unused && b); b=b->parent)
+                       unused = !b->variables.count(name);
+               if(unused)
+                       return name;
+
+               name.erase(base_size);
+               name += format("_%d", number);
+               ++number;
+       }
+}
+
+bool is_same_type(const TypeDeclaration &type1, const TypeDeclaration &type2)
+{
+       if(const BasicTypeDeclaration *basic1 = dynamic_cast<const BasicTypeDeclaration *>(&type1))
+       {
+               const BasicTypeDeclaration *basic2 = dynamic_cast<const BasicTypeDeclaration *>(&type2);
+               if(!basic2)
+                       return false;
+
+               if(basic1->kind!=basic2->kind || basic1->size!=basic2->size)
+                       return false;
+
+               if(basic1->base_type && basic2->base_type)
+                       return is_same_type(*basic1->base_type, *basic2->base_type);
+               else
+                       return (!basic1->base_type && !basic2->base_type);
+       }
+       else if(const ImageTypeDeclaration *image1 = dynamic_cast<const ImageTypeDeclaration *>(&type1))
+       {
+               const ImageTypeDeclaration *image2 = dynamic_cast<const ImageTypeDeclaration *>(&type2);
+               if(!image2)
+                       return false;
+
+               if(image1->dimensions!=image2->dimensions || image1->array!=image2->array)
+                       return false;
+               if(image1->sampled!=image2->sampled || image1->shadow!=image2->shadow)
+                       return false;
+
+               if(image1->base_type && image2->base_type)
+                       return is_same_type(*image1->base_type, *image2->base_type);
+               else
+                       return (!image1->base_type && !image2->base_type);
+       }
+       else if(const StructDeclaration *strct1 = dynamic_cast<const StructDeclaration *>(&type1))
+       {
+               const StructDeclaration *strct2 = dynamic_cast<const StructDeclaration *>(&type2);
+               if(!strct2)
+                       return false;
+
+               NodeList<Statement>::const_iterator i = strct1->members.body.begin();
+               NodeList<Statement>::const_iterator j = strct2->members.body.begin();
+               for(; (i!=strct1->members.body.end() && j!=strct2->members.body.end()); ++i, ++j)
+               {
+                       const VariableDeclaration *var1 = dynamic_cast<const VariableDeclaration *>(i->get());
+                       const VariableDeclaration *var2 = dynamic_cast<const VariableDeclaration *>(j->get());
+                       if(!var1 || !var1->type_declaration || !var2 || !var2->type_declaration)
+                               return false;
+                       if(!is_same_type(*var1->type_declaration, *var2->type_declaration))
+                               return false;
+                       if(var1->name!=var2->name || var1->array!=var2->array)
+                               return false;
+                       // TODO Compare array sizes
+                       // TODO Compare layout qualifiers for interface block members
+               }
+
+               return (i==strct1->members.body.end() && j==strct2->members.body.end());
+       }
+       else
+               return false;
+}
+
+int get_layout_value(const Layout &layout, const string &name, int def_value)
+{
+       for(vector<Layout::Qualifier>::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i)
+               if(i->name==name)
+                       return i->value;
+       return def_value;
+}
+
 } // namespace SL
 } // namespace GL
 } // namespace Msp