summaryrefslogtreecommitdiff
path: root/cpp/src/Transform/Node.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2003-10-21 22:25:48 +0000
committerMark Spruiell <mes@zeroc.com>2003-10-21 22:25:48 +0000
commit623184c101c904eb0d456d325d3ced4d4475d3ae (patch)
tree56a4d02eeb1f966ad1f17405a9c6b2fe84e804e0 /cpp/src/Transform/Node.cpp
parentFreeze Index Windows port (diff)
downloadice-623184c101c904eb0d456d325d3ced4d4475d3ae.tar.bz2
ice-623184c101c904eb0d456d325d3ced4d4475d3ae.tar.xz
ice-623184c101c904eb0d456d325d3ced4d4475d3ae.zip
initial check-in
Diffstat (limited to 'cpp/src/Transform/Node.cpp')
-rw-r--r--cpp/src/Transform/Node.cpp464
1 files changed, 464 insertions, 0 deletions
diff --git a/cpp/src/Transform/Node.cpp b/cpp/src/Transform/Node.cpp
new file mode 100644
index 00000000000..0c4948f72dd
--- /dev/null
+++ b/cpp/src/Transform/Node.cpp
@@ -0,0 +1,464 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#include <Transform/Node.h>
+
+using namespace std;
+
+ostream&
+operator<<(ostream& os, const Transform::Identifier& id)
+{
+ for(Transform::Identifier::const_iterator p = id.begin(); p != id.end(); ++p)
+ {
+ if(p != id.begin())
+ {
+ os << '.';
+ }
+ os << *p;
+ }
+ return os;
+}
+
+//
+// EvaluateException
+//
+Transform::EvaluateException::EvaluateException(const char* file, int line, const string& reason) :
+ IceUtil::Exception(file, line), _reason(reason)
+{
+}
+
+string
+Transform::EvaluateException::ice_name() const
+{
+ return "Transform::EvaluateException";
+}
+
+void
+Transform::EvaluateException::ice_print(ostream& out) const
+{
+ IceUtil::Exception::ice_print(out);
+ out << ":\nerror occurred while evaluating expression";
+ if(!_reason.empty())
+ {
+ out << ":\n" << _reason;
+ }
+}
+
+IceUtil::Exception*
+Transform::EvaluateException::ice_clone() const
+{
+ return new EvaluateException(ice_file(), ice_line(), _reason);
+}
+
+void
+Transform::EvaluateException::ice_throw() const
+{
+ throw *this;
+}
+
+string
+Transform::EvaluateException::reason() const
+{
+ return _reason;
+}
+
+//
+// SymbolTable
+//
+Transform::SymbolTable::~SymbolTable()
+{
+}
+
+//
+// Node
+//
+Transform::Node::~Node()
+{
+}
+
+//
+// BinaryNode
+//
+Transform::BinaryNode::BinaryNode(BinaryOperator op, const DataFactoryPtr& factory, const NodePtr& left,
+ const NodePtr& right) :
+ _op(op), _factory(factory), _left(left), _right(right)
+{
+}
+
+Transform::DataPtr
+Transform::BinaryNode::evaluate(SymbolTable& st)
+{
+ DataPtr result;
+
+ switch(_op)
+ {
+ case BinOpOr:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ if(leftValue->booleanValue())
+ {
+ result = leftValue;
+ }
+ else
+ {
+ result = _right->evaluate(st);
+ }
+ break;
+ }
+
+ case BinOpAnd:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ if(!leftValue->booleanValue())
+ {
+ result = leftValue;
+ }
+ else
+ {
+ result = _right->evaluate(st);
+ }
+ break;
+ }
+
+ case BinOpMul:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ IntegerDataPtr ileft = IntegerDataPtr::dynamicCast(leftValue);
+ IntegerDataPtr iright = IntegerDataPtr::dynamicCast(rightValue);
+ if(ileft && iright)
+ {
+ result = _factory->createInteger(leftValue->integerValue() * rightValue->integerValue(), true);
+ }
+ else
+ {
+ result = _factory->createDouble(leftValue->doubleValue(true) * rightValue->doubleValue(true), true);
+ }
+ break;
+ }
+
+ case BinOpDiv:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ IntegerDataPtr ileft = IntegerDataPtr::dynamicCast(leftValue);
+ IntegerDataPtr iright = IntegerDataPtr::dynamicCast(rightValue);
+ if(ileft && iright)
+ {
+ result = _factory->createInteger(leftValue->integerValue() / rightValue->integerValue(), true);
+ }
+ else
+ {
+ result = _factory->createDouble(leftValue->doubleValue(true) / rightValue->doubleValue(true), true);
+ }
+ break;
+ }
+
+ case BinOpMod:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ result = _factory->createInteger(leftValue->integerValue() % rightValue->integerValue(), true);
+ break;
+ }
+
+ case BinOpAdd:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ IntegerDataPtr ileft = IntegerDataPtr::dynamicCast(leftValue);
+ IntegerDataPtr iright = IntegerDataPtr::dynamicCast(rightValue);
+ if(ileft && iright)
+ {
+ result = _factory->createInteger(leftValue->integerValue() + rightValue->integerValue(), true);
+ }
+ else
+ {
+ result = _factory->createDouble(leftValue->doubleValue(true) + rightValue->doubleValue(true), true);
+ }
+ break;
+ }
+
+ case BinOpSub:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ IntegerDataPtr ileft = IntegerDataPtr::dynamicCast(leftValue);
+ IntegerDataPtr iright = IntegerDataPtr::dynamicCast(rightValue);
+ if(ileft && iright)
+ {
+ result = _factory->createInteger(leftValue->integerValue() - rightValue->integerValue(), true);
+ }
+ else
+ {
+ result = _factory->createDouble(leftValue->doubleValue(true) - rightValue->doubleValue(true), true);
+ }
+ break;
+ }
+
+ case BinOpLess:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ bool b = leftValue < rightValue;
+ result = _factory->createBoolean(b, true);
+ break;
+ }
+
+ case BinOpGreater:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ bool b = (leftValue < rightValue) || (leftValue == rightValue);
+ result = _factory->createBoolean(!b, true);
+ break;
+ }
+
+ case BinOpLessEq:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ bool b = (leftValue < rightValue) || (leftValue == rightValue);
+ result = _factory->createBoolean(b, true);
+ break;
+ }
+
+ case BinOpGrEq:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ bool b = leftValue < rightValue;
+ result = _factory->createBoolean(!b, true);
+ break;
+ }
+
+ case BinOpEq:
+ {
+ DataPtr leftValue = _left->evaluate(st);
+ DataPtr rightValue = _right->evaluate(st);
+ bool b = leftValue == rightValue;
+ result = _factory->createBoolean(b, true);
+ break;
+ }
+ }
+
+ if(!result)
+ {
+ throw EvaluateException(__FILE__, __LINE__, "invalid operands to operator " + opToString(_op));
+ }
+
+ return result;
+}
+
+void
+Transform::BinaryNode::print(ostream& os) const
+{
+ os << opToString(_op) << ": left=";
+ _left->print(os);
+ os << ", right=";
+ _right->print(os);
+}
+
+string
+Transform::BinaryNode::opToString(BinaryOperator op)
+{
+ switch(op)
+ {
+ case BinOpOr:
+ return "OR";
+
+ case BinOpAnd:
+ return "AND";
+
+ case BinOpMul:
+ return "*";
+
+ case BinOpDiv:
+ return "/";
+
+ case BinOpMod:
+ return "%";
+
+ case BinOpAdd:
+ return "+";
+
+ case BinOpSub:
+ return "-";
+
+ case BinOpLess:
+ return "<";
+
+ case BinOpGreater:
+ return ">";
+
+ case BinOpLessEq:
+ return "<=";
+
+ case BinOpGrEq:
+ return ">=";
+
+ case BinOpEq:
+ return "==";
+ }
+
+ assert(false);
+ return string();
+}
+
+//
+// UnaryNode
+//
+Transform::UnaryNode::UnaryNode(UnaryOperator op, const DataFactoryPtr& factory, const NodePtr& right) :
+ _op(op), _factory(factory), _right(right)
+{
+}
+
+Transform::DataPtr
+Transform::UnaryNode::evaluate(SymbolTable& st)
+{
+ DataPtr result;
+
+ switch(_op)
+ {
+ case UnaryOpNeg:
+ {
+ DataPtr rightValue = _right->evaluate(st);
+ IntegerDataPtr iright = IntegerDataPtr::dynamicCast(rightValue);
+ if(iright)
+ {
+ result = _factory->createInteger(-rightValue->integerValue(), true);
+ }
+ else
+ {
+ result = _factory->createDouble(-rightValue->doubleValue(), true);
+ }
+ break;
+ }
+
+ case UnaryOpNot:
+ {
+ DataPtr rightValue = _right->evaluate(st);
+ result = _factory->createBoolean(!rightValue->booleanValue(), true);
+ break;
+ }
+ }
+
+ if(!result)
+ {
+ throw EvaluateException(__FILE__, __LINE__, "invalid operand to operator " + opToString(_op));
+ }
+
+ return result;
+}
+
+void
+Transform::UnaryNode::print(ostream& os) const
+{
+ os << opToString(_op) << ": right=";
+ _right->print(os);
+}
+
+string
+Transform::UnaryNode::opToString(UnaryOperator op)
+{
+ switch(op)
+ {
+ case UnaryOpNeg:
+ return "-";
+
+ case UnaryOpNot:
+ return "!";
+ }
+
+ assert(false);
+ return string();
+}
+
+//
+// DataNode
+//
+Transform::DataNode::DataNode(const DataPtr& data) :
+ _data(data)
+{
+}
+
+Transform::DataPtr
+Transform::DataNode::evaluate(SymbolTable&)
+{
+ return _data;
+}
+
+void
+Transform::DataNode::print(ostream& os) const
+{
+ _data->print(os);
+}
+
+//
+// IdentNode
+//
+Transform::IdentNode::IdentNode(const Identifier& value) :
+ _value(value)
+{
+}
+
+Transform::DataPtr
+Transform::IdentNode::evaluate(SymbolTable& st)
+{
+ DataPtr result = st.getValue(_value);
+ if(!result)
+ {
+ ostringstream ostr;
+ print(ostr);
+ throw EvaluateException(__FILE__, __LINE__, "unknown identifier `" + ostr.str() + "'");
+ }
+ return result;
+}
+
+void
+Transform::IdentNode::print(ostream& os) const
+{
+ os << _value;
+}
+
+Transform::Identifier
+Transform::IdentNode::getValue() const
+{
+ return _value;
+}
+
+//
+// ConstantNode
+//
+Transform::ConstantNode::ConstantNode(const string& value) :
+ _value(value)
+{
+}
+
+Transform::DataPtr
+Transform::ConstantNode::evaluate(SymbolTable& st)
+{
+ DataPtr result = st.getConstantValue(_value);
+ if(!result)
+ {
+ throw EvaluateException(__FILE__, __LINE__, "unknown constant `" + _value + "'");
+ }
+ return result;
+}
+
+void
+Transform::ConstantNode::print(ostream& os) const
+{
+ os << _value;
+}