Fine program, bizzare output
<p>I have been working with C++ on a calculator that does simple arithmetic calculations. The program was taken from the text book by Stroustrup.  The program output "nan" which made no sense to me as there were simple expressions. I ran the code on other machines it worked fine so I believe there were no errors in the code. I could have posted image of the output from my machine but this forum prevent me from doing so because I am a new user.I am just wondering if anybody has an idea about what's going wrong?</p>

<pre><code>#include"std_lib_facilities.h"

const char number='8';
const char quit='q';
const char print=';';
const string prompt="&gt;";
const string result="=";
const char name='a';//name token
const char let='L';//declaration token
const string declkey="let";//declaration keyword

class Token
{public:
       char kind;
       double value;
       string name;
       Token(char ch)
          :kind(ch),value(0){}
       Token(char ch,double val)
          :kind(ch),value(val){}
       Token(char ch,string n)
          :kind(ch),name(n){}
};

class Token_stream
{public:
       Token_stream();
       Token get();
       void putback(Token t);
       void ignore(char c);//discard characters up to and including c
 private:
       bool full; //is there a token in the buffer?
       Token buffer;
};

Token_stream::Token_stream()
                     :full(false),buffer(0){}
void Token_stream::putback(Token t)
{
    if(full)error("putback() into a full buffer");
    buffer=t;
    full=true;
}
void Token_stream::ignore(char c)//c represents the kind of Token
{
    //first look in buffer
    if(full &amp;&amp; c==buffer.kind)
    {
        full=false;
        return;
    }
    full=false;
    //now search input
    char ch=0;
    while(cin&gt;&gt;ch)
      if(ch==c)return;
}
Token Token_stream::get() //read characters from cin and compose a token
{
    if(full) //remove Token from buffer
    {
        full=false;
        return buffer;
    }

    char ch;
    cin&gt;&gt;ch;
    switch(ch)
    {
        case print://for print
        case quit://for quit
        case'(':
        case')':
        case'+':
        case'-':
        case'*':
        case'/':
        case '%':
        case'=':
          return Token(ch); //let each character represnt itself
        case'.':
        case'0': case'1': case'2': case'3': case'4': case'5':
        case'6': case'7': case'8': case'9':
        {
            cin.putback(ch);//put digit back into the digit stream
            double val;
            cin&gt;&gt;val;
            return Token(number,val);
        }
        default:
          if(isalpha(ch))
          {
              string s;
              s+=ch;
              while(cin.get(ch) &amp;&amp; (isalpha(ch) || isdigit(ch))) s+=ch;
              cin.putback(ch);
              if(s==declkey) return Token(let);//declaration keyword
              return Token(name,s);
          }
          error("Bad token");
    }
}

class Variable
{
    public:
     string name;
     double value;
     Variable(string n, double v): name(n),value(v){}
};

vector&lt;Variable&gt; var_table;
double get_value(string s)//return the value of the Variable named s
{
    for(int i=0;i&lt;var_table.size();++i)
     if(s==var_table[i].name) return var_table[i].value;
    error("get:undefined variable ",s);
}
void set_value(string s,double d)
{
    for(int i=0;i&lt;var_table.size();++i)
      if(s==var_table[i].name) {var_table[i].value=d;return;}
    error("set:undefined variable ",s);
}

bool is_declared(string var)//is var already in var_table?
{
    for(int i=0;i&lt;var_table.size();++i)
      if(var==var_table[i].name) return true;
    return false;
}
double define_name(string var,double val)//add (var,val) to var_table
{
    if(is_declared(var)) error(var,"declared twice");
    var_table.push_back(Variable(var,val));
    return val;
}

Token_stream ts;
double expression();

double primary()
{
    Token t=ts.get();
    switch(t.kind)
    {
        case'(':
              {
                  double d=expression();
                  t=ts.get();
                  if(t.kind!=')')error("')' expected");
                  return d;
              }
        case number:
              return t.value;
        case '-':
              return -primary();
        case '+':
              return primary();
        case name:
              return get_value(t.name);
        default:
              error("primary expected");
    }
}
double term()
{
    double left=primary();
    Token t=ts.get();
    while(true)
    {
        switch(t.kind)
        {
            case'*':
            {
              left*=primary();
              t=ts.get();
              break;
            }
            case'/':
            {
                double d=primary();
                if(d==0) error("divide by zero");
                left/=d;
                t=ts.get();
                break;
            }
            case '%':
            {
                double d=primary();
                int i1=int(left);
                if(i1!=left) error("left-hand operand of % not int");
                int i2=int(d);
                if(i2!=d) error("right-hand operand of % not int");
                if(i2==0) error("%: divide by zero");
                left=i1%i2;
                t=ts.get();
                break;
            }
            default:
                ts.putback(t);//put back into the Token stream
                return left;
        }
    }
}
double expression()
{
    double left=term();
    Token t=ts.get();
    while(true)
    {
        switch(t.kind)
        {
            case'+':
                  left+=term();
                  t=ts.get();
                  break;
            case'-':
                  left-=term();
                  t=ts.get();
                  break;
            default:
                  ts.putback(t);
                  return left;
        }
    }
}


//handle:name=expression, declare a varaible called "name" with initial value "expression"
double declaration()
{
    Token t=ts.get();
    if(t.kind!=name)error("name expected in declaration");
    string var_name=t.name;

    Token t2=ts.get();
    if(t2.kind!='=')error("= missing in declaration of ",var_name);

    double d=expression();
    define_name(var_name,d);
    return d;
}
double statement()
{
    Token t=ts.get();
    switch(t.kind)
    {
        case let:
           return declaration();
        default:
           ts.putback(t);
           return expression();
    }
}

void clean_up_mess()
{
    ts.ignore(print);
}
void calculate()
{
  while(cin)
  try{
      cout&lt;&lt;prompt;
      Token t=ts.get();
      while(t.kind==print) t=ts.get(); //eat';'
      if(t.kind==quit) return;
      ts.putback(t);
      cout&lt;&lt;result&lt;&lt;statement()&lt;&lt;endl;
  }
  catch (exception&amp; e) {
    cerr &lt;&lt; e.what() &lt;&lt; endl;
    clean_up_mess();
  }
}

int main()
 try
{
  calculate();
  keep_window_open();
  return 0;
}
catch (...) {
    cerr &lt;&lt; "exception \n";
    keep_window_open ("~2");
    return 2;
}
</code></pre>
