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