From: Mikko Rasa Date: Sat, 19 Nov 2016 16:23:58 +0000 (+0200) Subject: Support layout declarations on variables X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=8812fe9fc71b997246ddfdedb8a91932b679d2d3 Support layout declarations on variables --- diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index aef17fa2..ece48cf0 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -334,7 +334,13 @@ void ProgramCompiler::Formatter::visit(Layout &layout) if(!i->value.empty()) formatted += format("=%s", i->value); } - formatted += format(") %s;", layout.interface); + formatted += ')'; +} + +void ProgramCompiler::Formatter::visit(InterfaceLayout &layout) +{ + layout.layout.visit(*this); + formatted += format(" %s;", layout.interface); } void ProgramCompiler::Formatter::visit(StructDeclaration &strct) @@ -346,6 +352,11 @@ void ProgramCompiler::Formatter::visit(StructDeclaration &strct) void ProgramCompiler::Formatter::visit(VariableDeclaration &var) { + if(var.layout) + { + var.layout->visit(*this); + formatted += ' '; + } if(var.constant) formatted += "const "; if(!var.sampling.empty()) diff --git a/source/programcompiler.h b/source/programcompiler.h index 8ae22901..2a31a962 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -52,6 +52,7 @@ private: virtual void visit(ProgramSyntax::ExpressionStatement &); virtual void visit(ProgramSyntax::Import &); virtual void visit(ProgramSyntax::Layout &); + virtual void visit(ProgramSyntax::InterfaceLayout &); virtual void visit(ProgramSyntax::StructDeclaration &); virtual void visit(ProgramSyntax::VariableDeclaration &); virtual void visit(ProgramSyntax::InterfaceBlock &); diff --git a/source/programparser.cpp b/source/programparser.cpp index ddea9640..596ed045 100644 --- a/source/programparser.cpp +++ b/source/programparser.cpp @@ -335,7 +335,24 @@ Node *ProgramParser::parse_global_declaration() if(token=="import") return parse_import(); else if(token=="layout") - return parse_layout(); + { + RefPtr layout = parse_layout(); + token = peek_token(); + if(is_interface_qualifier(token) && peek_token(1)==";") + { + RefPtr iface_lo = new InterfaceLayout; + iface_lo->layout.qualifiers = layout->qualifiers; + iface_lo->interface = parse_token(); + expect(";"); + return iface_lo.release(); + } + else + { + VariableDeclaration *var = parse_variable_declaration(); + var->layout = layout.release(); + return var; + } + } else if(token=="struct") return parse_struct_declaration(); else if(is_sampling_qualifier(token) || token=="const") @@ -421,8 +438,6 @@ Layout *ProgramParser::parse_layout() expect(","); } expect(")"); - layout->interface = parse_token(); - expect(";"); return layout.release(); } diff --git a/source/programsyntax.cpp b/source/programsyntax.cpp index 098130f8..c6e0f6d4 100644 --- a/source/programsyntax.cpp +++ b/source/programsyntax.cpp @@ -100,6 +100,12 @@ void Layout::visit(NodeVisitor &visitor) } +void InterfaceLayout::visit(NodeVisitor &visitor) +{ + visitor.visit(*this); +} + + StructDeclaration::StructDeclaration() { members.use_braces = true; @@ -222,6 +228,11 @@ void TraversingVisitor::visit(ExpressionStatement &expr) expr.expression->visit(*this); } +void TraversingVisitor::visit(InterfaceLayout &layout) +{ + layout.layout.visit(*this); +} + void TraversingVisitor::visit(StructDeclaration &strct) { strct.members.visit(*this); @@ -229,6 +240,8 @@ void TraversingVisitor::visit(StructDeclaration &strct) void TraversingVisitor::visit(VariableDeclaration &var) { + if(var.layout) + var.layout->visit(*this); if(var.init_expression) var.init_expression->visit(*this); if(var.array_size) diff --git a/source/programsyntax.h b/source/programsyntax.h index 2f9f1fc0..796c4b93 100644 --- a/source/programsyntax.h +++ b/source/programsyntax.h @@ -182,12 +182,20 @@ struct Layout: Node }; std::vector qualifiers; - std::string interface; virtual Layout *clone() const { return new Layout(*this); } virtual void visit(NodeVisitor &); }; +struct InterfaceLayout: Node +{ + std::string interface; + Layout layout; + + virtual InterfaceLayout *clone() const { return new InterfaceLayout(*this); } + virtual void visit(NodeVisitor &); +}; + struct StructDeclaration: Node { std::string name; @@ -211,6 +219,7 @@ struct VariableDeclaration: Node NodePtr array_size; NodePtr init_expression; VariableDeclaration *linked_declaration; + NodePtr layout; VariableDeclaration(); @@ -300,6 +309,7 @@ struct NodeVisitor virtual void visit(ExpressionStatement &) { } virtual void visit(Import &) { } virtual void visit(Layout &) { } + virtual void visit(InterfaceLayout &) { } virtual void visit(StructDeclaration &) { } virtual void visit(VariableDeclaration &) { } virtual void visit(InterfaceBlock &) { } @@ -319,6 +329,7 @@ struct TraversingVisitor: NodeVisitor virtual void visit(BinaryExpression &); virtual void visit(FunctionCall &); virtual void visit(ExpressionStatement &); + virtual void visit(InterfaceLayout &); virtual void visit(StructDeclaration &); virtual void visit(VariableDeclaration &); virtual void visit(InterfaceBlock &);