diff --git a/main/Scene-load.cc b/main/Scene-load.cc index 1117884..b712e1b 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -255,7 +255,7 @@ vector Scene::processTransformBlock(refptr node) vector Scene::processGeneralItems(refptr node) { - vector shapes; + vector shapes, incoming; for (Node_Iterator it = node->getChildren().begin(); it != node->getChildren().end(); @@ -263,15 +263,11 @@ vector Scene::processGeneralItems(refptr node) { if ((*it)->isTransformBlock()) { - vector in = processTransformBlock(*it); - for (int i = 0, sz = in.size(); i < sz; i++) - { - shapes.push_back(in[i]); - } + incoming = processTransformBlock(*it); } - else if ( typeid(*node) == typeid(MaterialDefinitionNode) ) + else if ( typeid(**it) == typeid(MaterialDefinitionNode) ) { - processMaterialDefinition(node); + processMaterialDefinition(*it); } else if ( typeid(**it) == typeid(ShapeDefinitionNode) ) { @@ -281,6 +277,41 @@ vector Scene::processGeneralItems(refptr node) { shapes.push_back(processShape(*it)); } + else if ( typeid(**it) == typeid(ForNode) ) + { + incoming = processForNode(*it); + } + while (incoming.size() > 0) + { + shapes.push_back(incoming[0]); + incoming.erase(incoming.begin()); + } + } + + return shapes; +} + +vector Scene::processForNode(refptr node) +{ + if (!node->getNode(0).isNull()) + { + node->getNode(0)->getNumber(); + } + + vector shapes, incoming; + + while (node->getNode(1)->getInteger() != 0) + { + incoming = processGeneralItems(node); + while (incoming.size() > 0) + { + shapes.push_back(incoming[0]); + incoming.erase(incoming.begin()); + } + if (!node->getNode(2).isNull()) + { + node->getNode(2)->getNumber(); + } } return shapes; diff --git a/main/Scene.h b/main/Scene.h index d5214d5..21be396 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -78,6 +78,7 @@ class Scene void processOptions(refptr node); std::vector processTransformBlock(refptr node); std::vector processGeneralItems(refptr node); + std::vector processForNode(refptr node); void processMaterialDefinition(refptr node); void processShapeDefinition(refptr node); diff --git a/parser/nodes.h b/parser/nodes.h index 87e072f..62fe405 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -42,6 +42,11 @@ class Node std::cerr << "Warning: Node::getString() called!" << std::endl; return ""; } + virtual refptr getNode(int idx) + { + std::cerr << "Warning: Node::getNode() called!" << std::endl; + return NULL; + } virtual bool isShape() { return false; } virtual bool isMaterial() { return false; } @@ -550,11 +555,21 @@ class ForNode : public Node { public: ForNode(refptr e1, refptr e2, refptr e3) - : m_e1(e1), m_e2(e2), m_e3(e3) { + m_nodes[0] = e1; + m_nodes[1] = e2; + m_nodes[2] = e3; + } + refptr getNode(int idx) + { + if (0 <= idx && idx <= 2) + { + return m_nodes[idx]; + } + return NULL; } protected: - refptr m_e1, m_e2, m_e3; + refptr m_nodes[3]; }; #endif diff --git a/parser/parser.yy b/parser/parser.yy index 0f3a794..c8ccf46 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -593,6 +593,10 @@ expression: term { $$ = $1; } | stmt_expression { $$ = $1; } ; +maybe_expression: /* empty */ + | expression { $$ = $1; } + ; + stmt_expression: assignment { $$ = $1; } | local_assignment { $$ = $1; } | local_decl { $$ = $1; } @@ -640,7 +644,7 @@ local_decl: LOCAL VARREF { } ; -for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN LCURLY general_items RCURLY { +for: FOR LPAREN maybe_expression SEMICOLON bool_expression SEMICOLON maybe_expression RPAREN LCURLY general_items RCURLY { $$ = new ForNode($3, $5, $7); $$->addChildren($10); }