00001 #include <iomanip>
00002 #include <ostream>
00003 #include <sstream>
00004
00005 #include "node.hpp"
00006 #include "node_impl.hpp"
00007 #include "variables.hpp"
00008
00009 node_impl::node_impl()
00010 : refcount_(1)
00011 {}
00012
00013 node_impl::~node_impl()
00014 {}
00015
00016 void node_impl::print(std::ostream& stream, int indent)
00017 const
00018 {
00019 print_node(stream, indent);
00020 }
00021
00022 double node_impl::evaluate()
00023 const
00024 {
00025 return evaluate_node();
00026 }
00027
00028 std::string node_impl::to_string()
00029 const
00030 {
00031 return evaluate_string();
00032 }
00033
00034 void node_impl::add_ref()
00035 {
00036 ++refcount_;
00037 }
00038
00039 void node_impl::del_ref()
00040 {
00041 --refcount_;
00042 if (refcount_ == 0)
00043 delete this;
00044 }
00045
00046 std::string node_impl::evaluate_string()
00047 const
00048 {
00049 std::ostringstream stream;
00050 stream << evaluate();
00051 return stream.str();
00052 }
00053
00054
00055 node_void::node_void()
00056 : node_impl()
00057 {}
00058
00059 void node_void::print_node(std::ostream& stream, int indent)
00060 const
00061 {
00062 stream << std::setw(indent) << "" << "void\n";
00063 }
00064
00065 double node_void::evaluate_node()
00066 const
00067 {
00068 return 0.0;
00069 }
00070
00071 std::string node_void::evaluate_string()
00072 const
00073 {
00074 return std::string();
00075 }
00076
00077
00078 node_number::node_number(double value)
00079 : node_impl(), value_(value)
00080 {}
00081
00082 double node_number::value()
00083 const
00084 {
00085 return value_;
00086 }
00087
00088 void node_number::print_node(std::ostream& stream, int indent)
00089 const
00090 {
00091 stream << std::setw(indent) << "" << value() << '\n';
00092 }
00093
00094 double node_number::evaluate_node()
00095 const
00096 {
00097 return value();
00098 }
00099
00100
00101 node_identifier::node_identifier(std::string const& identifier)
00102 : node_impl(), identifier_(identifier)
00103 {}
00104
00105 std::string node_identifier::identifier()
00106 const
00107 {
00108 return identifier_;
00109 }
00110
00111 void node_identifier::print_node(std::ostream& stream, int indent)
00112 const
00113 {
00114 stream << std::setw(indent) << "" << identifier() << '\n';
00115 }
00116
00117 double node_identifier::evaluate_node()
00118 const
00119 {
00120 return get_variable(identifier());
00121 }
00122
00123 std::string node_identifier::evaluate_string()
00124 const
00125 {
00126 return identifier();
00127 }
00128
00129
00130 node_assign::node_assign(node identifier, node value)
00131 : node_impl(), identifier_(identifier), value_(value)
00132 {}
00133
00134 node node_assign::identifier()
00135 const
00136 {
00137 return identifier_;
00138 }
00139
00140 node node_assign::value()
00141 const
00142 {
00143 return value_;
00144 }
00145
00146 std::string node_assign::get_identifier()
00147 const
00148 {
00149 return identifier().to_string();
00150 }
00151
00152 double node_assign::evaluate_value()
00153 const
00154 {
00155 return value().evaluate();
00156 }
00157
00158 void node_assign::print_node(std::ostream& stream, int indent)
00159 const
00160 {
00161 stream << std::setw(indent) << "" << get_identifier() << ":=\n";
00162 value().print(stream, indent + 2);
00163 }
00164
00165 double node_assign::evaluate_node()
00166 const
00167 {
00168 double result( evaluate_value() );
00169 set_variable(get_identifier(), result);
00170 return result;
00171 }
00172
00173
00174
00175 node_unary::node_unary(node operand)
00176 : node_impl(), operand_(operand)
00177 {}
00178
00179 node node_unary::operand()
00180 const
00181 {
00182 return operand_;
00183 }
00184
00185 double node_unary::evaluate_operand()
00186 const
00187 {
00188 return operand().evaluate();
00189 }
00190
00191 node_binary::node_binary(node left, node right)
00192 : left_(left), right_(right)
00193 {}
00194
00195 node node_binary::left()
00196 const
00197 {
00198 return left_;
00199 }
00200
00201 node node_binary::right()
00202 const
00203 {
00204 return right_;
00205 }
00206
00207 double node_binary::evaluate_left()
00208 const
00209 {
00210 return left().evaluate();
00211 }
00212
00213 double node_binary::evaluate_right()
00214 const
00215 {
00216 return right().evaluate();
00217 }
00218
00219
00220 node_negate::node_negate(node operand)
00221 : node_unary(operand)
00222 {}
00223
00224 void node_negate::print_node(std::ostream& stream, int indent)
00225 const
00226 {
00227 stream << std::setw(indent) << "" << "-\n";
00228 operand().print(stream, indent + 2);
00229 }
00230
00231 double node_negate::evaluate_node()
00232 const
00233 {
00234 return -evaluate_operand();
00235 }
00236
00237
00238 node_add::node_add(node left, node right)
00239 : node_binary(left, right)
00240 {}
00241
00242 void node_add::print_node(std::ostream& stream, int indent)
00243 const
00244 {
00245 stream << std::setw(indent) << "" << "+\n";
00246 left().print(stream, indent + 2);
00247 right().print(stream, indent + 2);
00248 }
00249
00250 double node_add::evaluate_node()
00251 const
00252 {
00253 return evaluate_left() + evaluate_right();
00254 }
00255
00256
00257 node_subtract::node_subtract(node left, node right)
00258 : node_binary(left, right)
00259 {}
00260
00261 void node_subtract::print_node(std::ostream& stream, int indent)
00262 const
00263 {
00264 stream << std::setw(indent) << "" << "-\n";
00265 left().print(stream, indent + 2);
00266 right().print(stream, indent + 2);
00267 }
00268
00269 double node_subtract::evaluate_node()
00270 const
00271 {
00272 return evaluate_left() - evaluate_right();
00273 }
00274
00275
00276 node_multiply::node_multiply(node left, node right)
00277 : node_binary(left, right)
00278 {}
00279
00280 void node_multiply::print_node(std::ostream& stream, int indent)
00281 const
00282 {
00283 stream << std::setw(indent) << "" << "*\n";
00284 left().print(stream, indent + 2);
00285 right().print(stream, indent + 2);
00286 }
00287
00288 double node_multiply::evaluate_node()
00289 const
00290 {
00291 return evaluate_left() * evaluate_right();
00292 }
00293
00294
00295 node_divide::node_divide(node left, node right)
00296 : node_binary(left, right)
00297 {}
00298
00299 void node_divide::print_node(std::ostream& stream, int indent)
00300 const
00301 {
00302 stream << std::setw(indent) << "" << "/\n";
00303 left().print(stream, indent + 2);
00304 right().print(stream, indent + 2);
00305 }
00306
00307 double node_divide::evaluate_node()
00308 const
00309 {
00310 return evaluate_left() / evaluate_right();
00311 }