1 #include <msp/core/maputils.h>
11 const Operator Operator::operators[] =
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 }
59 const Operator &Operator::get_operator(const string &token, Type type)
61 for(const Operator *i=operators; i->type; ++i)
62 if(i->type==type && i->token==token)
64 throw key_error(token);
69 NodeContainer<C>::NodeContainer(const NodeContainer &c):
72 for(typename C::iterator i=this->begin(); i!=this->end(); ++i)
82 Block::Block(const Block &other):
85 use_braces(other.use_braces),
89 void Block::visit(NodeVisitor &visitor)
95 Expression::Expression():
102 void Literal::visit(NodeVisitor &visitor)
104 visitor.visit(*this);
108 VariableReference::VariableReference():
112 VariableReference::VariableReference(const VariableReference &other):
118 void VariableReference::visit(NodeVisitor &visitor)
120 visitor.visit(*this);
124 InterfaceBlockReference::InterfaceBlockReference():
128 InterfaceBlockReference::InterfaceBlockReference(const InterfaceBlockReference &other):
134 void InterfaceBlockReference::visit(NodeVisitor &visitor)
136 visitor.visit(*this);
140 MemberAccess::MemberAccess():
145 MemberAccess::MemberAccess(const MemberAccess &other):
148 member(other.member),
153 void MemberAccess::visit(NodeVisitor &visitor)
155 visitor.visit(*this);
162 fill(components, components+4, 0);
165 void Swizzle::visit(NodeVisitor &visitor)
167 visitor.visit(*this);
171 void UnaryExpression::visit(NodeVisitor &visitor)
173 visitor.visit(*this);
177 void BinaryExpression::visit(NodeVisitor &visitor)
179 visitor.visit(*this);
183 Assignment::Assignment():
184 self_referencing(false)
187 Assignment::Assignment(const Assignment &other):
188 BinaryExpression(other),
189 self_referencing(other.self_referencing)
192 void Assignment::visit(NodeVisitor &visitor)
194 visitor.visit(*this);
198 Assignment::Target::Target(Statement *d):
202 fill(chain, chain+7, 0);
205 bool Assignment::Target::operator<(const Target &other) const
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;
216 void TernaryExpression::visit(NodeVisitor &visitor)
218 visitor.visit(*this);
222 FunctionCall::FunctionCall():
227 FunctionCall::FunctionCall(const FunctionCall &other):
230 constructor(other.constructor),
231 arguments(other.arguments),
235 void FunctionCall::visit(NodeVisitor &visitor)
237 visitor.visit(*this);
241 void ExpressionStatement::visit(NodeVisitor &visitor)
243 visitor.visit(*this);
247 void Import::visit(NodeVisitor &visitor)
249 visitor.visit(*this);
253 void Precision::visit(NodeVisitor &visitor)
255 visitor.visit(*this);
259 void Layout::visit(NodeVisitor &visitor)
261 visitor.visit(*this);
265 void InterfaceLayout::visit(NodeVisitor &visitor)
267 visitor.visit(*this);
271 BasicTypeDeclaration::BasicTypeDeclaration():
278 BasicTypeDeclaration::BasicTypeDeclaration(const BasicTypeDeclaration &other):
279 TypeDeclaration(other),
287 void BasicTypeDeclaration::visit(NodeVisitor &visitor)
289 visitor.visit(*this);
293 ImageTypeDeclaration::ImageTypeDeclaration():
300 void ImageTypeDeclaration::visit(NodeVisitor &visitor)
302 visitor.visit(*this);
306 StructDeclaration::StructDeclaration():
309 members.use_braces = true;
312 StructDeclaration::StructDeclaration(const StructDeclaration &other):
313 TypeDeclaration(other),
314 members(other.members),
318 StructDeclaration::~StructDeclaration()
320 if(interface_block && interface_block->struct_declaration==this)
321 interface_block->struct_declaration = 0;
324 void StructDeclaration::visit(NodeVisitor &visitor)
326 visitor.visit(*this);
330 VariableDeclaration::VariableDeclaration():
334 linked_declaration(0)
337 VariableDeclaration::VariableDeclaration(const VariableDeclaration &other):
339 layout(other.layout),
340 constant(other.constant),
341 sampling(other.sampling),
342 interpolation(other.interpolation),
343 interface(other.interface),
344 precision(other.precision),
348 array_size(other.array_size),
349 init_expression(other.init_expression),
351 linked_declaration(0)
354 VariableDeclaration::~VariableDeclaration()
356 if(linked_declaration && linked_declaration->linked_declaration==this)
357 linked_declaration->linked_declaration = 0;
360 void VariableDeclaration::visit(NodeVisitor &visitor)
362 visitor.visit(*this);
366 InterfaceBlock::InterfaceBlock():
369 struct_declaration(0),
373 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
375 interface(other.interface),
376 block_name(other.block_name),
377 members(other.members),
378 instance_name(other.instance_name),
381 struct_declaration(0),
385 InterfaceBlock::~InterfaceBlock()
387 if(linked_block && linked_block->linked_block==this)
388 linked_block->linked_block = 0;
389 if(struct_declaration && struct_declaration->interface_block==this)
390 struct_declaration->interface_block = 0;
393 void InterfaceBlock::visit(NodeVisitor &visitor)
395 visitor.visit(*this);
399 FunctionDeclaration::FunctionDeclaration():
403 return_type_declaration(0)
406 FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
408 return_type(other.return_type),
410 parameters(other.parameters),
411 virtua(other.virtua),
412 overrd(other.overrd),
414 signature(other.signature),
415 definition(other.definition==&other ? this : 0),
416 return_type_declaration(0)
419 void FunctionDeclaration::visit(NodeVisitor &visitor)
421 visitor.visit(*this);
425 void Conditional::visit(NodeVisitor &visitor)
427 visitor.visit(*this);
431 void Iteration::visit(NodeVisitor &visitor)
433 visitor.visit(*this);
437 void Passthrough::visit(NodeVisitor &visitor)
439 visitor.visit(*this);
443 void Return::visit(NodeVisitor &visitor)
445 visitor.visit(*this);
449 void Jump::visit(NodeVisitor &visitor)
451 visitor.visit(*this);
455 Stage::Stage(Stage::Type t):
460 const char *Stage::get_stage_name(Type type)
462 static const char *names[] = { "shared", "vertex", "geometry", "fragment" };
468 shared(Stage::SHARED)
472 string get_unused_variable_name(const Block &block, const string &base)
477 unsigned base_size = name.size();
481 for(const Block *b=█ (unused && b); b=b->parent)
482 unused = !b->variables.count(name);
486 name.erase(base_size);
487 name += format("_%d", number);
492 int get_layout_value(const Layout &layout, const string &name, int def_value)
494 for(vector<Layout::Qualifier>::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i)
500 void add_to_chain(Assignment::Target &target, Assignment::Target::ChainType type, unsigned index)
502 if(target.chain_len<7)
503 target.chain[target.chain_len] = type | min<unsigned>(index, 0x3F);