diff --git a/main/Scene-load.cc b/main/Scene-load.cc index cbb8103..a97394f 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -248,32 +248,6 @@ vector Scene::processGeneralItems(refptr node) 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; -} - void Scene::processMaterialDefinition(refptr node) { map< string, refptr >::iterator it = diff --git a/parser/nodes.cc b/parser/nodes.cc index f7c55de..e940673 100644 --- a/parser/nodes.cc +++ b/parser/nodes.cc @@ -3,6 +3,7 @@ #include #include +#include #include "nodes.h" @@ -25,48 +26,109 @@ Node::~Node() { } -double BinOpNode::getNumber() +NodeRef BinOpNode::evaluate() { - double o = one->getNumber(); - double t = two->getNumber(); + double o = one->evaluate()->getNumber(); + double t = two->evaluate()->getNumber(); + double r = 0.0; switch (m_op) { case '*': - return o * t; + r = o * t; + break; case '/': - return o / t; + r = o / t; + break; case '+': - return o + t; + r = o + t; + break; case '-': - return o - t; + r = o - t; + break; default: cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl; exit(-3); } + return new NumberNode(r); } -int BoolExpressionNode::getInteger() +NodeRef BoolExpressionNode::evaluate() { double o, t; + double r = 0; if (m_op != '!') { - o = one->getNumber(); - t = two->getNumber(); + o = one->evaluate()->getNumber(); + t = two->evaluate()->getNumber(); } switch (m_op) { case '<': - return o < t; + r = o < t ? 0 : 1; + break; case '>': - return o > t; + r = o > t ? 0 : 1; + break; case '=': - return o == t; + r = o == t ? 0 : 1; + break; case 'n': - return o != t; + r = o != t ? 0 : 1; + break; case '!': - return ! one->getInteger(); + r = ! one->evaluate()->getInteger(); + break; case 'T': - return 1; + r = 1; + break; } - return 0; + return new NumberNode(r); } + +NodeRef ForNode::evaluate() +{ + NodeRef eval = new EvaluatePropagateNode(); + + if (!m_nodes[0].isNull()) + { + m_nodes[0]->evaluate(); + } + + while (m_nodes[1]->evaluate()->getInteger() != 0) + { + for (vector::iterator it = m_children.begin(); + it != m_children.end(); + it++) + { + NodeRef n = (*it)->evaluate(); + if ( ! n.isNull() ) + { + if (typeid(*n) == typeid(EvaluatePropagateNode)) + { + for (vector::iterator it2 = n->getChildren().begin(); + it2 != n->getChildren().end(); + it2++) + { + eval->addChild(*it2); + } + } + else + { + eval->addChild(n); + } + } + } + + if (!m_nodes[2].isNull()) + { + m_nodes[2]->evaluate(); + } + } + + /* clear out all child nodes so that evaluateChildren() doesn't + * attempt to evaluate them */ + m_children.clear(); + + return eval; +} + diff --git a/parser/nodes.h b/parser/nodes.h index c417e0e..fa2716c 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -39,11 +39,6 @@ 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 refptr evaluate() { std::cerr << "Warning: Node::evaluate() called!" << std::endl; @@ -631,7 +626,7 @@ class ExpressionNode : public Node { public: bool isExpression() { return true; } - virtual double getNumber() = 0; + virtual NodeRef evaluate() = 0; }; class AssignmentNode : public ExpressionNode @@ -642,11 +637,11 @@ class AssignmentNode : public ExpressionNode { } std::string getString() { return m_varref->getString(); } - double getNumber() + virtual NodeRef evaluate() { - double n = m_expr->getNumber(); + double n = m_expr->evaluate()->getNumber(); parser_scope->putGlobal(getString(), n); - return n; + return new NumberNode(n); } protected: NodeRef m_varref; @@ -661,11 +656,11 @@ class LocalAssignmentNode : public ExpressionNode { } std::string getString() { return m_varref->getString(); } - double getNumber() + virtual NodeRef evaluate() { - double n = m_expr->getNumber(); + double n = m_expr->evaluate()->getNumber(); parser_scope->putLocal(getString(), n); - return n; + return new NumberNode(n); } protected: NodeRef m_varref; @@ -676,10 +671,10 @@ class LocalDeclNode : public ExpressionNode { public: LocalDeclNode(NodeRef varref) : m_varref(varref) { } - double getNumber() + virtual NodeRef evaluate() { parser_scope->putLocal(m_varref->getString(), 0.0); - return 0.0; + return NULL; } protected: NodeRef m_varref; @@ -692,7 +687,7 @@ class BinOpNode : public ExpressionNode : m_op(op), one(one), two(two) { } - virtual double getNumber(); + virtual NodeRef evaluate(); protected: char m_op; NodeRef one; @@ -706,7 +701,7 @@ class BoolExpressionNode : public Node : m_op(op), one(one), two(two) { } - int getInteger(); + virtual NodeRef evaluate(); protected: char m_op; NodeRef one; @@ -718,11 +713,11 @@ class VarRefNode : public Node public: VarRefNode(const std::string & str) { m_string = str; } std::string getString() { return m_string; } - double getNumber() + virtual NodeRef evaluate() { if (parser_scope->contains(m_string)) { - return parser_scope->get(m_string); + return new NumberNode(parser_scope->get(m_string)); } std::cerr << "Error: No identifier '" << m_string << "' in scope" << std::endl; @@ -741,17 +736,17 @@ class ForNode : public Node m_nodes[1] = e2; m_nodes[2] = e3; } - NodeRef getNode(int idx) - { - if (0 <= idx && idx <= 2) - { - return m_nodes[idx]; - } - return NULL; - } + virtual NodeRef evaluate(); protected: NodeRef m_nodes[3]; }; +/* this class is only used to hold a set of items coming out of a class's + * evaluate() from above. the evaluateChildren() top-level method will + * propagate children of this class up to the level of their parent */ +class EvaluatePropagateNode : public Node +{ +}; + #endif