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