Advertisement
Korotkodul

calculator.cpp

Sep 30th, 2024
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.52 KB | None | 0 0
  1. //
  2. // This is example of starting code from Chapter 7.8 "Variables" of
  3. // "Software - Principles and Practice using C++" by Bjarne Stroustrup
  4. //
  5.  
  6.  
  7. #include <std_lib_facilities.h>
  8. #include "token.h"
  9. #include "variable.h"
  10.  
  11.  
  12. double get_value(string s) {
  13.     for (int i = 0; i < var_table.size(); ++i) {
  14.         if (var_table[i].name == s) {
  15.             return var_table[i].value;
  16.         }
  17.     }
  18.     error("get: undefined _name", s);
  19. }
  20.  
  21. void set_value (const string& s, double d)
  22. {
  23.   for (auto& var : var_table)
  24.   {
  25.     if (var.name == s)
  26.     {
  27.       var.value = d;
  28.       return;
  29.     }
  30.   }
  31.  
  32.   error("set: undefined name ", s);
  33. }
  34.  
  35.  
  36. bool is_declared (const string& s)
  37. {
  38.   for (const auto& var : var_table)
  39.   {
  40.     if (var.name == s)
  41.       return true;
  42.   }
  43.  
  44.   return false;
  45. }
  46.  
  47. double define_name (const string& var, double val)
  48. {
  49.   if (is_declared(var))
  50.     error(var, " declared twice");
  51.  
  52.   var_table.push_back(Variable{var, val});
  53.  
  54.   return val;
  55. }
  56.  
  57. Token_stream ts;
  58.  
  59. double expression ();
  60.  
  61. double primary ()
  62. {
  63.   Token t = ts.get();
  64.   switch (t.kind)
  65.   {
  66.   case '(':
  67.   {
  68.     double d = expression();
  69.     t = ts.get();
  70.     if (t.kind != ')')
  71.       error("'(' expected");
  72.     return d;
  73.   }
  74.  
  75.   case '-':
  76.     return -primary();
  77.   case '+':
  78.     return +primary();
  79.  
  80.   case number:
  81.     return t.value;
  82.  
  83.   case name:
  84.     return get_value(t.name);
  85.  
  86.   default:
  87.     error("primary expected");
  88.   }
  89. }
  90.  
  91. double term ()
  92. {
  93.   double left = primary();
  94.  
  95.   while (true)
  96.   {
  97.     Token t = ts.get();
  98.  
  99.     switch (t.kind)
  100.     {
  101.     case '*':
  102.       left *= primary();
  103.       break;
  104.  
  105.     case '/':
  106.     {
  107.       double d = primary();
  108.       if (d == 0)
  109.         error("divide by zero");
  110.       left /= d;
  111.       break;
  112.     }
  113.  
  114.     case '%':
  115.     {
  116.       double d = primary();
  117.       if (d == 0)
  118.         error("'%': divide by zero");
  119.       left = fmod(left, d);
  120.       break;
  121.     }
  122.  
  123.     default:
  124.       ts.putback(t);
  125.       return left;
  126.     }
  127.   }
  128. }
  129.  
  130. double expression ()
  131. {
  132.   double left = term();
  133.  
  134.   while (true)
  135.   {
  136.     Token t = ts.get();
  137.  
  138.     switch (t.kind)
  139.     {
  140.     case '+':
  141.       left += term();
  142.       break;
  143.  
  144.     case '-':
  145.       left -= term();
  146.       break;
  147.  
  148.     default:
  149.       ts.putback(t);
  150.       return left;
  151.     }
  152.   }
  153. }
  154.  
  155. double declaration ()
  156. {
  157.   Token t = ts.get();
  158.   if (t.kind != name)
  159.     error("name expected in declaration");
  160.  
  161.   string var = t.name;
  162.   if (is_declared(var))
  163.     error(var, " declared twice");
  164.  
  165.   t = ts.get();
  166.   if (t.kind != '=')
  167.     error("'=' missing in declaration of ", var);
  168.  
  169.   return define_name(var, expression());
  170. }
  171.  
  172. double statement ()
  173. {
  174.   Token t = ts.get();
  175.   switch (t.kind)
  176.   {
  177.   case let:
  178.     return declaration();
  179.   default:
  180.     ts.putback(t);
  181.     return expression();
  182.   }
  183. }
  184.  
  185. void clean_up_mess () { ts.ignore(print); }
  186.  
  187. void calculate ()
  188. {
  189.   Token_stream ts;
  190.  
  191.   while (true)
  192.     try
  193.     {
  194.       cout << prompt;
  195.       Token t = ts.get();
  196.       while (t.kind == print)
  197.         t = ts.get();
  198.       if (t.kind == quit)
  199.         return;
  200.  
  201.       ts.putback(t);
  202.       cout << result << statement() << endl;
  203.     }
  204.     catch (runtime_error& e)
  205.     {
  206.       cerr << e.what() << endl;
  207.       clean_up_mess();
  208.     }
  209. }
  210.  
  211. int main ()
  212. try
  213. {
  214.   define_name("pi", 3.141592653589793);
  215.   define_name("e", 2.718281828459045);
  216.  
  217.   calculate();
  218. }
  219. catch (exception& e)
  220. {
  221.   cerr << "exception: " << e.what() << endl;
  222.   return 1;
  223. }
  224. catch (...)
  225. {
  226.   cerr << "Oops, unknown exception" << endl;
  227.   return 2;
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement