#ifndef MSP_GL_PROGRAMSYNTAX_H_
#define MSP_GL_PROGRAMSYNTAX_H_
+#include <list>
#include <map>
#include <string>
#include <vector>
+#include <msp/core/refptr.h>
+#include "extension.h"
+#include "uniform.h"
+
+#pragma push_macro("interface")
+#undef interface
namespace Msp {
namespace GL {
struct Node
{
+private:
+ Node &operator=(const Node &);
+public:
virtual ~Node() { }
+ virtual Node *clone() const = 0;
virtual void visit(NodeVisitor &) = 0;
};
+template<typename T>
+class NodePtr: public RefPtr<T>
+{
+public:
+ NodePtr() { }
+ NodePtr(T *p): RefPtr<T>(p) { }
+ NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
+
+ template<typename U>
+ NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
+
+ template<typename U>
+ NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
+};
+
+template<typename C>
+class NodeContainer: public C
+{
+public:
+ NodeContainer() { }
+ NodeContainer(const NodeContainer &);
+};
+
+template<typename T>
+class NodeList: public NodeContainer<std::list<RefPtr<T> > >
+{ };
+
+template<typename T>
+class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
+{ };
+
+struct StructDeclaration;
+struct VariableDeclaration;
+struct FunctionDeclaration;
+
+struct Statement: Node
+{
+ virtual Statement *clone() const = 0;
+};
+
struct Block: Node
{
- std::vector<Node *> body;
+ NodeList<Statement> body;
bool use_braces;
+ std::map<std::string, StructDeclaration *> types;
+ std::map<std::string, VariableDeclaration *> variables;
Block();
- virtual ~Block();
+ virtual Block *clone() const { return new Block(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct Expression: Node
+{
+ virtual Expression *clone() const = 0;
+};
+
+struct Literal: Expression
+{
+ std::string token;
+
+ virtual Literal *clone() const { return new Literal(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct ParenthesizedExpression: Expression
+{
+ NodePtr<Expression> expression;
+
+ virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct VariableReference: Expression
+{
+ std::string name;
+ VariableDeclaration *declaration;
+
+ VariableReference();
+
+ virtual VariableReference *clone() const { return new VariableReference(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct MemberAccess: Expression
+{
+ NodePtr<Expression> left;
+ std::string member;
+ VariableDeclaration *declaration;
+
+ virtual MemberAccess *clone() const { return new MemberAccess(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct UnaryExpression: Expression
+{
+ std::string oper;
+ NodePtr<Expression> expression;
+ bool prefix;
+
+ UnaryExpression();
+
+ virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct BinaryExpression: Expression
+{
+ NodePtr<Expression> left;
+ std::string oper;
+ NodePtr<Expression> right;
+ std::string after;
+
+ virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
virtual void visit(NodeVisitor &);
};
-struct Expression
+struct Assignment: BinaryExpression
{
- std::vector<std::string> tokens;
+ bool self_referencing;
+ VariableDeclaration *target_declaration;
- bool empty() const { return tokens.empty(); }
+ Assignment();
+
+ virtual Assignment *clone() const { return new Assignment(*this); }
+ virtual void visit(NodeVisitor &);
};
-struct ExpressionStatement: Node
+struct FunctionCall: Expression
{
- Expression expression;
+ std::string name;
+ FunctionDeclaration *declaration;
+ bool constructor;
+ NodeArray<Expression> arguments;
+ FunctionCall();
+
+ virtual FunctionCall *clone() const { return new FunctionCall(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct ExpressionStatement: Statement
+{
+ NodePtr<Expression> expression;
+
+ virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct Import: Statement
+{
+ std::string module;
+
+ virtual Import *clone() const { return new Import(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct Precision: Statement
+{
+ std::string precision;
+ std::string type;
+
+ virtual Precision *clone() const { return new Precision(*this); }
virtual void visit(NodeVisitor &);
};
{
struct Qualifier
{
+ // TODO the standard calls this name, not identifier
std::string identifier;
std::string value;
};
std::vector<Qualifier> qualifiers;
+
+ virtual Layout *clone() const { return new Layout(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct InterfaceLayout: Statement
+{
std::string interface;
+ Layout layout;
+ virtual InterfaceLayout *clone() const { return new InterfaceLayout(*this); }
virtual void visit(NodeVisitor &);
};
-struct StructDeclaration: Node
+struct StructDeclaration: Statement
{
std::string name;
Block members;
StructDeclaration();
+ virtual StructDeclaration *clone() const { return new StructDeclaration(*this); }
virtual void visit(NodeVisitor &);
};
-struct VariableDeclaration: Node
+struct VariableDeclaration: Statement
{
bool constant;
std::string sampling;
+ std::string interpolation;
std::string interface;
+ std::string precision;
std::string type;
+ StructDeclaration *type_declaration;
std::string name;
bool array;
- Expression array_size;
- Expression init_expression;
+ NodePtr<Expression> array_size;
+ NodePtr<Expression> init_expression;
+ VariableDeclaration *linked_declaration;
+ NodePtr<Layout> layout;
VariableDeclaration();
+ virtual VariableDeclaration *clone() const { return new VariableDeclaration(*this); }
virtual void visit(NodeVisitor &);
};
-struct InterfaceBlock: Node
+struct InterfaceBlock: Statement
{
std::string interface;
std::string name;
Block members;
+ std::string instance_name;
+ bool array;
InterfaceBlock();
+ virtual InterfaceBlock *clone() const { return new InterfaceBlock(*this); }
virtual void visit(NodeVisitor &);
};
-struct FunctionDeclaration: Node
+struct FunctionDeclaration: Statement
{
std::string return_type;
std::string name;
- std::vector<VariableDeclaration *> parameters;
- bool definition;
+ NodeArray<VariableDeclaration> parameters;
+ FunctionDeclaration *definition;
Block body;
FunctionDeclaration();
- ~FunctionDeclaration();
+ FunctionDeclaration(const FunctionDeclaration &);
+ virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
virtual void visit(NodeVisitor &);
};
-struct Conditional: Node
+struct Conditional: Statement
{
- Expression condition;
+ NodePtr<Expression> condition;
Block body;
Block else_body;
+ virtual Conditional *clone() const { return new Conditional(*this); }
virtual void visit(NodeVisitor &);
};
-struct Iteration: Node
+struct Iteration: Statement
{
- Node *init_statement;
- Expression condition;
- Expression loop_expression;
+ NodePtr<Node> init_statement;
+ NodePtr<Expression> condition;
+ NodePtr<Expression> loop_expression;
Block body;
- Iteration();
- virtual ~Iteration();
+ virtual Iteration *clone() const { return new Iteration(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct Passthrough: Statement
+{
+ NodePtr<Expression> subscript;
+ virtual Passthrough *clone() const { return new Passthrough(*this); }
virtual void visit(NodeVisitor &);
};
-struct Return: Node
+struct Return: Statement
{
- Expression expression;
+ NodePtr<Expression> expression;
+ virtual Return *clone() const { return new Return(*this); }
+ virtual void visit(NodeVisitor &);
+};
+
+struct Jump: Statement
+{
+ std::string keyword;
+
+ virtual Jump *clone() const { return new Jump(*this); }
virtual void visit(NodeVisitor &);
};
virtual ~NodeVisitor() { }
virtual void visit(Block &) { }
+ virtual void visit(Literal &) { }
+ virtual void visit(ParenthesizedExpression &) { }
+ virtual void visit(VariableReference &) { }
+ virtual void visit(MemberAccess &) { }
+ virtual void visit(UnaryExpression &) { }
+ virtual void visit(BinaryExpression &) { }
+ virtual void visit(Assignment &);
+ virtual void visit(FunctionCall &) { }
virtual void visit(ExpressionStatement &) { }
+ virtual void visit(Import &) { }
+ virtual void visit(Precision &) { }
virtual void visit(Layout &) { }
+ virtual void visit(InterfaceLayout &) { }
virtual void visit(StructDeclaration &) { }
virtual void visit(VariableDeclaration &) { }
virtual void visit(InterfaceBlock &) { }
virtual void visit(FunctionDeclaration &) { }
virtual void visit(Conditional &) { }
virtual void visit(Iteration &) { }
+ virtual void visit(Passthrough &) { }
virtual void visit(Return &) { }
+ virtual void visit(Jump &) { }
};
-enum ContextType
+struct TraversingVisitor: NodeVisitor
{
- GLOBAL,
+ using NodeVisitor::visit;
+ virtual void visit(Block &);
+ virtual void visit(ParenthesizedExpression &);
+ virtual void visit(MemberAccess &);
+ virtual void visit(UnaryExpression &);
+ 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 &);
+ virtual void visit(FunctionDeclaration &);
+ virtual void visit(Conditional &);
+ virtual void visit(Iteration &);
+ virtual void visit(Passthrough &);
+ virtual void visit(Return &);
+};
+
+enum StageType
+{
+ SHARED,
VERTEX,
GEOMETRY,
FRAGMENT
};
-struct Context
+struct Stage
{
- ContextType type;
- bool present;
+ StageType type;
+ Stage *previous;
ProgramSyntax::Block content;
+ std::map<std::string, VariableDeclaration *> in_variables;
+ std::map<std::string, VariableDeclaration *> out_variables;
+ std::map<std::string, unsigned> locations;
+ Version required_version;
+ std::vector<const Extension *> required_extensions;
- Context(ContextType);
+ Stage(StageType);
};
struct Module
{
- Context global_context;
- Context vertex_context;
- Context geometry_context;
- Context fragment_context;
- std::map<std::string, StructDeclaration *> structs;
+ Stage shared;
+ std::list<Stage> stages;
Module();
};
} // namespace GL
} // namespace Msp
+#pragma pop_macro("interface")
+
#endif