]> git.tdb.fi Git - libs/gl.git/blob - source/programsyntax.h
Refactor writing files in the Blender exporter
[libs/gl.git] / source / programsyntax.h
1 #ifndef MSP_GL_PROGRAMSYNTAX_H_
2 #define MSP_GL_PROGRAMSYNTAX_H_
3
4 #include <list>
5 #include <map>
6 #include <string>
7 #include <vector>
8 #include <msp/core/refptr.h>
9 #include "extension.h"
10 #include "uniform.h"
11
12 #pragma push_macro("interface")
13 #undef interface
14
15 namespace Msp {
16 namespace GL {
17 namespace ProgramSyntax {
18
19 struct NodeVisitor;
20
21 struct Node
22 {
23 protected:
24         Node() { }
25         Node(const Node &) { }
26 private:
27         Node &operator=(const Node &);
28 public:
29         virtual ~Node() { }
30
31         virtual Node *clone() const = 0;
32         virtual void visit(NodeVisitor &) = 0;
33 };
34
35 template<typename T>
36 class NodePtr: public RefPtr<T>
37 {
38 public:
39         NodePtr() { }
40         NodePtr(T *p): RefPtr<T>(p) { }
41         NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
42         NodePtr &operator=(const NodePtr &p) { RefPtr<T>::operator=(p); return *this; }
43
44         template<typename U>
45         NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
46
47         template<typename U>
48         NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
49 };
50
51 template<typename C>
52 class NodeContainer: public C
53 {
54 public:
55         NodeContainer() { }
56         NodeContainer(const NodeContainer &);
57 };
58
59 template<typename T>
60 class NodeList: public NodeContainer<std::list<RefPtr<T> > >
61 { };
62
63 template<typename T>
64 class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
65 { };
66
67 struct StructDeclaration;
68 struct VariableDeclaration;
69 struct FunctionDeclaration;
70
71 struct Statement: Node
72 {
73         unsigned source;
74         unsigned line;
75
76         Statement();
77
78         virtual Statement *clone() const = 0;
79 };
80
81 struct Block: Node
82 {
83         NodeList<Statement> body;
84         bool use_braces;
85         std::map<std::string, StructDeclaration *> types;
86         std::map<std::string, VariableDeclaration *> variables;
87
88         Block();
89
90         virtual Block *clone() const { return new Block(*this); }
91         virtual void visit(NodeVisitor &);
92 };
93
94 struct Expression: Node
95 {
96         virtual Expression *clone() const = 0;
97 };
98
99 struct Literal: Expression
100 {
101         std::string token;
102
103         virtual Literal *clone() const { return new Literal(*this); }
104         virtual void visit(NodeVisitor &);
105 };
106
107 struct ParenthesizedExpression: Expression
108 {
109         NodePtr<Expression> expression;
110
111         virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
112         virtual void visit(NodeVisitor &);
113 };
114
115 struct VariableReference: Expression
116 {
117         std::string name;
118         VariableDeclaration *declaration;
119
120         VariableReference();
121
122         virtual VariableReference *clone() const { return new VariableReference(*this); }
123         virtual void visit(NodeVisitor &);
124 };
125
126 struct MemberAccess: Expression
127 {
128         NodePtr<Expression> left;
129         std::string member;
130         VariableDeclaration *declaration;
131
132         virtual MemberAccess *clone() const { return new MemberAccess(*this); }
133         virtual void visit(NodeVisitor &);
134 };
135
136 struct UnaryExpression: Expression
137 {
138         std::string oper;
139         NodePtr<Expression> expression;
140         bool prefix;
141
142         UnaryExpression();
143
144         virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
145         virtual void visit(NodeVisitor &);
146 };
147
148 struct BinaryExpression: Expression
149 {
150         NodePtr<Expression> left;
151         std::string oper;
152         NodePtr<Expression> right;
153         std::string after;
154
155         virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
156         virtual void visit(NodeVisitor &);
157 };
158
159 struct Assignment: BinaryExpression
160 {
161         bool self_referencing;
162         VariableDeclaration *target_declaration;
163
164         Assignment();
165
166         virtual Assignment *clone() const { return new Assignment(*this); }
167         virtual void visit(NodeVisitor &);
168 };
169
170 struct FunctionCall: Expression
171 {
172         std::string name;
173         FunctionDeclaration *declaration;
174         bool constructor;
175         NodeArray<Expression> arguments;
176
177         FunctionCall();
178
179         virtual FunctionCall *clone() const { return new FunctionCall(*this); }
180         virtual void visit(NodeVisitor &);
181 };
182
183 struct ExpressionStatement: Statement
184 {
185         NodePtr<Expression> expression;
186
187         virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
188         virtual void visit(NodeVisitor &);
189 };
190
191 struct Import: Statement
192 {
193         std::string module;
194
195         virtual Import *clone() const { return new Import(*this); }
196         virtual void visit(NodeVisitor &);
197 };
198
199 struct Precision: Statement
200 {
201         std::string precision;
202         std::string type;
203
204         virtual Precision *clone() const { return new Precision(*this); }
205         virtual void visit(NodeVisitor &);
206 };
207
208 struct Layout: Node
209 {
210         struct Qualifier
211         {
212                 // TODO the standard calls this name, not identifier
213                 std::string identifier;
214                 std::string value;
215         };
216
217         std::vector<Qualifier> qualifiers;
218
219         virtual Layout *clone() const { return new Layout(*this); }
220         virtual void visit(NodeVisitor &);
221 };
222
223 struct InterfaceLayout: Statement
224 {
225         std::string interface;
226         Layout layout;
227
228         virtual InterfaceLayout *clone() const { return new InterfaceLayout(*this); }
229         virtual void visit(NodeVisitor &);
230 };
231
232 struct StructDeclaration: Statement
233 {
234         std::string name;
235         Block members;
236
237         StructDeclaration();
238
239         virtual StructDeclaration *clone() const { return new StructDeclaration(*this); }
240         virtual void visit(NodeVisitor &);
241 };
242
243 struct VariableDeclaration: Statement
244 {
245         bool constant;
246         std::string sampling;
247         std::string interpolation;
248         std::string interface;
249         std::string precision;
250         std::string type;
251         StructDeclaration *type_declaration;
252         std::string name;
253         bool array;
254         NodePtr<Expression> array_size;
255         NodePtr<Expression> init_expression;
256         VariableDeclaration *linked_declaration;
257         NodePtr<Layout> layout;
258
259         VariableDeclaration();
260
261         virtual VariableDeclaration *clone() const { return new VariableDeclaration(*this); }
262         virtual void visit(NodeVisitor &);
263 };
264
265 struct InterfaceBlock: Statement
266 {
267         std::string interface;
268         std::string name;
269         Block members;
270         std::string instance_name;
271         bool array;
272
273         InterfaceBlock();
274
275         virtual InterfaceBlock *clone() const { return new InterfaceBlock(*this); }
276         virtual void visit(NodeVisitor &);
277 };
278
279 struct FunctionDeclaration: Statement
280 {
281         std::string return_type;
282         std::string name;
283         NodeArray<VariableDeclaration> parameters;
284         FunctionDeclaration *definition;
285         Block body;
286
287         FunctionDeclaration();
288         FunctionDeclaration(const FunctionDeclaration &);
289
290         virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
291         virtual void visit(NodeVisitor &);
292 };
293
294 struct Conditional: Statement
295 {
296         NodePtr<Expression> condition;
297         Block body;
298         Block else_body;
299
300         virtual Conditional *clone() const { return new Conditional(*this); }
301         virtual void visit(NodeVisitor &);
302 };
303
304 struct Iteration: Statement
305 {
306         NodePtr<Node> init_statement;
307         NodePtr<Expression> condition;
308         NodePtr<Expression> loop_expression;
309         Block body;
310
311         virtual Iteration *clone() const { return new Iteration(*this); }
312         virtual void visit(NodeVisitor &);
313 };
314
315 struct Passthrough: Statement
316 {
317         NodePtr<Expression> subscript;
318
319         virtual Passthrough *clone() const { return new Passthrough(*this); }
320         virtual void visit(NodeVisitor &);
321 };
322
323 struct Return: Statement
324 {
325         NodePtr<Expression> expression;
326
327         virtual Return *clone() const { return new Return(*this); }
328         virtual void visit(NodeVisitor &);
329 };
330
331 struct Jump: Statement
332 {
333         std::string keyword;
334
335         virtual Jump *clone() const { return new Jump(*this); }
336         virtual void visit(NodeVisitor &);
337 };
338
339 struct NodeVisitor
340 {
341         virtual ~NodeVisitor() { }
342
343         virtual void visit(Block &) { }
344         virtual void visit(Literal &) { }
345         virtual void visit(ParenthesizedExpression &) { }
346         virtual void visit(VariableReference &) { }
347         virtual void visit(MemberAccess &) { }
348         virtual void visit(UnaryExpression &) { }
349         virtual void visit(BinaryExpression &) { }
350         virtual void visit(Assignment &);
351         virtual void visit(FunctionCall &) { }
352         virtual void visit(ExpressionStatement &) { }
353         virtual void visit(Import &) { }
354         virtual void visit(Precision &) { }
355         virtual void visit(Layout &) { }
356         virtual void visit(InterfaceLayout &) { }
357         virtual void visit(StructDeclaration &) { }
358         virtual void visit(VariableDeclaration &) { }
359         virtual void visit(InterfaceBlock &) { }
360         virtual void visit(FunctionDeclaration &) { }
361         virtual void visit(Conditional &) { }
362         virtual void visit(Iteration &) { }
363         virtual void visit(Passthrough &) { }
364         virtual void visit(Return &) { }
365         virtual void visit(Jump &) { }
366 };
367
368 struct TraversingVisitor: NodeVisitor
369 {
370         using NodeVisitor::visit;
371         virtual void visit(Block &);
372         virtual void visit(ParenthesizedExpression &);
373         virtual void visit(MemberAccess &);
374         virtual void visit(UnaryExpression &);
375         virtual void visit(BinaryExpression &);
376         virtual void visit(FunctionCall &);
377         virtual void visit(ExpressionStatement &);
378         virtual void visit(InterfaceLayout &);
379         virtual void visit(StructDeclaration &);
380         virtual void visit(VariableDeclaration &);
381         virtual void visit(InterfaceBlock &);
382         virtual void visit(FunctionDeclaration &);
383         virtual void visit(Conditional &);
384         virtual void visit(Iteration &);
385         virtual void visit(Passthrough &);
386         virtual void visit(Return &);
387 };
388
389 enum StageType
390 {
391         SHARED,
392         VERTEX,
393         GEOMETRY,
394         FRAGMENT
395 };
396
397 struct Stage
398 {
399         StageType type;
400         Stage *previous;
401         ProgramSyntax::Block content;
402         std::map<std::string, VariableDeclaration *> in_variables;
403         std::map<std::string, VariableDeclaration *> out_variables;
404         std::map<std::string, unsigned> locations;
405         Version required_version;
406         std::vector<const Extension *> required_extensions;
407
408         Stage(StageType);
409 };
410
411 struct Module
412 {
413         Stage shared;
414         std::list<Stage> stages;
415
416         Module();
417 };
418
419 } // namespace ProgramSyntax
420 } // namespace GL
421 } // namespace Msp
422
423 #pragma pop_macro("interface")
424
425 #endif