double expression(TokenStream& tokenStream) { double result = term(tokenStream); // set result to value of term Token token = tokenStream.getToken(); // get next token from tokenStream while (true) { if (token.kind == '+') { result += term(tokenStream); // evaluate term and add to result token = tokenStream.getToken(); // get next token from tokenStream } if (token.kind == '-') { result -= term(tokenStream); // evaluate term and subtract from result token = tokenStream.getToken(); // get next token from tokenStream } if (token.kind != '+' && token.kind != '-') { tokenStream.setToken(token); // reset token into token stream return result; // return result } } }
void calculate() { const char quit = 'q'; // t.kind==quit means that t is a quit Token const char print = ';'; // t.kind==print means that t is a print Token const std::string prompt = "> "; const std::string equals = "= "; // used to indicate that what follows is an evaluation TokenStream tokenStream; std::string enterToClose = "~~"; while (std::cin) try { std::cout << prompt; Token token = tokenStream.getToken(); if (token.kind == print) token = tokenStream.getToken(); // eat ';' if (token.kind == quit) break; tokenStream.setToken(token); // reset token into tokenStream std::cout << equals << expression(tokenStream) << '\n'; } catch (std::exception& e) { std::cerr << e.what() << '\n'; // write error message tokenStream.ignore(print); } }
double term(TokenStream& tokenStream) { double result = primary(tokenStream); // set result to value of primary Token token = tokenStream.getToken(); // get next token from tokenStream while (true) { if (token.kind == '*') { result *= primary(tokenStream); // evaluate primary and multiply with result token = tokenStream.getToken(); // get next token from tokenStream } else if (token.kind == '/') { double divisor = primary(tokenStream); // set divisor to value of primary if (divisor == 0) error("divide by zero"); // check for error result /= divisor; // divide result by divisor token = tokenStream.getToken(); // get next token from tokenStream } else if (token.kind == '%') // modulo will only work on ints for this implementation { int numer = result; // cast result to int int denom = primary(tokenStream); // cast denom to int if (denom == 0) error("%: divide by zero"); // error check result = numer % denom; // get result token = tokenStream.getToken(); // get next token from tokenStream } else { tokenStream.setToken(token); // put token back into the Token stream return result; // return result } } }