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)
void ProgramCompiler::Formatter::visit(VariableDeclaration &var)
{
+ if(var.layout)
+ {
+ var.layout->visit(*this);
+ formatted += ' ';
+ }
if(var.constant)
formatted += "const ";
if(!var.sampling.empty())
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 &);
if(token=="import")
return parse_import();
else if(token=="layout")
- return parse_layout();
+ {
+ RefPtr<Layout> layout = parse_layout();
+ token = peek_token();
+ if(is_interface_qualifier(token) && peek_token(1)==";")
+ {
+ RefPtr<InterfaceLayout> 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")
expect(",");
}
expect(")");
- layout->interface = parse_token();
- expect(";");
return layout.release();
}
}
+void InterfaceLayout::visit(NodeVisitor &visitor)
+{
+ visitor.visit(*this);
+}
+
+
StructDeclaration::StructDeclaration()
{
members.use_braces = true;
expr.expression->visit(*this);
}
+void TraversingVisitor::visit(InterfaceLayout &layout)
+{
+ layout.layout.visit(*this);
+}
+
void TraversingVisitor::visit(StructDeclaration &strct)
{
strct.members.visit(*this);
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)
};
std::vector<Qualifier> 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;
NodePtr<Expression> array_size;
NodePtr<Expression> init_expression;
VariableDeclaration *linked_declaration;
+ NodePtr<Layout> layout;
VariableDeclaration();
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 &) { }
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 &);