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