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 }