]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/syntax.cpp
Fix the declaration of the builtin textureLod function
[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 { }
143
144 MemberAccess::MemberAccess(const MemberAccess &other):
145         Expression(other),
146         left(other.left),
147         member(other.member),
148         declaration(0)
149 { }
150
151 void MemberAccess::visit(NodeVisitor &visitor)
152 {
153         visitor.visit(*this);
154 }
155
156
157 Swizzle::Swizzle():
158         count(0)
159 {
160         fill(components, components+4, 0);
161 }
162
163 void Swizzle::visit(NodeVisitor &visitor)
164 {
165         visitor.visit(*this);
166 }
167
168
169 void UnaryExpression::visit(NodeVisitor &visitor)
170 {
171         visitor.visit(*this);
172 }
173
174
175 void BinaryExpression::visit(NodeVisitor &visitor)
176 {
177         visitor.visit(*this);
178 }
179
180
181 Assignment::Assignment():
182         self_referencing(false)
183 { }
184
185 Assignment::Assignment(const Assignment &other):
186         BinaryExpression(other),
187         self_referencing(other.self_referencing)
188 { }
189
190 void Assignment::visit(NodeVisitor &visitor)
191 {
192         visitor.visit(*this);
193 }
194
195
196 Assignment::Target::Target(Statement *d):
197         declaration(d),
198         chain_len(0)
199 {
200         fill(chain, chain+7, 0);
201 }
202
203 bool Assignment::Target::operator<(const Target &other) const
204 {
205         if(declaration!=other.declaration)
206                 return declaration<other.declaration;
207         for(unsigned i=0; (i<7 && i<chain_len && i<other.chain_len); ++i)
208                 if(chain[i]!=other.chain[i])
209                         return chain[i]<other.chain[i];
210         return chain_len<other.chain_len;
211 }
212
213
214 void TernaryExpression::visit(NodeVisitor &visitor)
215 {
216         visitor.visit(*this);
217 }
218
219
220 FunctionCall::FunctionCall():
221         constructor(false),
222         declaration(0)
223 { }
224
225 FunctionCall::FunctionCall(const FunctionCall &other):
226         Expression(other),
227         name(other.name),
228         constructor(other.constructor),
229         arguments(other.arguments),
230         declaration(0)
231 { }
232
233 void FunctionCall::visit(NodeVisitor &visitor)
234 {
235         visitor.visit(*this);
236 }
237
238
239 void ExpressionStatement::visit(NodeVisitor &visitor)
240 {
241         visitor.visit(*this);
242 }
243
244
245 void Import::visit(NodeVisitor &visitor)
246 {
247         visitor.visit(*this);
248 }
249
250
251 void Precision::visit(NodeVisitor &visitor)
252 {
253         visitor.visit(*this);
254 }
255
256
257 void Layout::visit(NodeVisitor &visitor)
258 {
259         visitor.visit(*this);
260 }
261
262
263 void InterfaceLayout::visit(NodeVisitor &visitor)
264 {
265         visitor.visit(*this);
266 }
267
268
269 BasicTypeDeclaration::BasicTypeDeclaration():
270         kind(ALIAS),
271         size(0),
272         base_type(0)
273 { }
274
275 BasicTypeDeclaration::BasicTypeDeclaration(const BasicTypeDeclaration &other):
276         TypeDeclaration(other),
277         kind(other.kind),
278         size(other.size),
279         base(other.base),
280         base_type(0)
281 { }
282
283 void BasicTypeDeclaration::visit(NodeVisitor &visitor)
284 {
285         visitor.visit(*this);
286 }
287
288
289 ImageTypeDeclaration::ImageTypeDeclaration():
290         dimensions(TWO),
291         array(false),
292         sampled(true),
293         shadow(false)
294 { }
295
296 void ImageTypeDeclaration::visit(NodeVisitor &visitor)
297 {
298         visitor.visit(*this);
299 }
300
301
302 StructDeclaration::StructDeclaration():
303         interface_block(0)
304 {
305         members.use_braces = true;
306 }
307
308 StructDeclaration::StructDeclaration(const StructDeclaration &other):
309         TypeDeclaration(other),
310         members(other.members),
311         interface_block(0)
312 { }
313
314 StructDeclaration::~StructDeclaration()
315 {
316         if(interface_block && interface_block->struct_declaration==this)
317                 interface_block->struct_declaration = 0;
318 }
319
320 void StructDeclaration::visit(NodeVisitor &visitor)
321 {
322         visitor.visit(*this);
323 }
324
325
326 VariableDeclaration::VariableDeclaration():
327         constant(false),
328         array(false),
329         type_declaration(0),
330         linked_declaration(0)
331 { }
332
333 VariableDeclaration::VariableDeclaration(const VariableDeclaration &other):
334         Statement(other),
335         layout(other.layout),
336         constant(other.constant),
337         sampling(other.sampling),
338         interpolation(other.interpolation),
339         interface(other.interface),
340         precision(other.precision),
341         type(other.type),
342         name(other.name),
343         array(other.array),
344         array_size(other.array_size),
345         init_expression(other.init_expression),
346         type_declaration(0),
347         linked_declaration(0)
348 { }
349
350 VariableDeclaration::~VariableDeclaration()
351 {
352         if(linked_declaration && linked_declaration->linked_declaration==this)
353                 linked_declaration->linked_declaration = 0;
354 }
355
356 void VariableDeclaration::visit(NodeVisitor &visitor)
357 {
358         visitor.visit(*this);
359 }
360
361
362 InterfaceBlock::InterfaceBlock():
363         array(false),
364         type_declaration(0),
365         struct_declaration(0),
366         linked_block(0)
367 { }
368
369 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
370         Statement(other),
371         interface(other.interface),
372         name(other.name),
373         members(other.members),
374         instance_name(other.instance_name),
375         array(other.array),
376         type_declaration(0),
377         struct_declaration(0),
378         linked_block(0)
379 { }
380
381 InterfaceBlock::~InterfaceBlock()
382 {
383         if(linked_block && linked_block->linked_block==this)
384                 linked_block->linked_block = 0;
385         if(struct_declaration && struct_declaration->interface_block==this)
386                 struct_declaration->interface_block = 0;
387 }
388
389 void InterfaceBlock::visit(NodeVisitor &visitor)
390 {
391         visitor.visit(*this);
392 }
393
394
395 FunctionDeclaration::FunctionDeclaration():
396         virtua(false),
397         overrd(false),
398         definition(0),
399         return_type_declaration(0)
400 { }
401
402 FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
403         Statement(other),
404         return_type(other.return_type),
405         name(other.name),
406         parameters(other.parameters),
407         virtua(other.virtua),
408         overrd(other.overrd),
409         body(other.body),
410         signature(other.signature),
411         definition(other.definition==&other ? this : 0),
412         return_type_declaration(0)
413 { }
414
415 void FunctionDeclaration::visit(NodeVisitor &visitor)
416 {
417         visitor.visit(*this);
418 }
419
420
421 void Conditional::visit(NodeVisitor &visitor)
422 {
423         visitor.visit(*this);
424 }
425
426
427 void Iteration::visit(NodeVisitor &visitor)
428 {
429         visitor.visit(*this);
430 }
431
432
433 void Passthrough::visit(NodeVisitor &visitor)
434 {
435         visitor.visit(*this);
436 }
437
438
439 void Return::visit(NodeVisitor &visitor)
440 {
441         visitor.visit(*this);
442 }
443
444
445 void Jump::visit(NodeVisitor &visitor)
446 {
447         visitor.visit(*this);
448 }
449
450
451 Stage::Stage(Stage::Type t):
452         type(t),
453         previous(0)
454 { }
455
456 const char *Stage::get_stage_name(Type type)
457 {
458         static const char *names[] = { "shared", "vertex", "geometry", "fragment" };
459         return names[type];
460 }
461
462
463 Module::Module():
464         shared(Stage::SHARED)
465 { }
466
467
468 string get_unused_variable_name(const Block &block, const string &base, const string &prefix_hint)
469 {
470         string name = base;
471
472         bool prefixed = false;
473         unsigned number = 1;
474         unsigned size_without_number = name.size();
475         while(1)
476         {
477                 bool unused = true;
478                 for(const Block *b=&block; (unused && b); b=b->parent)
479                         unused = !b->variables.count(name);
480                 if(unused)
481                         return name;
482
483                 if(!prefixed && !prefix_hint.empty())
484                 {
485                         if(name.front()!='_')
486                                 name = "_"+name;
487                         name = prefix_hint+name;
488                         if(name.front()!='_')
489                                 name = "_"+name;
490                         prefixed = true;
491                         size_without_number = name.size();
492                 }
493                 else
494                 {
495                         name.erase(size_without_number);
496                         name += format("_%d", number);
497                         ++number;
498                 }
499         }
500 }
501
502 } // namespace SL
503 } // namespace GL
504 } // namespace Msp