45 std::ostringstream stream{};
67 if (not (stream >> type))
70 return std::make_shared<node_void>(stream);
72 return std::make_shared<node_number>(stream);
73 if (type ==
"identifier")
74 return std::make_shared<node_identifier>(stream);
75 if (type ==
"function")
76 return std::make_shared<node_function>(stream);
78 return std::make_shared<node_function_call>(stream);
80 return std::make_shared<node_negate>(stream);
82 return std::make_shared<node_add>(stream);
83 if (type ==
"subtract")
84 return std::make_shared<node_subtract>(stream);
85 if (type ==
"multiply")
86 return std::make_shared<node_multiply>(stream);
88 return std::make_shared<node_divide>(stream);
90 throw calc_error{
"unknown node type: " + type};
104 stream << std::setw(indent) <<
"" <<
"void\n";
116 return std::string{};
132 if (not (stream >> value_))
133 throw calc_error{
"malformed library file, cannot read number"};
145 stream << std::setw(indent) <<
"" <<
value() <<
'\n';
157 stream <<
"number " <<
value() <<
'\n';
168 if (not (stream >> name_))
169 throw calc_error{
"malformed library file, cannot read identifier"};
181 stream << std::setw(indent) <<
"" <<
"identifier " <<
name() <<
'\n';
199 stream <<
"identifier " <<
name() <<
'\n';
204 :
node_impl{}, parameters_{std::move(parameters)}, definition_(definition)
211 if (not (stream >> size))
212 throw calc_error{
"malformed library file, cannot read function"};
213 parameters_.reserve(size);
214 while (size-- != 0) {
215 std::string parameter{};
216 if (not (stream >> parameter))
217 throw calc_error{
"malformed library file, cannot read function parameter"};
218 parameters_.emplace_back(std::move(parameter));
220 definition_ =
node(stream);
238 char const* sep =
"";
239 for (
auto const&
id : identifiers) {
249 stream << std::setw(indent) <<
"" <<
"fun\n";
270 stream <<
"function " <<
parameters().size() <<
' ';
272 stream << parameter <<
' ';
278 :
node_impl{}, name_{std::move(name)}, arguments_{std::move(arguments)}
285 if (not (stream >> name_))
286 throw calc_error{
"malformed library file, cannot read function call name"};
288 if (not (stream >> size))
289 throw calc_error{
"malformed library file, cannot read function call"};
290 arguments_.reserve(size);
291 while (size-- != 0) {
292 arguments_.emplace_back(stream);
311 stream << std::setw(indent) <<
"" <<
name() <<
"(\n";
312 std::size_t index{0};
314 stream << std::setw(indent+1) <<
"" <<
"arg " << index <<
": ";
315 arg.print(stream, indent + 2);
318 stream << std::setw(indent) <<
"" <<
")\n";
327 if (parameters.size() !=
arguments().size())
333 identifier_list::const_iterator parm{parameters.begin()};
335 locals.emplace(*parm, arg);
339 return function.evaluate();
346 stream <<
"call " <<
name() <<
' ' <<
arguments().size() <<
' ';
373 :
node_impl{}, left_{left}, right_{right}
377 :
node_impl{}, left_{stream}, right_{stream}
416 stream << std::setw(indent) <<
"" <<
"-\n";
446 stream << std::setw(indent) <<
"" <<
"+\n";
477 stream << std::setw(indent) <<
"" <<
"-\n";
491 stream <<
"subtract ";
508 stream << std::setw(indent) <<
"" <<
"*\n";
522 stream <<
"multiply ";
539 stream << std::setw(indent) <<
"" <<
"/\n";
virtual double evaluate_node() const override
node_number(double value)
double evaluate_right() const
node get_function(std::string const &name)
virtual void save_node(std::ostream &stream) const override
void save(std::ostream &stream) const
virtual void save_node(std::ostream &stream) const override
virtual std::string evaluate_string() const override
virtual std::string evaluate_string() const
virtual void print_node(std::ostream &stream, int indent) const override
virtual double evaluate_node() const =0
virtual double evaluate_node() const override
node_list const & arguments() const
virtual void print_node(std::ostream &stream, int indent) const override
virtual void print_node(std::ostream &stream, int indent) const override
double evaluate_left() const
virtual void save_node(std::ostream &stream) const override
node_function_call(std::string name, node_list arguments)
node_binary(node left, node right)
virtual double evaluate_node() const override
virtual double evaluate_node() const override
std::string const & name() const
virtual void print_node(std::ostream &stream, int indent) const override
virtual std::string evaluate_string() const override
node_identifier(std::string name)
virtual void save_node(std::ostream &stream) const override
virtual void print_node(std::ostream &stream, int indent) const override
virtual double evaluate_node() const override
virtual double evaluate_node() const override
void print(std::ostream &stream, int indent) const
std::vector< std::string > identifier_list
A sequence of identifiers (e.g., parameter names).
static std::shared_ptr< node_impl > read_node(std::istream &stream)
virtual void print_node(std::ostream &stream, int indent) const override
virtual void save_node(std::ostream &stream) const override
node_function(identifier_list parameters, node definition)
double evaluate_operand() const
node_multiply(node left, node right)
virtual identifier_list const & evaluate_parameters() const override
virtual void print_node(std::ostream &stream, int indent) const override
void print(std::ostream &stream, int indent=0) const
virtual void save_node(std::ostream &stream) const override
void print_identifier_list(std::ostream &stream, identifier_list const &identifiers)
virtual void print_node(std::ostream &stream, int indent) const override
virtual void print_node(std::ostream &stream, int indent) const =0
identifier_list parameters_
node_subtract(node left, node right)
virtual void save_node(std::ostream &stream) const =0
virtual double evaluate_node() const override
virtual void print_node(std::ostream &stream, int indent) const override
virtual identifier_list const & evaluate_parameters() const
virtual void save_node(std::ostream &stream) const override
virtual double evaluate_node() const override
identifier_list const & get_parameters() const
identifier_list const & get_parameters() const
std::vector< node > node_list
A sequence of nodes.
std::string to_string() const
void save(std::ostream &stream) const
virtual void save_node(std::ostream &stream) const override
node_negate(node operand)
virtual void print_node(std::ostream &stream, int indent) const override
virtual double evaluate_node() const override
virtual void save_node(std::ostream &stream) const override
node_divide(node left, node right)
node_add(node left, node right)
virtual void save_node(std::ostream &stream) const override
identifier_list const & parameters() const
node get_variable(std::string const &name)
std::map< std::string, node > symbol_table
virtual double evaluate_node() const override