]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/syntax.cpp
Copy the location when moving output declarations out of functions
[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, BINARY, 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, BINARY, RIGHT_TO_LEFT },
44         { ":", 15, 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         { "|=", 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(typename C::iterator i=this->begin(); i!=this->end(); ++i)
74                 *i = (*i)->clone();
75 }
76
77
78 Statement::Statement():
79         source(GENERATED_SOURCE),
80         line(1)
81 { }
82
83
84 Block::Block():
85         use_braces(false),
86         parent(0)
87 { }
88
89 Block::Block(const Block &other):
90         Node(other),
91         body(other.body),
92         use_braces(other.use_braces),
93         parent(0)
94 { }
95
96 void Block::visit(NodeVisitor &visitor)
97 {
98         visitor.visit(*this);
99 }
100
101
102 Expression::Expression():
103         oper(0)
104 { }
105
106
107 void Literal::visit(NodeVisitor &visitor)
108 {
109         visitor.visit(*this);
110 }
111
112
113 void ParenthesizedExpression::visit(NodeVisitor &visitor)
114 {
115         visitor.visit(*this);
116 }
117
118
119 VariableReference::VariableReference():
120         declaration(0)
121 { }
122
123 VariableReference::VariableReference(const VariableReference &other):
124         Expression(other),
125         name(other.name),
126         declaration(0)
127 { }
128
129 void VariableReference::visit(NodeVisitor &visitor)
130 {
131         visitor.visit(*this);
132 }
133
134
135 InterfaceBlockReference::InterfaceBlockReference():
136         declaration(0)
137 { }
138
139 InterfaceBlockReference::InterfaceBlockReference(const InterfaceBlockReference &other):
140         Expression(other),
141         name(other.name),
142         declaration(0)
143 { }
144
145 void InterfaceBlockReference::visit(NodeVisitor &visitor)
146 {
147         visitor.visit(*this);
148 }
149
150
151 MemberAccess::MemberAccess():
152         declaration(0)
153 { }
154
155 MemberAccess::MemberAccess(const MemberAccess &other):
156         Expression(other),
157         left(other.left),
158         member(other.member),
159         declaration(0)
160 { }
161
162 void MemberAccess::visit(NodeVisitor &visitor)
163 {
164         visitor.visit(*this);
165 }
166
167
168 void UnaryExpression::visit(NodeVisitor &visitor)
169 {
170         visitor.visit(*this);
171 }
172
173
174 void BinaryExpression::visit(NodeVisitor &visitor)
175 {
176         visitor.visit(*this);
177 }
178
179
180 Assignment::Assignment():
181         self_referencing(false),
182         target_declaration(0)
183 { }
184
185 Assignment::Assignment(const Assignment &other):
186         BinaryExpression(other),
187         self_referencing(other.self_referencing),
188         target_declaration(0)
189 { }
190
191 void Assignment::visit(NodeVisitor &visitor)
192 {
193         visitor.visit(*this);
194 }
195
196
197 FunctionCall::FunctionCall():
198         constructor(false),
199         declaration(0)
200 { }
201
202 FunctionCall::FunctionCall(const FunctionCall &other):
203         Expression(other),
204         name(other.name),
205         constructor(other.constructor),
206         arguments(other.arguments),
207         declaration(0)
208 { }
209
210 void FunctionCall::visit(NodeVisitor &visitor)
211 {
212         visitor.visit(*this);
213 }
214
215
216 void ExpressionStatement::visit(NodeVisitor &visitor)
217 {
218         visitor.visit(*this);
219 }
220
221
222 void Import::visit(NodeVisitor &visitor)
223 {
224         visitor.visit(*this);
225 }
226
227
228 void Precision::visit(NodeVisitor &visitor)
229 {
230         visitor.visit(*this);
231 }
232
233
234 void Layout::visit(NodeVisitor &visitor)
235 {
236         visitor.visit(*this);
237 }
238
239
240 void InterfaceLayout::visit(NodeVisitor &visitor)
241 {
242         visitor.visit(*this);
243 }
244
245
246 StructDeclaration::StructDeclaration()
247 {
248         members.use_braces = true;
249 }
250
251 void StructDeclaration::visit(NodeVisitor &visitor)
252 {
253         visitor.visit(*this);
254 }
255
256
257 VariableDeclaration::VariableDeclaration():
258         constant(false),
259         array(false),
260         type_declaration(0),
261         linked_declaration(0)
262 { }
263
264 VariableDeclaration::VariableDeclaration(const VariableDeclaration &other):
265         Statement(other),
266         layout(other.layout),
267         constant(other.constant),
268         sampling(other.sampling),
269         interpolation(other.interpolation),
270         interface(other.interface),
271         precision(other.precision),
272         type(other.type),
273         name(other.name),
274         array(other.array),
275         array_size(other.array_size),
276         init_expression(other.init_expression),
277         type_declaration(0),
278         linked_declaration(0)
279 { }
280
281 VariableDeclaration::~VariableDeclaration()
282 {
283         if(linked_declaration && linked_declaration->linked_declaration==this)
284                 linked_declaration->linked_declaration = 0;
285 }
286
287 void VariableDeclaration::visit(NodeVisitor &visitor)
288 {
289         visitor.visit(*this);
290 }
291
292
293 InterfaceBlock::InterfaceBlock():
294         array(false),
295         linked_block(0)
296 {
297         members.use_braces = true;
298 }
299
300 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
301         Statement(other),
302         interface(other.interface),
303         name(other.name),
304         members(other.members),
305         instance_name(other.instance_name),
306         array(other.array),
307         linked_block(0)
308 { }
309
310 InterfaceBlock::~InterfaceBlock()
311 {
312         if(linked_block && linked_block->linked_block==this)
313                 linked_block->linked_block = 0;
314 }
315
316 void InterfaceBlock::visit(NodeVisitor &visitor)
317 {
318         visitor.visit(*this);
319 }
320
321
322 FunctionDeclaration::FunctionDeclaration():
323         definition(0)
324 { }
325
326 FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
327         Statement(other),
328         return_type(other.return_type),
329         name(other.name),
330         parameters(other.parameters),
331         body(other.body),
332         definition(other.definition==&other ? this : 0)
333 { }
334
335 void FunctionDeclaration::visit(NodeVisitor &visitor)
336 {
337         visitor.visit(*this);
338 }
339
340
341 void Conditional::visit(NodeVisitor &visitor)
342 {
343         visitor.visit(*this);
344 }
345
346
347 void Iteration::visit(NodeVisitor &visitor)
348 {
349         visitor.visit(*this);
350 }
351
352
353 void Passthrough::visit(NodeVisitor &visitor)
354 {
355         visitor.visit(*this);
356 }
357
358
359 void Return::visit(NodeVisitor &visitor)
360 {
361         visitor.visit(*this);
362 }
363
364
365 void Jump::visit(NodeVisitor &visitor)
366 {
367         visitor.visit(*this);
368 }
369
370
371 Stage::Stage(Stage::Type t):
372         type(t),
373         previous(0)
374 { }
375
376 const char *Stage::get_stage_name(Type type)
377 {
378         static const char *names[] = { "shared", "vertex", "geometry", "fragment" };
379         return names[type];
380 }
381
382
383 Module::Module():
384         shared(Stage::SHARED)
385 { }
386
387 } // namespace SL
388 } // namespace GL
389 } // namespace Msp