The text for this exercise reads:
Allow a user to define a function in the calculator. Hint: Define a function as a sequence of operations just as the user would have typed them. Such a sequence can be stored either as a character string or a list of tokens. Then read and execute those operations. If you want user-defined functions to take arguments, you will have to invent a notation for that.
I have changed my func class completely. Before it stored info as a set of symbols. Now I use strings with the character 'x' as the variable. When evaluating the value from an argument I do a replace (arg -> 'x') and use the calculator engine to do the calculations.
class func
{
public:
func() {}
func(string str);
~func() {}
func& operator= (string str) { func tmp(str); *this = tmp; }
func& operator= (char* p) { this->operator=(string(p)); return *this; }
double operator() (double) const;
private:
static const string rep; //rep = "x"
static double evaluate(string); // calls the calculator code on the string arg.
string m_str;
};
There are two ways to use a function: as a macro or as a real function. Macros are defined in the f()="macro" style, functions are defined using f(x)="function". The string passed to the constructors may (but is not required to) contain the function name before the parentheses.
func::func(string str)
{
string::size_type placer = 0;
while (str[placer] != '(') ++placer; //eat function name
if (str[placer + 1] == ')') // we have a simple macro
{
placer += 2; // for the ")="
m_str.assign(str,placer,string::npos);
return;
}
string::size_type func_begin = placer;
string::size_type var_sz = 0;
while(str[++placer] != ')') ++var_sz;
string var_name(str,placer,var_sz);
while ( (placer = tmp.find(var_name)) != string::npos)
{
tmp.replace(placer,var_name.size(),rep);
}
m_str.assign(tmp,func_begin,string::npos);
}
This is a very simple function:
double func::operator()(double arg) const
{
string tmp = m_srt;
istringstream a;
a << arg;
string argument = a.str();
string::size_type where;
while( (where = tmp.find(rep)) != string::npos)
{
tmp.replace(where,1,argument);
}
return evaluate(tmp);
}
double func::evaluate(string str)
{
Back to the Exercise Page