]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/syntax.h
Recognize swizzles in GLSL
[libs/gl.git] / source / glsl / syntax.h
1 #ifndef MSP_GL_SL_SYNTAX_H_
2 #define MSP_GL_SL_SYNTAX_H_
3
4 #include <list>
5 #include <map>
6 #include <set>
7 #include <string>
8 #include <vector>
9 #include <msp/core/inttypes.h>
10 #include <msp/core/refptr.h>
11 #include <msp/core/variant.h>
12 #include "features.h"
13 #include "glsl_error.h"
14 #include "sourcemap.h"
15
16 #pragma push_macro("interface")
17 #undef interface
18
19 namespace Msp {
20 namespace GL {
21 namespace SL {
22
23 struct Operator
24 {
25         enum Type
26         {
27                 NO_OPERATOR,
28                 BINARY,
29                 PREFIX,
30                 POSTFIX
31         };
32
33         enum Associativity
34         {
35                 LEFT_TO_RIGHT,
36                 RIGHT_TO_LEFT,
37                 ASSOCIATIVE
38         };
39
40         char token[4];
41         unsigned precedence;
42         Type type;
43         Associativity assoc;
44
45         static const Operator operators[];
46
47         static const Operator &get_operator(const std::string &, Type);
48 };
49
50 enum
51 {
52         INTERNAL_SOURCE = -2,
53         BUILTIN_SOURCE = -1,
54         GENERATED_SOURCE = 0
55 };
56
57 struct NodeVisitor;
58
59 struct Node
60 {
61         int source;
62         unsigned line;
63
64         Node(): source(GENERATED_SOURCE), line(1) { }
65         Node(const Node &n): source(n.source), line(n.line) { }
66 private:
67         Node &operator=(const Node &);
68 public:
69         virtual ~Node() { }
70
71         virtual Node *clone() const = 0;
72         virtual void visit(NodeVisitor &) = 0;
73 };
74
75 template<typename T>
76 class NodePtr: public RefPtr<T>
77 {
78 public:
79         NodePtr() { }
80         NodePtr(T *p): RefPtr<T>(p) { }
81         NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
82         NodePtr &operator=(const NodePtr &p) { RefPtr<T>::operator=(p); return *this; }
83
84         template<typename U>
85         NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
86
87         template<typename U>
88         NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
89 };
90
91 template<typename C>
92 class NodeContainer: public C
93 {
94 public:
95         NodeContainer() { }
96         NodeContainer(const NodeContainer &);
97 };
98
99 template<typename T>
100 class NodeList: public NodeContainer<std::list<RefPtr<T> > >
101 { };
102
103 template<typename T>
104 class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
105 { };
106
107 struct TypeDeclaration;
108 struct VariableDeclaration;
109 struct InterfaceBlock;
110 struct FunctionDeclaration;
111
112 struct Statement: Node
113 {
114         virtual Statement *clone() const = 0;
115 };
116
117 struct Block: Node
118 {
119         NodeList<Statement> body;
120         bool use_braces;
121
122         std::map<std::string, VariableDeclaration *> variables;
123         Block *parent;
124
125         Block();
126         Block(const Block &);
127
128         virtual Block *clone() const { return new Block(*this); }
129         virtual void visit(NodeVisitor &);
130 };
131
132 struct Expression: Node
133 {
134         const Operator *oper;
135
136         TypeDeclaration *type;
137         bool lvalue;
138
139         Expression();
140
141         virtual Expression *clone() const = 0;
142 };
143
144 struct Literal: Expression
145 {
146         std::string token;
147         Variant value;
148
149         virtual Literal *clone() const { return new Literal(*this); }
150         virtual void visit(NodeVisitor &);
151 };
152
153 struct ParenthesizedExpression: Expression
154 {
155         NodePtr<Expression> expression;
156
157         virtual ParenthesizedExpression *clone() const { return new ParenthesizedExpression(*this); }
158         virtual void visit(NodeVisitor &);
159 };
160
161 struct VariableReference: Expression
162 {
163         std::string name;
164
165         VariableDeclaration *declaration;
166
167         VariableReference();
168         VariableReference(const VariableReference &);
169
170         virtual VariableReference *clone() const { return new VariableReference(*this); }
171         virtual void visit(NodeVisitor &);
172 };
173
174 struct InterfaceBlockReference: Expression
175 {
176         std::string name;
177
178         InterfaceBlock *declaration;
179
180         InterfaceBlockReference();
181         InterfaceBlockReference(const InterfaceBlockReference &);
182
183         virtual InterfaceBlockReference *clone() const { return new InterfaceBlockReference(*this); }
184         virtual void visit(NodeVisitor &);
185 };
186
187 struct MemberAccess: Expression
188 {
189         NodePtr<Expression> left;
190         std::string member;
191
192         VariableDeclaration *declaration;
193
194         MemberAccess();
195         MemberAccess(const MemberAccess &);
196
197         virtual MemberAccess *clone() const { return new MemberAccess(*this); }
198         virtual void visit(NodeVisitor &);
199 };
200
201 struct Swizzle: Expression
202 {
203         NodePtr<Expression> left;
204         std::string component_group;
205         unsigned count;
206         UInt8 components[4];
207
208         Swizzle();
209
210         virtual Swizzle *clone() const { return new Swizzle(*this); }
211         virtual void visit(NodeVisitor &);
212 };
213
214 struct UnaryExpression: Expression
215 {
216         NodePtr<Expression> expression;
217
218         virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
219         virtual void visit(NodeVisitor &);
220 };
221
222 struct BinaryExpression: Expression
223 {
224         NodePtr<Expression> left;
225         NodePtr<Expression> right;
226
227         virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
228         virtual void visit(NodeVisitor &);
229 };
230
231 struct Assignment: BinaryExpression
232 {
233         bool self_referencing;
234
235         VariableDeclaration *target_declaration;
236
237         Assignment();
238         Assignment(const Assignment &);
239
240         virtual Assignment *clone() const { return new Assignment(*this); }
241         virtual void visit(NodeVisitor &);
242 };
243
244 struct FunctionCall: Expression
245 {
246         std::string name;
247         bool constructor;
248         NodeArray<Expression> arguments;
249
250         FunctionDeclaration *declaration;
251
252         FunctionCall();
253         FunctionCall(const FunctionCall &);
254
255         virtual FunctionCall *clone() const { return new FunctionCall(*this); }
256         virtual void visit(NodeVisitor &);
257 };
258
259 struct ExpressionStatement: Statement
260 {
261         NodePtr<Expression> expression;
262
263         virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
264         virtual void visit(NodeVisitor &);
265 };
266
267 struct Import: Statement
268 {
269         std::string module;
270
271         virtual Import *clone() const { return new Import(*this); }
272         virtual void visit(NodeVisitor &);
273 };
274
275 struct Precision: Statement
276 {
277         std::string precision;
278         std::string type;
279
280         virtual Precision *clone() const { return new Precision(*this); }
281         virtual void visit(NodeVisitor &);
282 };
283
284 struct Layout: Node
285 {
286         struct Qualifier
287         {
288                 std::string name;
289                 bool has_value;
290                 int value;
291         };
292
293         std::vector<Qualifier> qualifiers;
294
295         virtual Layout *clone() const { return new Layout(*this); }
296         virtual void visit(NodeVisitor &);
297 };
298
299 struct InterfaceLayout: Statement
300 {
301         std::string interface;
302         Layout layout;
303
304         virtual InterfaceLayout *clone() const { return new InterfaceLayout(*this); }
305         virtual void visit(NodeVisitor &);
306 };
307
308 struct TypeDeclaration: Statement
309 {
310         std::string name;
311
312         virtual TypeDeclaration *clone() const = 0;
313 };
314
315 struct BasicTypeDeclaration: TypeDeclaration
316 {
317         enum Kind
318         {
319                 ALIAS,
320                 VOID,
321                 BOOL,
322                 INT,
323                 FLOAT,
324                 VECTOR,
325                 MATRIX,
326                 ARRAY
327         };
328
329         Kind kind;
330         unsigned size;
331         std::string base;
332
333         TypeDeclaration *base_type;
334
335         BasicTypeDeclaration();
336         BasicTypeDeclaration(const BasicTypeDeclaration &);
337
338         virtual BasicTypeDeclaration *clone() const { return new BasicTypeDeclaration(*this); }
339         virtual void visit(NodeVisitor &);
340 };
341
342 struct ImageTypeDeclaration: TypeDeclaration
343 {
344         enum Dimensions
345         {
346                 ONE = 1,
347                 TWO,
348                 THREE,
349                 CUBE
350         };
351
352         Dimensions dimensions;
353         bool array;
354         bool sampled;
355         bool shadow;
356         std::string base;
357
358         TypeDeclaration *base_type;
359
360         ImageTypeDeclaration();
361
362         virtual ImageTypeDeclaration *clone() const { return new ImageTypeDeclaration(*this); }
363         virtual void visit(NodeVisitor &);
364 };
365
366 struct StructDeclaration: TypeDeclaration
367 {
368         Block members;
369
370         InterfaceBlock *interface_block;
371
372         StructDeclaration();
373         StructDeclaration(const StructDeclaration &);
374         ~StructDeclaration();
375
376         virtual StructDeclaration *clone() const { return new StructDeclaration(*this); }
377         virtual void visit(NodeVisitor &);
378 };
379
380 struct VariableDeclaration: Statement
381 {
382         NodePtr<Layout> layout;
383         bool constant;
384         std::string sampling;
385         std::string interpolation;
386         std::string interface;
387         std::string precision;
388         std::string type;
389         std::string name;
390         bool array;
391         NodePtr<Expression> array_size;
392         NodePtr<Expression> init_expression;
393
394         TypeDeclaration *type_declaration;
395         VariableDeclaration *linked_declaration;
396
397         VariableDeclaration();
398         VariableDeclaration(const VariableDeclaration &);
399         ~VariableDeclaration();
400
401         virtual VariableDeclaration *clone() const { return new VariableDeclaration(*this); }
402         virtual void visit(NodeVisitor &);
403 };
404
405 struct InterfaceBlock: Statement
406 {
407         std::string interface;
408         std::string name;
409         NodePtr<Block> members;
410         std::string instance_name;
411         bool array;
412
413         /* An interface block's ultimate base type is always a struct.  The
414         immediate type may be either that same struct or an array of it. */
415         TypeDeclaration *type_declaration;
416         StructDeclaration *struct_declaration;
417         InterfaceBlock *linked_block;
418
419         InterfaceBlock();
420         InterfaceBlock(const InterfaceBlock &);
421         ~InterfaceBlock();
422
423         virtual InterfaceBlock *clone() const { return new InterfaceBlock(*this); }
424         virtual void visit(NodeVisitor &);
425 };
426
427 struct FunctionDeclaration: Statement
428 {
429         std::string return_type;
430         std::string name;
431         NodeArray<VariableDeclaration> parameters;
432         Block body;
433
434         FunctionDeclaration *definition;
435         TypeDeclaration *return_type_declaration;
436
437         FunctionDeclaration();
438         FunctionDeclaration(const FunctionDeclaration &);
439
440         virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
441         virtual void visit(NodeVisitor &);
442 };
443
444 struct Conditional: Statement
445 {
446         NodePtr<Expression> condition;
447         Block body;
448         Block else_body;
449
450         virtual Conditional *clone() const { return new Conditional(*this); }
451         virtual void visit(NodeVisitor &);
452 };
453
454 struct Iteration: Statement
455 {
456         NodePtr<Statement> init_statement;
457         NodePtr<Expression> condition;
458         NodePtr<Expression> loop_expression;
459         Block body;
460
461         virtual Iteration *clone() const { return new Iteration(*this); }
462         virtual void visit(NodeVisitor &);
463 };
464
465 struct Passthrough: Statement
466 {
467         NodePtr<Expression> subscript;
468
469         virtual Passthrough *clone() const { return new Passthrough(*this); }
470         virtual void visit(NodeVisitor &);
471 };
472
473 struct Return: Statement
474 {
475         NodePtr<Expression> expression;
476
477         virtual Return *clone() const { return new Return(*this); }
478         virtual void visit(NodeVisitor &);
479 };
480
481 struct Jump: Statement
482 {
483         std::string keyword;
484
485         virtual Jump *clone() const { return new Jump(*this); }
486         virtual void visit(NodeVisitor &);
487 };
488
489 struct Stage
490 {
491         enum Type
492         {
493                 SHARED,
494                 VERTEX,
495                 GEOMETRY,
496                 FRAGMENT
497         };
498
499         Type type;
500         Stage *previous;
501         Block content;
502         std::map<std::string, TypeDeclaration *> types;
503         std::map<std::string, InterfaceBlock *> interface_blocks;
504         std::map<std::string, FunctionDeclaration *> functions;
505         std::map<std::string, unsigned> locations;
506         Features required_features;
507         std::vector<Diagnostic> diagnostics;
508
509         Stage(Type);
510
511         static const char *get_stage_name(Type);
512 };
513
514 struct Module
515 {
516         SourceMap source_map;
517         Stage shared;
518         std::list<Stage> stages;
519
520         Module();
521 };
522
523 } // namespace SL
524 } // namespace GL
525 } // namespace Msp
526
527 #pragma pop_macro("interface")
528
529 #endif