]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/syntax.h
2a9dcf84869261298d404248c3fd138de41fc498
[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         char token2[2];
43         UInt8 precedence;
44         Type type;
45         Associativity assoc;
46
47         static const Operator operators[];
48
49         static const Operator &get_operator(const std::string &, Type);
50 };
51
52 enum
53 {
54         INTERNAL_SOURCE = -2,
55         BUILTIN_SOURCE = -1,
56         GENERATED_SOURCE = 0
57 };
58
59 struct NodeVisitor;
60
61 struct Node
62 {
63         int source;
64         unsigned line;
65
66         Node(): source(GENERATED_SOURCE), line(1) { }
67         Node(const Node &n): source(n.source), line(n.line) { }
68 private:
69         Node &operator=(const Node &);
70 public:
71         virtual ~Node() { }
72
73         virtual Node *clone() const = 0;
74         virtual void visit(NodeVisitor &) = 0;
75 };
76
77 template<typename T>
78 class NodePtr: public RefPtr<T>
79 {
80 public:
81         NodePtr() { }
82         NodePtr(T *p): RefPtr<T>(p) { }
83         NodePtr(const NodePtr &p): RefPtr<T>(p ? p->clone() : 0) { }
84         NodePtr &operator=(const NodePtr &p) { RefPtr<T>::operator=(p); return *this; }
85
86         template<typename U>
87         NodePtr(const RefPtr<U> &p): RefPtr<T>(p) { }
88
89         template<typename U>
90         NodePtr(const NodePtr<U> &p): RefPtr<T>(p ? p->clone() : 0) { }
91 };
92
93 template<typename C>
94 class NodeContainer: public C
95 {
96 public:
97         NodeContainer() { }
98         NodeContainer(const NodeContainer &);
99
100         void push_back_nocopy(const typename C::value_type &v)
101         { C::push_back(0); C::back() = v; }
102 };
103
104 template<typename T>
105 class NodeList: public NodeContainer<std::list<RefPtr<T> > >
106 { };
107
108 template<typename T>
109 class NodeArray: public NodeContainer<std::vector<RefPtr<T> > >
110 { };
111
112 struct TypeDeclaration;
113 struct VariableDeclaration;
114 struct InterfaceBlock;
115 struct FunctionDeclaration;
116
117 struct Statement: Node
118 {
119         virtual Statement *clone() const = 0;
120 };
121
122 struct Block: Node
123 {
124         NodeList<Statement> body;
125         bool use_braces;
126
127         std::map<std::string, VariableDeclaration *> variables;
128         Block *parent;
129
130         Block();
131         Block(const Block &);
132
133         virtual Block *clone() const { return new Block(*this); }
134         virtual void visit(NodeVisitor &);
135 };
136
137 struct Expression: Node
138 {
139         const Operator *oper;
140
141         TypeDeclaration *type;
142         bool lvalue;
143
144         Expression();
145
146         virtual Expression *clone() const = 0;
147 };
148
149 struct Literal: Expression
150 {
151         std::string token;
152         Variant value;
153
154         virtual Literal *clone() const { return new Literal(*this); }
155         virtual void visit(NodeVisitor &);
156 };
157
158 struct VariableReference: Expression
159 {
160         std::string name;
161
162         VariableDeclaration *declaration;
163
164         VariableReference();
165         VariableReference(const VariableReference &);
166
167         virtual VariableReference *clone() const { return new VariableReference(*this); }
168         virtual void visit(NodeVisitor &);
169 };
170
171 struct InterfaceBlockReference: Expression
172 {
173         std::string name;
174
175         InterfaceBlock *declaration;
176
177         InterfaceBlockReference();
178         InterfaceBlockReference(const InterfaceBlockReference &);
179
180         virtual InterfaceBlockReference *clone() const { return new InterfaceBlockReference(*this); }
181         virtual void visit(NodeVisitor &);
182 };
183
184 struct MemberAccess: Expression
185 {
186         NodePtr<Expression> left;
187         std::string member;
188
189         VariableDeclaration *declaration;
190         int index;
191
192         MemberAccess();
193         MemberAccess(const MemberAccess &);
194
195         virtual MemberAccess *clone() const { return new MemberAccess(*this); }
196         virtual void visit(NodeVisitor &);
197 };
198
199 struct Swizzle: Expression
200 {
201         NodePtr<Expression> left;
202         std::string component_group;
203         unsigned count;
204         UInt8 components[4];
205
206         Swizzle();
207
208         virtual Swizzle *clone() const { return new Swizzle(*this); }
209         virtual void visit(NodeVisitor &);
210 };
211
212 struct UnaryExpression: Expression
213 {
214         NodePtr<Expression> expression;
215
216         virtual UnaryExpression *clone() const { return new UnaryExpression(*this); }
217         virtual void visit(NodeVisitor &);
218 };
219
220 struct BinaryExpression: Expression
221 {
222         NodePtr<Expression> left;
223         NodePtr<Expression> right;
224
225         virtual BinaryExpression *clone() const { return new BinaryExpression(*this); }
226         virtual void visit(NodeVisitor &);
227 };
228
229 struct Assignment: BinaryExpression
230 {
231         struct Target
232         {
233                 enum ChainType
234                 {
235                         MEMBER = 0x40,
236                         SWIZZLE = 0x80,
237                         ARRAY = 0xC0
238                 };
239
240                 Statement *declaration;
241                 Msp::UInt8 chain_len;
242                 Msp::UInt8 chain[7];
243
244                 Target(Statement * = 0);
245
246                 bool operator<(const Target &) const;
247         };
248
249         bool self_referencing;
250
251         Target target;
252
253         Assignment();
254         Assignment(const Assignment &);
255
256         virtual Assignment *clone() const { return new Assignment(*this); }
257         virtual void visit(NodeVisitor &);
258 };
259
260 struct TernaryExpression: Expression
261 {
262         NodePtr<Expression> condition;
263         NodePtr<Expression> true_expr;
264         NodePtr<Expression> false_expr;
265
266         virtual TernaryExpression *clone() const { return new TernaryExpression(*this); }
267         virtual void visit(NodeVisitor &);
268 };
269
270 struct FunctionCall: Expression
271 {
272         std::string name;
273         bool constructor;
274         NodeArray<Expression> arguments;
275
276         FunctionDeclaration *declaration;
277
278         FunctionCall();
279         FunctionCall(const FunctionCall &);
280
281         virtual FunctionCall *clone() const { return new FunctionCall(*this); }
282         virtual void visit(NodeVisitor &);
283 };
284
285 struct ExpressionStatement: Statement
286 {
287         NodePtr<Expression> expression;
288
289         virtual ExpressionStatement *clone() const { return new ExpressionStatement(*this); }
290         virtual void visit(NodeVisitor &);
291 };
292
293 struct Import: Statement
294 {
295         std::string module;
296
297         virtual Import *clone() const { return new Import(*this); }
298         virtual void visit(NodeVisitor &);
299 };
300
301 struct Precision: Statement
302 {
303         std::string precision;
304         std::string type;
305
306         virtual Precision *clone() const { return new Precision(*this); }
307         virtual void visit(NodeVisitor &);
308 };
309
310 struct Layout: Node
311 {
312         struct Qualifier
313         {
314                 std::string name;
315                 bool has_value;
316                 int value;
317
318                 Qualifier(const std::string &n = std::string()): name(n), has_value(false), value(0) { }
319                 Qualifier(const std::string &n, int v): name(n), has_value(true), value(v) { }
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         NodePtr<Layout> layout;
437         std::string interface;
438         std::string block_name;
439         NodePtr<Block> members;
440         std::string instance_name;
441         bool array;
442
443         /* An interface block's ultimate base type is always a struct.  The
444         immediate type may be either that same struct or an array of it. */
445         TypeDeclaration *type_declaration;
446         StructDeclaration *struct_declaration;
447         InterfaceBlock *linked_block;
448
449         InterfaceBlock();
450         InterfaceBlock(const InterfaceBlock &);
451         ~InterfaceBlock();
452
453         virtual InterfaceBlock *clone() const { return new InterfaceBlock(*this); }
454         virtual void visit(NodeVisitor &);
455 };
456
457 struct FunctionDeclaration: Statement
458 {
459         std::string return_type;
460         std::string name;
461         NodeArray<VariableDeclaration> parameters;
462         bool virtua;
463         bool overrd;
464         Block body;
465
466         std::string signature;
467         FunctionDeclaration *definition;
468         TypeDeclaration *return_type_declaration;
469
470         FunctionDeclaration();
471         FunctionDeclaration(const FunctionDeclaration &);
472
473         virtual FunctionDeclaration *clone() const { return new FunctionDeclaration(*this); }
474         virtual void visit(NodeVisitor &);
475 };
476
477 struct Conditional: Statement
478 {
479         NodePtr<Expression> condition;
480         Block body;
481         Block else_body;
482
483         virtual Conditional *clone() const { return new Conditional(*this); }
484         virtual void visit(NodeVisitor &);
485 };
486
487 struct Iteration: Statement
488 {
489         NodePtr<Statement> init_statement;
490         NodePtr<Expression> condition;
491         NodePtr<Expression> loop_expression;
492         Block body;
493
494         virtual Iteration *clone() const { return new Iteration(*this); }
495         virtual void visit(NodeVisitor &);
496 };
497
498 struct Passthrough: Statement
499 {
500         NodePtr<Expression> subscript;
501
502         virtual Passthrough *clone() const { return new Passthrough(*this); }
503         virtual void visit(NodeVisitor &);
504 };
505
506 struct Return: Statement
507 {
508         NodePtr<Expression> expression;
509
510         virtual Return *clone() const { return new Return(*this); }
511         virtual void visit(NodeVisitor &);
512 };
513
514 struct Jump: Statement
515 {
516         std::string keyword;
517
518         virtual Jump *clone() const { return new Jump(*this); }
519         virtual void visit(NodeVisitor &);
520 };
521
522 struct Stage
523 {
524         enum Type
525         {
526                 SHARED,
527                 VERTEX,
528                 GEOMETRY,
529                 FRAGMENT
530         };
531
532         Type type;
533         Stage *previous;
534         Block content;
535         std::map<std::string, TypeDeclaration *> types;
536         std::map<std::string, InterfaceBlock *> interface_blocks;
537         std::map<std::string, FunctionDeclaration *> functions;
538         std::map<std::string, unsigned> locations;
539         std::map<std::string, unsigned> texture_bindings;
540         std::map<std::string, unsigned> uniform_block_bindings;
541         Features required_features;
542         std::vector<Diagnostic> diagnostics;
543
544         Stage(Type);
545
546         static const char *get_stage_name(Type);
547 };
548
549 struct Module
550 {
551         SourceMap source_map;
552         Stage shared;
553         std::list<Stage> stages;
554
555         Module();
556 };
557
558 std::string get_unused_variable_name(const Block &, const std::string &);
559
560 bool is_same_type(const TypeDeclaration &, const TypeDeclaration &);
561 int get_layout_value(const Layout &, const std::string &, int = -1);
562 void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
563
564 } // namespace SL
565 } // namespace GL
566 } // namespace Msp
567
568 #pragma pop_macro("interface")
569
570 #endif