C++ – Method to return to beginning of function

c++

Does C++ have any type of utility to return to the beginning of a function after a function call? For example, example the call to help() in the calculate function.

void help()
{
     cout << "Welcome to this annoying calculator program.\n";
     cout << "You can add(+), subtract(-), multiply(*), divide(/),\n";
     cout << "find the remainder(%), square root(sqrt()), use exponents(pow(x,x)),\n";
     cout << "use parentheses, assign variables (ex: let x = 3), and assign\n";
     cout << " constants (ex: const pi = 3.14). Happy Calculating!\n";
     return;
}

void clean_up_mess()        // purge error tokens
{
    ts.ignore(print);
}

const string prompt = "> ";
const string result = "= ";

void calculate()
{
    while(true) try {
        cout << prompt;
        Token t = ts.get();
        if (t.kind == help_user) help();  
        else if (t.kind == quit) return;
        while (t.kind == print) t=ts.get();
        ts.unget(t);
        cout << result << statement() << endl;
    }
    catch(runtime_error& e) {
        cerr << e.what() << endl;
        clean_up_mess();
    }
}

While technically my implementation of a help function works fine, it's not perfect. After help is called, and returns, it proceeds with trying to cout << result << statement() << endl; which isn't possible because no values have been entered. Thus it gives a little error message (elsewhere in the program) and then proceeds on with the program. No problem with functionality, but it's ugly and I don't like it (:P).

So is there any way for when the help function returns, to return to the beginning of calculate and start over? (I played around with inserting a function call in if(t.kind == help_user) block to call calculate, but as I figured that just delays the problem rather than solving it.)

Best Solution

You can use goto, but the moment you do that consider yourself over. It's considered bad practice and good uses of it are rare and far apart.

I think what you're looking for is continue:

void do_calculate(void)
{
    while (true)
    {
        cout << prompt;
        Token t = ts.get();

        if (t.kind == help_user)
        {
            help();  
            continue; // <- here
        }
        else if (t.kind == quit)
        {
            return;
        }

        while (t.kind == print)
        {
            t = ts.get();
        }
        ts.unget(t);

        cout << result << statement() << endl;
    }
}

void calculate()
{
    try
    {
        do_calculate();
    }
    catch (const std::exception& e)
    {
        cerr << e.what() << endl;
        clean_up_mess();
    }
}

I have also reformatted your code. I think this is more readable, to each his own but just wanted to let you compare.

  • The try/catch clause is now no longer interfering with the calculation function.

  • The 'if' statements use brackets for consistency. Also, it's much easier to read, because I know whatever the if is controlling is within these brackets.

  • The catch will catch a std::exception, rather than runtime_error. All standard exceptions inherit from std::exception, so by catching that you know you can catch anything.