]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/syntax.cpp
Mark constant data as const
[libs/gl.git] / source / glsl / syntax.cpp
1 #include <msp/core/algorithm.h>
2 #include <msp/core/maputils.h>
3 #include "syntax.h"
4 #include "visitor.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10 namespace SL {
11
12 const Operator Operator::operators[] =
13 {
14         { "[", "]", 2, BINARY, LEFT_TO_RIGHT },
15         { "(", ")", 2, POSTFIX, LEFT_TO_RIGHT },
16         { ".", { }, 2, POSTFIX, LEFT_TO_RIGHT },
17         { "++", { }, 2, POSTFIX, LEFT_TO_RIGHT },
18         { "--", { }, 2, POSTFIX, LEFT_TO_RIGHT },
19         { "++", { }, 3, PREFIX, RIGHT_TO_LEFT },
20         { "--", { }, 3, PREFIX, RIGHT_TO_LEFT },
21         { "+", { }, 3, PREFIX, RIGHT_TO_LEFT },
22         { "-", { }, 3, PREFIX, RIGHT_TO_LEFT },
23         { "~", { }, 3, PREFIX, RIGHT_TO_LEFT },
24         { "!", { }, 3, PREFIX, RIGHT_TO_LEFT },
25         { "*", { }, 4, BINARY, ASSOCIATIVE },
26         { "/", { }, 4, BINARY, LEFT_TO_RIGHT },
27         { "%", { }, 4, BINARY, LEFT_TO_RIGHT },
28         { "+", { }, 5, BINARY, ASSOCIATIVE },
29         { "-", { }, 5, BINARY, LEFT_TO_RIGHT },
30         { "<<", { }, 6, BINARY, LEFT_TO_RIGHT },
31         { ">>", { }, 6, BINARY, LEFT_TO_RIGHT },
32         { "<", { }, 7, BINARY, LEFT_TO_RIGHT },
33         { ">", { }, 7, BINARY, LEFT_TO_RIGHT },
34         { "<=", { }, 7, BINARY, LEFT_TO_RIGHT },
35         { ">=", { }, 7, BINARY, LEFT_TO_RIGHT },
36         { "==", { }, 8, BINARY, LEFT_TO_RIGHT },
37         { "!=", { }, 8, BINARY, LEFT_TO_RIGHT },
38         { "&", { }, 9, BINARY, ASSOCIATIVE },
39         { "^", { }, 10, BINARY, ASSOCIATIVE },
40         { "|", { }, 11, BINARY, ASSOCIATIVE },
41         { "&&", { }, 12, BINARY, ASSOCIATIVE },
42         { "^^", { }, 13, BINARY, ASSOCIATIVE },
43         { "||", { }, 14, BINARY, ASSOCIATIVE },
44         { "?", ":", 15, TERNARY, RIGHT_TO_LEFT },
45         { "=", { }, 16, BINARY, RIGHT_TO_LEFT },
46         { "+=", { }, 16, BINARY, RIGHT_TO_LEFT },
47         { "-=", { }, 16, BINARY, RIGHT_TO_LEFT },
48         { "*=", { }, 16, BINARY, RIGHT_TO_LEFT },
49         { "/=", { }, 16, BINARY, RIGHT_TO_LEFT },
50         { "%=", { }, 16, BINARY, RIGHT_TO_LEFT },
51         { "<<=", { }, 16, BINARY, RIGHT_TO_LEFT },
52         { ">>=", { }, 16, BINARY, RIGHT_TO_LEFT },
53         { "&=", { }, 16, BINARY, RIGHT_TO_LEFT },
54         { "^=", { }, 16, BINARY, RIGHT_TO_LEFT },
55         { "|=", { }, 16, BINARY, RIGHT_TO_LEFT },
56         { ",", { }, 17, BINARY, LEFT_TO_RIGHT },
57         { { 0 }, { }, 18, NO_OPERATOR, LEFT_TO_RIGHT }
58 };
59
60 const Operator &Operator::get_operator(const string &token, Type type)
61 {
62         for(const Operator *i=operators; i->type; ++i)
63                 if(i->type==type && i->token==token)
64                         return *i;
65         throw key_error(token);
66 }
67
68
69 template<typename C>
70 NodeContainer<C>::NodeContainer(const NodeContainer &c):
71         C(c)
72 {
73         for(auto &i: *this)
74                 i = i->clone();
75 }
76
77
78 Block::Block():
79         use_braces(false),
80         parent(0)
81 { }
82
83 Block::Block(const Block &other):
84         Node(other),
85         body(other.body),
86         use_braces(other.use_braces),
87         parent(0)
88 { }
89
90 void Block::visit(NodeVisitor &visitor)
91 {
92         visitor.visit(*this);
93 }
94
95
96 Expression::Expression():
97         oper(0),
98         type(0),
99         lvalue(false)
100 { }
101
102
103 void Literal::visit(NodeVisitor &visitor)
104 {
105         visitor.visit(*this);
106 }
107
108
109 VariableReference::VariableReference():
110         declaration(0)
111 { }
112
113 VariableReference::VariableReference(const VariableReference &other):
114         Expression(other),
115         name(other.name),
116         declaration(0)
117 { }
118
119 void VariableReference::visit(NodeVisitor &visitor)
120 {
121         visitor.visit(*this);
122 }
123
124
125 InterfaceBlockReference::InterfaceBlockReference():
126         declaration(0)
127 { }
128
129 InterfaceBlockReference::InterfaceBlockReference(const InterfaceBlockReference &other):
130         Expression(other),
131         name(other.name),
132         declaration(0)
133 { }
134
135 void InterfaceBlockReference::visit(NodeVisitor &visitor)
136 {
137         visitor.visit(*this);
138 }
139
140
141 MemberAccess::MemberAccess():
142         declaration(0),
143         index(-1)
144 { }
145
146 MemberAccess::MemberAccess(const MemberAccess &other):
147         Expression(other),
148         left(other.left),
149         member(other.member),
150         declaration(0),
151         index(-1)
152 { }
153
154 void MemberAccess::visit(NodeVisitor &visitor)
155 {
156         visitor.visit(*this);
157 }
158
159
160 Swizzle::Swizzle():
161         count(0)
162 {
163         fill(components, components+4, 0);
164 }
165
166 void Swizzle::visit(NodeVisitor &visitor)
167 {
168         visitor.visit(*this);
169 }
170
171
172 void UnaryExpression::visit(NodeVisitor &visitor)
173 {
174         visitor.visit(*this);
175 }
176
177
178 void BinaryExpression::visit(NodeVisitor &visitor)
179 {
180         visitor.visit(*this);
181 }
182
183
184 Assignment::Assignment():
185         self_referencing(false)
186 { }
187
188 Assignment::Assignment(const Assignment &other):
189         BinaryExpression(other),
190         self_referencing(other.self_referencing)
191 { }
192
193 void Assignment::visit(NodeVisitor &visitor)
194 {
195         visitor.visit(*this);
196 }
197
198
199 Assignment::Target::Target(Statement *d):
200         declaration(d),
201         chain_len(0)
202 {
203         fill(chain, chain+7, 0);
204 }
205
206 bool Assignment::Target::operator<(const Target &other) const
207 {
208         if(declaration!=other.declaration)
209                 return declaration<other.declaration;
210         for(unsigned i=0; (i<7 && i<chain_len && i<other.chain_len); ++i)
211                 if(chain[i]!=other.chain[i])
212                         return chain[i]<other.chain[i];
213         return chain_len<other.chain_len;
214 }
215
216
217 void TernaryExpression::visit(NodeVisitor &visitor)
218 {
219         visitor.visit(*this);
220 }
221
222
223 FunctionCall::FunctionCall():
224         constructor(false),
225         declaration(0)
226 { }
227
228 FunctionCall::FunctionCall(const FunctionCall &other):
229         Expression(other),
230         name(other.name),
231         constructor(other.constructor),
232         arguments(other.arguments),
233         declaration(0)
234 { }
235
236 void FunctionCall::visit(NodeVisitor &visitor)
237 {
238         visitor.visit(*this);
239 }
240
241
242 void ExpressionStatement::visit(NodeVisitor &visitor)
243 {
244         visitor.visit(*this);
245 }
246
247
248 void Import::visit(NodeVisitor &visitor)
249 {
250         visitor.visit(*this);
251 }
252
253
254 void Precision::visit(NodeVisitor &visitor)
255 {
256         visitor.visit(*this);
257 }
258
259
260 void Layout::visit(NodeVisitor &visitor)
261 {
262         visitor.visit(*this);
263 }
264
265
266 void InterfaceLayout::visit(NodeVisitor &visitor)
267 {
268         visitor.visit(*this);
269 }
270
271
272 BasicTypeDeclaration::BasicTypeDeclaration():
273         kind(ALIAS),
274         size(0),
275         sign(true),
276         base_type(0)
277 { }
278
279 BasicTypeDeclaration::BasicTypeDeclaration(const BasicTypeDeclaration &other):
280         TypeDeclaration(other),
281         kind(other.kind),
282         size(other.size),
283         sign(other.sign),
284         base(other.base),
285         base_type(0)
286 { }
287
288 void BasicTypeDeclaration::visit(NodeVisitor &visitor)
289 {
290         visitor.visit(*this);
291 }
292
293
294 ImageTypeDeclaration::ImageTypeDeclaration():
295         dimensions(TWO),
296         array(false),
297         sampled(true),
298         shadow(false)
299 { }
300
301 void ImageTypeDeclaration::visit(NodeVisitor &visitor)
302 {
303         visitor.visit(*this);
304 }
305
306
307 StructDeclaration::StructDeclaration():
308         interface_block(0)
309 {
310         members.use_braces = true;
311 }
312
313 StructDeclaration::StructDeclaration(const StructDeclaration &other):
314         TypeDeclaration(other),
315         members(other.members),
316         interface_block(0)
317 { }
318
319 StructDeclaration::~StructDeclaration()
320 {
321         if(interface_block && interface_block->struct_declaration==this)
322                 interface_block->struct_declaration = 0;
323 }
324
325 void StructDeclaration::visit(NodeVisitor &visitor)
326 {
327         visitor.visit(*this);
328 }
329
330
331 VariableDeclaration::VariableDeclaration():
332         constant(false),
333         array(false),
334         type_declaration(0),
335         linked_declaration(0)
336 { }
337
338 VariableDeclaration::VariableDeclaration(const VariableDeclaration &other):
339         Statement(other),
340         layout(other.layout),
341         constant(other.constant),
342         sampling(other.sampling),
343         interpolation(other.interpolation),
344         interface(other.interface),
345         precision(other.precision),
346         type(other.type),
347         name(other.name),
348         array(other.array),
349         array_size(other.array_size),
350         init_expression(other.init_expression),
351         type_declaration(0),
352         linked_declaration(0)
353 { }
354
355 VariableDeclaration::~VariableDeclaration()
356 {
357         if(linked_declaration && linked_declaration->linked_declaration==this)
358                 linked_declaration->linked_declaration = 0;
359 }
360
361 void VariableDeclaration::visit(NodeVisitor &visitor)
362 {
363         visitor.visit(*this);
364 }
365
366
367 InterfaceBlock::InterfaceBlock():
368         array(false),
369         type_declaration(0),
370         struct_declaration(0),
371         linked_block(0)
372 { }
373
374 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
375         Statement(other),
376         interface(other.interface),
377         block_name(other.block_name),
378         members(other.members),
379         instance_name(other.instance_name),
380         array(other.array),
381         type_declaration(0),
382         struct_declaration(0),
383         linked_block(0)
384 { }
385
386 InterfaceBlock::~InterfaceBlock()
387 {
388         if(linked_block && linked_block->linked_block==this)
389                 linked_block->linked_block = 0;
390         if(struct_declaration && struct_declaration->interface_block==this)
391                 struct_declaration->interface_block = 0;
392 }
393
394 void InterfaceBlock::visit(NodeVisitor &visitor)
395 {
396         visitor.visit(*this);
397 }
398
399
400 FunctionDeclaration::FunctionDeclaration():
401         virtua(false),
402         overrd(false),
403         definition(0),
404         return_type_declaration(0)
405 { }
406
407 FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
408         Statement(other),
409         return_type(other.return_type),
410         name(other.name),
411         parameters(other.parameters),
412         virtua(other.virtua),
413         overrd(other.overrd),
414         body(other.body),
415         signature(other.signature),
416         definition(other.definition==&other ? this : 0),
417         return_type_declaration(0)
418 { }
419
420 void FunctionDeclaration::visit(NodeVisitor &visitor)
421 {
422         visitor.visit(*this);
423 }
424
425
426 void Conditional::visit(NodeVisitor &visitor)
427 {
428         visitor.visit(*this);
429 }
430
431
432 void Iteration::visit(NodeVisitor &visitor)
433 {
434         visitor.visit(*this);
435 }
436
437
438 void Passthrough::visit(NodeVisitor &visitor)
439 {
440         visitor.visit(*this);
441 }
442
443
444 void Return::visit(NodeVisitor &visitor)
445 {
446         visitor.visit(*this);
447 }
448
449
450 void Jump::visit(NodeVisitor &visitor)
451 {
452         visitor.visit(*this);
453 }
454
455
456 Stage::Stage(Stage::Type t):
457         type(t),
458         previous(0)
459 { }
460
461 const char *Stage::get_stage_name(Type type)
462 {
463         static const char *const names[] = { "shared", "vertex", "geometry", "fragment" };
464         return names[type];
465 }
466
467
468 Module::Module():
469         shared(Stage::SHARED)
470 { }
471
472
473 string get_unused_variable_name(const Block &block, const string &base)
474 {
475         string name = base;
476
477         unsigned number = 1;
478         unsigned base_size = name.size();
479         while(1)
480         {
481                 bool unused = true;
482                 for(const Block *b=&block; (unused && b); b=b->parent)
483                         unused = !b->variables.count(name);
484                 if(unused)
485                         return name;
486
487                 name.erase(base_size);
488                 name += format("_%d", number);
489                 ++number;
490         }
491 }
492
493 int get_layout_value(const Layout &layout, const string &name, int def_value)
494 {
495         auto i = find_member(layout.qualifiers, name, &Layout::Qualifier::name);
496         return (i!=layout.qualifiers.end() ? i->value : def_value);
497 }
498
499 void add_to_chain(Assignment::Target &target, Assignment::Target::ChainType type, unsigned index)
500 {
501         if(target.chain_len<7)
502                 target.chain[target.chain_len] = type | min<unsigned>(index, 0x3F);
503         ++target.chain_len;
504 }
505
506 } // namespace SL
507 } // namespace GL
508 } // namespace Msp