X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fsyntax.cpp;h=dff52639b0e2c835d43a4f622f4d4b590d8b13cf;hp=b20f63caf2030887a5a4ea6203346f401253e36b;hb=38712d8ecc57d043a2419ffbaeeb57f7a6586f14;hpb=f08bd843fbe63a0bf5bcbc21308f2751d08f00c1 diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index b20f63ca..dff52639 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -1,3 +1,5 @@ +#include +#include #include "syntax.h" #include "visitor.h" @@ -9,74 +11,70 @@ namespace SL { const Operator Operator::operators[] = { - { "[", 2, BINARY, LEFT_TO_RIGHT }, - { "(", 2, BINARY, 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, LEFT_TO_RIGHT }, - { "/", 4, BINARY, LEFT_TO_RIGHT }, - { "%", 4, BINARY, LEFT_TO_RIGHT }, - { "+", 5, BINARY, LEFT_TO_RIGHT }, - { "-", 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, LEFT_TO_RIGHT }, - { "^", 10, BINARY, LEFT_TO_RIGHT }, - { "|", 11, BINARY, LEFT_TO_RIGHT }, - { "&&", 12, BINARY, LEFT_TO_RIGHT }, - { "^^", 13, BINARY, LEFT_TO_RIGHT }, - { "||", 14, BINARY, LEFT_TO_RIGHT }, - { "?", 15, BINARY, RIGHT_TO_LEFT }, - { ":", 15, 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 }, - { "|=", 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) +{ + for(const Operator *i=operators; i->type; ++i) + if(i->type==type && i->token==token) + return *i; + throw key_error(token); +} + template NodeContainer::NodeContainer(const NodeContainer &c): C(c) { - for(typename C::iterator i=this->begin(); i!=this->end(); ++i) - *i = (*i)->clone(); + for(auto &i: *this) + i = i->clone(); } -Statement::Statement(): - source(0), - line(1) -{ } - - -Block::Block(): - use_braces(false), - parent(0) -{ } - Block::Block(const Block &other): Node(other), body(other.body), @@ -96,35 +94,33 @@ void Literal::visit(NodeVisitor &visitor) } -void ParenthesizedExpression::visit(NodeVisitor &visitor) +VariableReference::VariableReference(const VariableReference &other): + Expression(other), + name(other.name) +{ } + +void VariableReference::visit(NodeVisitor &visitor) { visitor.visit(*this); } -VariableReference::VariableReference(): - declaration(0) +InterfaceBlockReference::InterfaceBlockReference(const InterfaceBlockReference &other): + Expression(other), + name(other.name) { } -VariableReference::VariableReference(const VariableReference &other): - name(other.name), - declaration(0) -{ } - -void VariableReference::visit(NodeVisitor &visitor) +void InterfaceBlockReference::visit(NodeVisitor &visitor) { visitor.visit(*this); } -MemberAccess::MemberAccess(): - declaration(0) -{ } - MemberAccess::MemberAccess(const MemberAccess &other): + Expression(other), left(other.left), - member(other.member), - declaration(0) + member(other.member) + // Do not copy declaration { } void MemberAccess::visit(NodeVisitor &visitor) @@ -133,9 +129,11 @@ void MemberAccess::visit(NodeVisitor &visitor) } -UnaryExpression::UnaryExpression(): - prefix(true) -{ } +void Swizzle::visit(NodeVisitor &visitor) +{ + visitor.visit(*this); +} + void UnaryExpression::visit(NodeVisitor &visitor) { @@ -149,14 +147,10 @@ void BinaryExpression::visit(NodeVisitor &visitor) } -Assignment::Assignment(): - self_referencing(false), - target_declaration(0) -{ } - Assignment::Assignment(const Assignment &other): - self_referencing(other.self_referencing), - target_declaration(0) + BinaryExpression(other), + self_referencing(other.self_referencing) + // Do not copy target { } void Assignment::visit(NodeVisitor &visitor) @@ -165,16 +159,29 @@ void Assignment::visit(NodeVisitor &visitor) } -FunctionCall::FunctionCall(): - declaration(0), - constructor(false) -{ } +bool Assignment::Target::operator<(const Target &other) const +{ + if(declaration!=other.declaration) + return declarationstruct_declaration==this) + interface_block->struct_declaration = 0; +} + void StructDeclaration::visit(NodeVisitor &visitor) { visitor.visit(*this); } -VariableDeclaration::VariableDeclaration(): - constant(false), - type_declaration(0), - array(false), - linked_declaration(0) -{ } - VariableDeclaration::VariableDeclaration(const VariableDeclaration &other): + Statement(other), + layout(other.layout), constant(other.constant), sampling(other.sampling), interpolation(other.interpolation), interface(other.interface), precision(other.precision), type(other.type), - type_declaration(0), name(other.name), array(other.array), array_size(other.array_size), - init_expression(other.init_expression), - linked_declaration(0), - layout(other.layout) + init_expression(other.init_expression) + // Do not copy type and linked declarations { } +VariableDeclaration::~VariableDeclaration() +{ + if(linked_declaration && linked_declaration->linked_declaration==this) + linked_declaration->linked_declaration = 0; +} + void VariableDeclaration::visit(NodeVisitor &visitor) { visitor.visit(*this); } -InterfaceBlock::InterfaceBlock(): - array(false) +InterfaceBlock::InterfaceBlock(const InterfaceBlock &other): + Statement(other), + interface(other.interface), + block_name(other.block_name), + members(other.members), + instance_name(other.instance_name), + array(other.array) + // Do not copy pointers to other nodes +{ } + +InterfaceBlock::~InterfaceBlock() { - members.use_braces = true; + if(linked_block && linked_block->linked_block==this) + linked_block->linked_block = 0; + if(struct_declaration && struct_declaration->interface_block==this) + struct_declaration->interface_block = 0; } void InterfaceBlock::visit(NodeVisitor &visitor) @@ -265,16 +316,17 @@ void InterfaceBlock::visit(NodeVisitor &visitor) } -FunctionDeclaration::FunctionDeclaration(): - definition(0) -{ } - FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other): + Statement(other), return_type(other.return_type), name(other.name), parameters(other.parameters), - definition(other.definition==&other ? this : 0), - body(other.body) + virtua(other.virtua), + overrd(other.overrd), + body(other.body), + signature(other.signature), + definition(other.definition==&other ? this : 0) + // Do not copy return type declaration { } void FunctionDeclaration::visit(NodeVisitor &visitor) @@ -320,7 +372,7 @@ Stage::Stage(Stage::Type t): const char *Stage::get_stage_name(Type type) { - static const char *names[] = { "shared", "vertex", "geometry", "fragment" }; + static const char *const names[] = { "shared", "vertex", "geometry", "fragment" }; return names[type]; } @@ -329,6 +381,40 @@ 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=█ (unused && b); b=b->parent) + unused = !b->variables.count(name); + if(unused) + return name; + + name.erase(base_size); + name += format("_%d", number); + ++number; + } +} + +int get_layout_value(const Layout &layout, const string &name, int def_value) +{ + auto i = find_member(layout.qualifiers, name, &Layout::Qualifier::name); + return (i!=layout.qualifiers.end() ? i->value : def_value); +} + +void add_to_chain(Assignment::Target &target, Assignment::Target::ChainType type, unsigned index) +{ + if(target.chain_len<7) + target.chain[target.chain_len] = type | min(index, 0x3F); + ++target.chain_len; +} + } // namespace SL } // namespace GL } // namespace Msp