node_impl.cpp

Go to the documentation of this file.
00001 #include <iomanip>
00002 #include <iterator>
00003 #include <ostream>
00004 #include <sstream>
00005 
00006 #include "calc_error.hpp"
00007 #include "node.hpp"
00008 #include "node_impl.hpp"
00009 #include "variables.hpp"
00010 
00011 node_impl::node_impl()
00012 : refcount_(1)
00013 {}
00014 
00015 node_impl::~node_impl()
00016 {}
00017 
00018 void node_impl::print(std::ostream& stream, int indent)
00019 const
00020 {
00021   print_node(stream, indent);
00022 }
00023 
00024 double node_impl::evaluate()
00025 const
00026 {
00027   return evaluate_node();
00028 }
00029 
00030 std::string node_impl::to_string()
00031 const
00032 {
00033   return evaluate_string();
00034 }
00035 
00036 void node_impl::add_ref()
00037 {
00038   ++refcount_;
00039 }
00040 
00041 identifier_list const& node_impl::get_parameters()
00042 const
00043 {
00044   return evaluate_parameters();
00045 }
00046 
00047 void node_impl::del_ref()
00048 {
00049   --refcount_;
00050   if (refcount_ == 0)
00051     delete this;
00052 }
00053 
00054 std::string node_impl::evaluate_string()
00055 const
00056 {
00057   std::ostringstream stream;
00058   stream << evaluate();
00059   return stream.str();
00060 }
00061 
00062 identifier_list const& node_impl::evaluate_parameters()
00063 const
00064 {
00065   static identifier_list const empty;
00066   return empty;
00067 }
00068 
00069 
00070 node_void::node_void()
00071 : node_impl()
00072 {}
00073 
00074 void node_void::print_node(std::ostream& stream, int indent)
00075 const
00076 {
00077   stream << std::setw(indent) << "" << "void\n";
00078 }
00079 
00080 double node_void::evaluate_node()
00081 const
00082 {
00083   return 0.0;
00084 }
00085 
00086 std::string node_void::evaluate_string()
00087 const
00088 {
00089   return std::string();
00090 }
00091 
00092 
00093 node_number::node_number(double value)
00094 : node_impl(), value_(value)
00095 {}
00096 
00097 double node_number::value()
00098 const
00099 {
00100   return value_;
00101 }
00102 
00103 void node_number::print_node(std::ostream& stream, int indent)
00104 const
00105 {
00106   stream << std::setw(indent) << "" << value() << '\n';
00107 }
00108 
00109 double node_number::evaluate_node()
00110 const
00111 {
00112   return value();
00113 }
00114 
00115 node_identifier::node_identifier(std::string const& name)
00116 : node_impl(), name_(name)
00117 {}
00118 
00119 std::string const& node_identifier::name()
00120 const
00121 {
00122   return name_;
00123 }
00124 
00125 void node_identifier::print_node(std::ostream& stream, int indent)
00126 const
00127 {
00128   stream << std::setw(indent) << "" << "identifier:" << name() << '\n';
00129 }
00130 
00131 double node_identifier::evaluate_node()
00132 const
00133 {
00134   return get_variable(name()).evaluate();
00135 }
00136 
00137 std::string node_identifier::evaluate_string()
00138 const
00139 {
00140   return name();
00141 }
00142 
00143 
00144 node_function::node_function(identifier_list const& parameters, node definition)
00145 : node_impl(), parameters_(parameters), definition_(definition)
00146 {}
00147 
00148 identifier_list const& node_function::parameters()
00149 const
00150 {
00151   return parameters_;
00152 }
00153 
00154 node node_function::definition()
00155 const
00156 {
00157   return definition_;
00158 }
00159 
00160 void print_identifier_list(std::ostream& stream, identifier_list const& identifiers)
00161 {
00162   stream << '(';
00163   char const* sep = "";
00164   for (identifier_list::const_iterator id(identifiers.begin()); id != identifiers.end(); ++id) {
00165     stream << sep << *id;
00166     sep = ", ";
00167   }
00168   stream << ')';
00169 }
00170 
00171 void node_function::print_node(std::ostream& stream, int indent)
00172 const
00173 {
00174   stream << std::setw(indent) << "" << "fun\n";
00175   print_identifier_list(stream, parameters());
00176   stream << '=';
00177   definition().print(stream, indent + 2);
00178 }
00179 
00180 double node_function::evaluate_node()
00181 const
00182 {
00183   return definition().evaluate();
00184 }
00185 
00186 identifier_list const& node_function::evaluate_parameters()
00187 const
00188 {
00189   return parameters();
00190 }
00191 
00192 
00193 node_function_call::node_function_call(std::string const& name, node_list const& arguments)
00194 : node_impl(), name_(name), arguments_(arguments)
00195 {}
00196 
00197 std::string node_function_call::name()
00198 const
00199 {
00200   return name_;
00201 }
00202 
00203 node_list const& node_function_call::arguments()
00204 const
00205 {
00206   return arguments_;
00207 }
00208 
00209 void node_function_call::print_node(std::ostream& stream, int indent)
00210 const
00211 {
00212   stream << std::setw(indent) << "" << name() << "(\n";
00213   for (node_list::const_iterator first(arguments().begin()), arg(first); arg != arguments().end(); ++arg) {
00214     stream << std::setw(indent+1) << "" << "arg " << std::distance(first, arg) << ": ";
00215     arg->print(stream, indent + 2);
00216   }
00217   stream << std::setw(indent) << "" << ")\n";
00218 }
00219 
00220 double node_function_call::evaluate_node()
00221 const
00222 {
00223   // Create a local symbol table, assigning all the node values to the parameters.
00224   node function = get_function(name());
00225   identifier_list const& parameters( function.get_parameters() );
00226   if (parameters.size() != arguments().size())
00227     throw function_error(name(), parameters.size(), arguments().size());
00228   else
00229   {
00230     // Create a local symbol table by assigning the arguments to the function parameters.
00231     symbol_table locals;
00232     identifier_list::const_iterator parm(parameters.begin());
00233     for (node_list::const_iterator arg(arguments().begin()); arg != arguments().end(); ++arg, ++parm) {
00234       locals.insert(std::make_pair(*parm, *arg));
00235     }
00236     set_symbol_table syms(locals);
00237     return function.evaluate();
00238   }
00239 }
00240 
00241 
00242 
00243 node_unary::node_unary(node operand)
00244 : node_impl(), operand_(operand)
00245 {}
00246 
00247 node node_unary::operand()
00248 const
00249 {
00250   return operand_;
00251 }
00252 
00253 double node_unary::evaluate_operand()
00254 const
00255 {
00256   return operand().evaluate();
00257 }
00258 
00259 node_binary::node_binary(node left, node right)
00260 : left_(left), right_(right)
00261 {}
00262 
00263 node node_binary::left()
00264 const
00265 {
00266   return left_;
00267 }
00268 
00269 node node_binary::right()
00270 const
00271 {
00272   return right_;
00273 }
00274 
00275 double node_binary::evaluate_left()
00276 const
00277 {
00278   return left().evaluate();
00279 }
00280 
00281 double node_binary::evaluate_right()
00282 const
00283 {
00284   return right().evaluate();
00285 }
00286 
00287 
00288 node_negate::node_negate(node operand)
00289 : node_unary(operand)
00290 {}
00291 
00292 void node_negate::print_node(std::ostream& stream, int indent)
00293 const
00294 {
00295   stream << std::setw(indent) << "" << "-\n";
00296   operand().print(stream, indent + 2);
00297 }
00298 
00299 double node_negate::evaluate_node()
00300 const
00301 {
00302   return -evaluate_operand();
00303 }
00304 
00305 
00306 node_add::node_add(node left, node right)
00307 : node_binary(left, right)
00308 {}
00309 
00310 void node_add::print_node(std::ostream& stream, int indent)
00311 const
00312 {
00313   stream << std::setw(indent) << "" << "+\n";
00314   left().print(stream, indent + 2);
00315   right().print(stream, indent + 2);
00316 }
00317 
00318 double node_add::evaluate_node()
00319 const
00320 {
00321   return evaluate_left() + evaluate_right();
00322 }
00323 
00324 
00325 node_subtract::node_subtract(node left, node right)
00326 : node_binary(left, right)
00327 {}
00328 
00329 void node_subtract::print_node(std::ostream& stream, int indent)
00330 const
00331 {
00332   stream << std::setw(indent) << "" << "-\n";
00333   left().print(stream, indent + 2);
00334   right().print(stream, indent + 2);
00335 }
00336 
00337 double node_subtract::evaluate_node()
00338 const
00339 {
00340   return evaluate_left() - evaluate_right();
00341 }
00342 
00343 
00344 node_multiply::node_multiply(node left, node right)
00345 : node_binary(left, right)
00346 {}
00347 
00348 void node_multiply::print_node(std::ostream& stream, int indent)
00349 const
00350 {
00351   stream << std::setw(indent) << "" << "*\n";
00352   left().print(stream, indent + 2);
00353   right().print(stream, indent + 2);
00354 }
00355 
00356 double node_multiply::evaluate_node()
00357 const
00358 {
00359   return evaluate_left() * evaluate_right();
00360 }
00361 
00362 
00363 node_divide::node_divide(node left, node right)
00364 : node_binary(left, right)
00365 {}
00366 
00367 void node_divide::print_node(std::ostream& stream, int indent)
00368 const
00369 {
00370   stream << std::setw(indent) << "" << "/\n";
00371   left().print(stream, indent + 2);
00372   right().print(stream, indent + 2);
00373 }
00374 
00375 double node_divide::evaluate_node()
00376 const
00377 {
00378   return evaluate_left() / evaluate_right();
00379 }

Generated on Sun Nov 30 10:05:26 2008 for Calculator by  doxygen 1.5.3