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