1 #include <msp/core/algorithm.h>
2 #include <msp/core/maputils.h>
12 const Operator Operator::operators[] =
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 }
60 const Operator &Operator::get_operator(const string &token, Type type)
62 for(const Operator *i=operators; i->type; ++i)
63 if(i->type==type && i->token==token)
65 throw key_error(token);
70 NodeContainer<C>::NodeContainer(const NodeContainer &c):
83 Block::Block(const Block &other):
86 use_braces(other.use_braces),
90 void Block::visit(NodeVisitor &visitor)
96 Expression::Expression():
103 void Literal::visit(NodeVisitor &visitor)
105 visitor.visit(*this);
109 VariableReference::VariableReference():
113 VariableReference::VariableReference(const VariableReference &other):
119 void VariableReference::visit(NodeVisitor &visitor)
121 visitor.visit(*this);
125 InterfaceBlockReference::InterfaceBlockReference():
129 InterfaceBlockReference::InterfaceBlockReference(const InterfaceBlockReference &other):
135 void InterfaceBlockReference::visit(NodeVisitor &visitor)
137 visitor.visit(*this);
141 MemberAccess::MemberAccess():
146 MemberAccess::MemberAccess(const MemberAccess &other):
149 member(other.member),
154 void MemberAccess::visit(NodeVisitor &visitor)
156 visitor.visit(*this);
163 fill(components, components+4, 0);
166 void Swizzle::visit(NodeVisitor &visitor)
168 visitor.visit(*this);
172 void UnaryExpression::visit(NodeVisitor &visitor)
174 visitor.visit(*this);
178 void BinaryExpression::visit(NodeVisitor &visitor)
180 visitor.visit(*this);
184 Assignment::Assignment():
185 self_referencing(false)
188 Assignment::Assignment(const Assignment &other):
189 BinaryExpression(other),
190 self_referencing(other.self_referencing)
193 void Assignment::visit(NodeVisitor &visitor)
195 visitor.visit(*this);
199 Assignment::Target::Target(Statement *d):
203 fill(chain, chain+7, 0);
206 bool Assignment::Target::operator<(const Target &other) const
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;
217 void TernaryExpression::visit(NodeVisitor &visitor)
219 visitor.visit(*this);
223 FunctionCall::FunctionCall():
228 FunctionCall::FunctionCall(const FunctionCall &other):
231 constructor(other.constructor),
232 arguments(other.arguments),
236 void FunctionCall::visit(NodeVisitor &visitor)
238 visitor.visit(*this);
242 void ExpressionStatement::visit(NodeVisitor &visitor)
244 visitor.visit(*this);
248 void Import::visit(NodeVisitor &visitor)
250 visitor.visit(*this);
254 void Precision::visit(NodeVisitor &visitor)
256 visitor.visit(*this);
260 void Layout::visit(NodeVisitor &visitor)
262 visitor.visit(*this);
266 void InterfaceLayout::visit(NodeVisitor &visitor)
268 visitor.visit(*this);
272 BasicTypeDeclaration::BasicTypeDeclaration():
279 BasicTypeDeclaration::BasicTypeDeclaration(const BasicTypeDeclaration &other):
280 TypeDeclaration(other),
288 void BasicTypeDeclaration::visit(NodeVisitor &visitor)
290 visitor.visit(*this);
294 ImageTypeDeclaration::ImageTypeDeclaration():
301 void ImageTypeDeclaration::visit(NodeVisitor &visitor)
303 visitor.visit(*this);
307 StructDeclaration::StructDeclaration():
310 members.use_braces = true;
313 StructDeclaration::StructDeclaration(const StructDeclaration &other):
314 TypeDeclaration(other),
315 members(other.members),
319 StructDeclaration::~StructDeclaration()
321 if(interface_block && interface_block->struct_declaration==this)
322 interface_block->struct_declaration = 0;
325 void StructDeclaration::visit(NodeVisitor &visitor)
327 visitor.visit(*this);
331 VariableDeclaration::VariableDeclaration():
335 linked_declaration(0)
338 VariableDeclaration::VariableDeclaration(const VariableDeclaration &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),
349 array_size(other.array_size),
350 init_expression(other.init_expression),
352 linked_declaration(0)
355 VariableDeclaration::~VariableDeclaration()
357 if(linked_declaration && linked_declaration->linked_declaration==this)
358 linked_declaration->linked_declaration = 0;
361 void VariableDeclaration::visit(NodeVisitor &visitor)
363 visitor.visit(*this);
367 InterfaceBlock::InterfaceBlock():
370 struct_declaration(0),
374 InterfaceBlock::InterfaceBlock(const InterfaceBlock &other):
376 interface(other.interface),
377 block_name(other.block_name),
378 members(other.members),
379 instance_name(other.instance_name),
382 struct_declaration(0),
386 InterfaceBlock::~InterfaceBlock()
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;
394 void InterfaceBlock::visit(NodeVisitor &visitor)
396 visitor.visit(*this);
400 FunctionDeclaration::FunctionDeclaration():
404 return_type_declaration(0)
407 FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
409 return_type(other.return_type),
411 parameters(other.parameters),
412 virtua(other.virtua),
413 overrd(other.overrd),
415 signature(other.signature),
416 definition(other.definition==&other ? this : 0),
417 return_type_declaration(0)
420 void FunctionDeclaration::visit(NodeVisitor &visitor)
422 visitor.visit(*this);
426 void Conditional::visit(NodeVisitor &visitor)
428 visitor.visit(*this);
432 void Iteration::visit(NodeVisitor &visitor)
434 visitor.visit(*this);
438 void Passthrough::visit(NodeVisitor &visitor)
440 visitor.visit(*this);
444 void Return::visit(NodeVisitor &visitor)
446 visitor.visit(*this);
450 void Jump::visit(NodeVisitor &visitor)
452 visitor.visit(*this);
456 Stage::Stage(Stage::Type t):
461 const char *Stage::get_stage_name(Type type)
463 static const char *const names[] = { "shared", "vertex", "geometry", "fragment" };
469 shared(Stage::SHARED)
473 string get_unused_variable_name(const Block &block, const string &base)
478 unsigned base_size = name.size();
482 for(const Block *b=█ (unused && b); b=b->parent)
483 unused = !b->variables.count(name);
487 name.erase(base_size);
488 name += format("_%d", number);
493 int get_layout_value(const Layout &layout, const string &name, int def_value)
495 auto i = find_member(layout.qualifiers, name, &Layout::Qualifier::name);
496 return (i!=layout.qualifiers.end() ? i->value : def_value);
499 void add_to_chain(Assignment::Target &target, Assignment::Target::ChainType type, unsigned index)
501 if(target.chain_len<7)
502 target.chain[target.chain_len] = type | min<unsigned>(index, 0x3F);