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