// in_driver.cpp : a infix evaluator driver #include #include #include #include "Lexer.h" #include "Infix_Evaluator.h" #include "term_control.h" #include "error_handling.h" using namespace std; // ---------------------------------------------------------------------------------- // prototypes and typedefs // ---------------------------------------------------------------------------------- typedef void (*cmd_t)(Lexer); void print_exp(Lexer); // print the value of an expression void assign(Lexer); // assign a variable to be an exp void bye(Lexer); // simply quit void prompt(); static map sym_table; /** * ---------------------------------------------------------------------------------- * the body * ---------------------------------------------------------------------------------- */ int main() { Lexer lexer; string line; Token tok; map cmd_map; cmd_map["exit"] = &bye; cmd_map["bye"] = &bye; cmd_map["print"] = &print_exp; cmd_map["assign"] = &assign; cout << term_cc(YELLOW) << "UB Calculator Program. Version 0.9" << endl << " Author: Hung Q. Ngo" << endl << " Report bugs to hungngo@buffalo.edu\n"; while (cin) { prompt(); getline(cin, line); lexer.set_input(line); if (!lexer.has_more_token()) continue; tok = lexer.next_token(); if (tok.type != IDENT) { error_return("Syntax error\n"); continue; } if (cmd_map.find(tok.value) != cmd_map.end()) cmd_map[tok.value](lexer); else error_return("Unknown command"); } return 0; } /** * ----------------------------------------------------------------------------- * print the expression if there's no error * ----------------------------------------------------------------------------- */ void print_exp(Lexer lexer) { Infix_Evaluator ie; double result; try { ie.set_expression(lexer); result = ie.eval(sym_table); cout << term_cc(CYAN) << "= " << result << term_cc() << endl; } catch (runtime_error &dbz) { error_return(dbz.what()); } } /** * ----------------------------------------------------------------------------- * assign a variable. * ----------------------------------------------------------------------------- */ void assign(Lexer lexer) { Infix_Evaluator ie; double result; Token var_tok, assign_tok; // short circuit evaluation if (!lexer.has_more_token() || (var_tok = lexer.next_token()).type != IDENT) { error_return("Syntax error: assign var = expression"); return; } // short circuit evaluation if (!lexer.has_more_token() || (assign_tok = lexer.next_token()).type != OPERATOR || assign_tok.value[0] != '=') { error_return("Syntax error: assign var = expression"); return; } try { ie.set_expression(lexer); result = ie.eval(sym_table); sym_table[var_tok.value] = result; cout << term_cc(CYAN) << var_tok.value << " = " << result << term_cc() << endl; } catch (runtime_error &dbz) { error_return(dbz.what()); } } /** * ----------------------------------------------------------------------------- * terminates the program, ignores all parameters * ----------------------------------------------------------------------------- */ void bye(Lexer lexer) { if (lexer.has_more_token()) { error_return("Syntax error: use bye/exit/quit\n"); } else { exit(0); } } /** * ---------------------------------------------------------------------------------- * just print a prompt. * ---------------------------------------------------------------------------------- */ void prompt() { cout << term_cc(BLUE) << "> " << term_cc() << flush; }