- Main Page
- Classes
- Files

# 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 }