Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <cmath>
  4.  
  5. // ..:: COMMAND ::..
  6. typedef void(*fptr)();
  7.  
  8. struct Command
  9. {
  10.     const char* name;
  11.     fptr func;
  12. };
  13. // ..:: END COMMAND ::..
  14.  
  15. // ..:: STACK ::..
  16. #define MAX_STACK_LENGTH 8
  17.  
  18. struct Stack
  19. {
  20.     int top;
  21.     double* values;
  22. };
  23.  
  24. // Initialize a stack
  25. void st_init(Stack* st)
  26. {
  27.     st->top = -1;
  28.     st->values = new double[MAX_STACK_LENGTH];
  29. }
  30. // Pop a top value from a stack
  31. void st_pop(Stack* st)
  32. {
  33.     if (st->values == nullptr || st->top == -1)
  34.         throw std::runtime_error("(st_top): The stack is empty");
  35.     st->top--;
  36. }
  37. // Push a value into a stack's top
  38. void st_push(Stack* st, double value)
  39. {
  40.     if (st->top + 1 < MAX_STACK_LENGTH)
  41.         st->values[st->top++] = value;
  42.     else
  43.         throw std::runtime_error("(st_push): The stack is full");
  44. }
  45. // Get the top value from a stack
  46. double st_top(Stack* st)
  47. {
  48.     if (st->top != -1)
  49.         return st->values[st->top - 1];
  50.  
  51.     throw std::runtime_error("(st_top): The stack is empty");
  52. }
  53. // Replace the top value with the new one
  54. void st_replace(Stack* st, double value)
  55. {
  56.     if (st->top == -1)
  57.         throw std::runtime_error("(st_replace): The stack is empty");
  58.         //std::cerr << "(st_replace): The stack is empty" << std::endl;
  59.  
  60.     st->values[st->top - 1] = value;
  61. }
  62. // Remove all values from a stack
  63. void st_clear(Stack* st)
  64. {
  65.     st_free(st);
  66.     st_init(st);
  67. }
  68. // Free the memory allocated for the stack values
  69. void st_free(Stack* st)
  70. {
  71.     delete[] st->values;
  72. }
  73. // ..:: END STACK ::..
  74.  
  75. // ..:: MAIN ::..
  76. // PI value
  77. #define M_PI 3.14159265358979323846
  78.  
  79. static Stack* stack; // The main stack
  80.  
  81. static bool in_runtime = true; // Is program still running
  82.  
  83. // Clear the stack (remove all data)
  84. void fn_clear()
  85. {
  86.     st_clear(stack);
  87. }
  88.  
  89. // Print the top value from the stack
  90. void fn_print()
  91. {
  92.     std::cout << st_top(stack) << std::endl;
  93. }
  94.  
  95. // Quit the program
  96. void fn_quit()
  97. {
  98.     in_runtime = false;
  99. }
  100.  
  101. // Addition
  102. void op_add()
  103. {
  104.     double a, b;
  105.     a = st_top(stack);
  106.     st_pop(stack);
  107.     b = st_top(stack);
  108.     st_pop(stack);
  109.     st_push(stack, a + b);
  110. }
  111.  
  112. // Subtraction
  113. void op_subtract()
  114. {
  115.     double a, b;
  116.     a = st_top(stack);
  117.     st_pop(stack);
  118.     b = st_top(stack);
  119.     st_pop(stack);
  120.     st_push(stack, b - a);
  121. }
  122.  
  123. // Multiplication
  124. void op_multiply()
  125. {
  126.     double a, b;
  127.     a = st_top(stack);
  128.     st_pop(stack);
  129.     b = st_top(stack);
  130.     st_pop(stack);
  131.     st_push(stack, a * b);
  132. }
  133.  
  134. // Division
  135. void op_divide()
  136. {
  137.     double a, b;
  138.     a = st_top(stack);
  139.     st_pop(stack);
  140.     b = st_top(stack);
  141.     if (a == 0) throw std::runtime_error("Cannot divide by zero");
  142.     st_pop(stack);
  143.     st_push(stack, b / a);
  144. }
  145.  
  146. // Sine function
  147. void fn_sin()
  148. {
  149.     double a = st_top(stack);
  150.     st_pop(stack);
  151.     st_push(stack, std::sin(a));
  152. }
  153.  
  154. // Cosine function
  155. void fn_cos()
  156. {
  157.     double a = st_top(stack);
  158.     st_pop(stack);
  159.     st_push(stack, std::cos(a));
  160. }
  161.  
  162. // Tangent function
  163. void fn_tan()
  164. {
  165.     double a = st_top(stack);
  166.     if (std::cos(a) == 0) throw std::runtime_error("Bad values for tan function (cos a = 0, division by zero)");
  167.     st_pop(stack);
  168.     st_push(stack, std::tan(a));
  169. }
  170.  
  171. // Arctangent function
  172. void fn_atan()
  173. {
  174.     double a = st_top(stack);
  175.     st_pop(stack);
  176.     st_push(stack, std::atan(a));
  177. }
  178.  
  179. // Arcsine function
  180. void fn_asin()
  181. {
  182.     double a = st_top(stack);
  183.     if (a < -1 || a > 1) throw std::runtime_error("Bad values for asin function (a < -1 or a > 1)");
  184.     st_pop(stack);
  185.     st_push(stack, std::asin(a));
  186. }
  187.  
  188. // Arccosine function
  189. void fn_acos()
  190. {
  191.     double a = st_top(stack);
  192.     if (a < -1 || a > 1) throw std::runtime_error("Bad values for acos function (a < -1 or a > 1)");
  193.     st_pop(stack);
  194.     st_push(stack, std::acos(a));
  195. }
  196.  
  197. // PI constant
  198. void cn_pi()
  199. {
  200.     st_push(stack, M_PI);
  201. }
  202.  
  203. Command cmd[14] = {
  204.     // Operators
  205.     { "+",      op_add      },
  206.     { "-",      op_subtract },
  207.     { "*",      op_multiply },
  208.     { "/",      op_divide   },
  209.     // Functions
  210.     { "clear",  fn_clear    },
  211.     { "print",  fn_print    },
  212.     { "quit",   fn_quit     },
  213.     { "sin",    fn_sin      },
  214.     { "cos",    fn_cos      },
  215.     { "tan",    fn_tan      },
  216.     { "atan",   fn_atan     },
  217.     { "asin",   fn_asin     },
  218.     { "acos",   fn_acos     },
  219.     // Constants
  220.     { "pi",     cn_pi       },
  221. };
  222.  
  223. fptr get_function_by_name(const char* name)
  224. {
  225.     for (int i = 0; i < 14; i++)
  226.         if (strcmp(cmd[i].name, name) == 0)
  227.             return cmd[i].func;
  228.  
  229.     throw std::runtime_error("No function with this name found");
  230. }
  231.  
  232. int main()
  233. {
  234.     stack = new Stack();
  235.  
  236.     st_init(stack);
  237.  
  238.     std::string last_cmd = "";
  239.  
  240.     do
  241.     {
  242.         std::cin >> last_cmd;
  243.  
  244.         try
  245.         {
  246.             if (isdigit(last_cmd[0]))
  247.             {
  248.                 double value = std::stod(last_cmd.c_str());
  249.                 st_push(stack, value);
  250.             }
  251.             else
  252.                 get_function_by_name(last_cmd.c_str())();
  253.         }
  254.         catch (std::exception ex)
  255.         {
  256.             std::cerr << ex.what() << std::endl;
  257.         }
  258.     } while (in_runtime);
  259.  
  260.     st_free(stack);
  261.     delete stack;
  262.  
  263.     return 0;
  264. }
  265. // ..:: END MAIN ::..
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement