rmoronsv

Untitled

Dec 24th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.51 KB | None | 0 0
  1. #define NUMBER 1
  2.  
  3. int getop(char[]); //processes data into a number that is pushed onto a stack or an operand
  4. void push(double); //stores argument into values[]
  5. double pop(void); //returns the top value in stack values[]
  6. int getchx(void); //reads from operator_or_error_overread[] if it has anything, else uses getchar()
  7. void ungetchx(int); //stores argument in operator_or_error_overread[]
  8. double atofx(char[]); //converts the string op[] into a number
  9. void cleararray(char[], int);
  10.  
  11. int index = 0; //index of the stack of numbers
  12. double values[MAXARRAYSIZE]; //stack of numbers
  13.  
  14. char ungets_string[MAXARRAYSIZE]; //an array used to push back an entire line of numbers and operands onto the input
  15. int ungets_index = 0; //index of the ungets array
  16.  
  17. char operator_or_error_overread[MAXARRAYSIZE]; //stored overread characters: 1.2+ saves +, here. Then getc() reads from here first, instead of using getchar(). Also stores everything from ungets[], ungets 'u' pushes a string onto the input using this array that getc() reads from, instead of reading with getchar()
  18. int index_error = 0; //index of operator_or_error_overread[]
  19.  
  20.  
  21. main()
  22. {
  23. int operator; //variable for holding a number popped from the stack of numbers values[index]
  24. double operator2; //second variable for holding a number popped from the stack of numbers values[index]
  25. double temp; //variable for holding a value temporarily
  26. double temp2; //variable for holding a value temporarily
  27. char op[MAXARRAYSIZE]; //array used to store numbers that may be negative and floating-point. Used with atof to produce a number that is pushed onto values[index]
  28.  
  29. double a = 0; /* variables for holding values and a flag to indicate if they have been defined*/
  30. int a_def = NO;
  31. double b = 0;
  32. int b_def = NO;
  33. double x = 0;
  34. int x_def = NO;
  35. double y = 0;
  36. int y_def = NO;
  37. int undef = 0; /* variables for holding values and a flag to indicate if they have been defined*/
  38.  
  39. double mrp = 0.0; //most recently printed value
  40.  
  41. int placeholder = 0; //used for multiple ungets 'u' in one line of input
  42.  
  43. while ((operator = getop(op)) != EOF)
  44. {
  45. switch (operator) {
  46.  
  47.  
  48.  
  49. case 'a': /*define and undefine variables*/
  50. if (a_def == NO)
  51. {
  52. if (index > 0)
  53. a = pop(), a_def = YES;
  54. else
  55. a = 0;
  56. }
  57. else
  58. push(a);
  59. break;
  60. case 'b':
  61. if (b_def == NO)
  62. b = pop(), b_def = YES;
  63. else
  64. push(b);
  65. break;
  66. case 'x':
  67. if (x_def == NO)
  68. x = pop(), x_def = YES;
  69. else
  70. push(a);
  71. break;
  72. case 'y':
  73. if (y_def == NO)
  74. y = pop(), y_def = YES;
  75. else
  76. push(a);
  77. break;
  78. case 'z': //assuming appropriate usage //undefine variable
  79. undef = getchar();
  80. switch (undef) {
  81. case 'a':
  82. a_def = NO;
  83. break;
  84. case 'b':
  85. b_def = NO;
  86. break;
  87. case 'x':
  88. x_def = NO;
  89. break;
  90. case 'y':
  91. y_def = NO;
  92. break;
  93. default: printf("Error: The character after z is supposed to be a variable. The variable are a, b, x, and y. The correct syntax to undefine a variable is za, zb, zx, and zy.\n");
  94. break;
  95. }
  96. break; /*define and undefine variables*/
  97.  
  98.  
  99.  
  100. case NUMBER:
  101. push(atof(op));
  102. break;
  103. case '+':
  104. push(pop() + pop());
  105. break;
  106. case '*':
  107. push(pop() * pop());
  108. break;
  109. case '-':
  110. operator2 = pop();
  111. push(pop() - operator2);
  112. break;
  113. case '/':
  114. operator2 = pop();
  115. if (operator2 != 0.0)
  116. push(pop() / operator2);
  117. else
  118. printf("Error: Operator 2 is 0. Cannot divide by 0.\n");
  119. break;
  120. case '%':
  121. operator2 = pop();
  122. if (operator2 != 0)
  123. push((int)pop() % (int)operator2);
  124. else
  125. printf("Error: Operator 2 is 0. Cannot divide by 0.\n");
  126. break;
  127. case 'q':
  128. push(sin(pop()));
  129. break;
  130. case 'w':
  131. push(cos(pop()));
  132. break;
  133. case 'e':
  134. operator2 = pop();
  135. push(pow(pop(), operator2));
  136. break;
  137.  
  138.  
  139.  
  140. case 'm': //print mrp
  141. printf("%f\n", mrp);
  142. break;
  143. case 'p': //print topmost value in stack values[]
  144. temp = pop();
  145. push(temp);
  146. printf("%f", temp);
  147. break;
  148. case 'd': //duplicate topmost value in stack values[]
  149. temp = pop();
  150. push(temp);
  151. push(temp);
  152. break;
  153. case 's': //swap topmost two values in stack values[]
  154. temp = pop();
  155. temp2 = pop();
  156. push(temp);
  157. push(temp2);
  158. break;
  159. case 'c': //clear values[]
  160. cleararray(values, index);
  161. index = 0;
  162. break;
  163.  
  164.  
  165.  
  166. case 'u': //places everything before 'u' in the line of input where 'u' was
  167. printf("%s\n", ungets_string);
  168. placeholder = ungets_index;
  169. while (ungets_index >= 0)
  170. operator_or_error_overread[index_error++] = ungets_string[ungets_index--];
  171. ungets_index = placeholder;
  172. break;
  173. case 'r': //clears ungets_string[]
  174. printf("Cleared ungets_string[]: %s\n", ungets_string);
  175. cleararray(ungets_string, ungets_index);
  176. printf("Current ungets_string: %s\n", ungets_string);
  177. ungets_index = 0;
  178. break;
  179. case 'v':
  180. printf("%s\n", ungets_string);
  181. break;
  182.  
  183. case '\n': //prints the topmost value of values[], saves mrp
  184. mrp = pop();
  185. printf("\t%.8f\n", mrp);
  186. break;
  187. case '!': //end program
  188. goto terminate;
  189. break;
  190. default: //error
  191. printf("Error: The program read a character using getchar() that was not a digit or a character with a switch case defined. The character is %s.\n", op);
  192. break;
  193. }
  194. }
  195. terminate:
  196. return 0;
  197. }
  198.  
  199. void push(double OperandValue) //stores argument into stack values[], else full
  200. {
  201. if (index < MAXARRAYSIZE)
  202. values[index++] = OperandValue;
  203. else
  204. printf("Error: Stack full. Cannot push operand value %g.\n", OperandValue);
  205. }
  206. double pop(void) //returns topmost value of values[], else error
  207. {
  208. if (index > 0)
  209. return values[--index];
  210. else
  211. {
  212. printf("Error: There are 0 operands stored in the stack containing numbers.\n");
  213. return 0.0;
  214. }
  215. }
  216.  
  217. int getop(char s[]) //process characters and return to the switch with a number or a character
  218. {
  219. int c;
  220. int d = 0;
  221. int i = 0;
  222.  
  223. while ((s[i] = c = getchx()) == ' ' || c == '\t' || c == '\0') //skips white space by overwriting c into s[0] until an operand, operator, or error is read using getch() which reads an operand, operator, or error from getchar() overreading past any number onto a space or an operator 1.2+ or 1.2 .
  224. ;
  225.  
  226. if (s[i] != '\n' && s[i] != 'u')
  227. ungets_string[ungets_index++] = s[i]; //saves all characters into ungets_string[] that are not '\n' and 'u'. '\n' would create printing errors and 'u' would create infinite ungets operations
  228.  
  229. else if (s[i] == '\n' || s[i] == 'u')
  230. ungets_string[ungets_index++] = ' '; //spaces are used to avoid 'u' '\n' and '\0' repeating in ungets_string[].
  231.  
  232. i++; //increment op = s[i] to the next free space to save numbers and decimals
  233.  
  234. if (!isdigit(c) && c != '.' && c != '-') //saves character operand and returns character operand
  235. {
  236. return c;
  237. ungets_string[ungets_index++] = ' ';
  238. }
  239.  
  240. if (c == '-')
  241. d = getchx();
  242.  
  243. if (c == '-' && !isdigit(d)) //saves negative '-' character and return character '-'
  244. {
  245. ungetchx(d);
  246. ungets_string[ungets_index++] = ' ';
  247. return c;
  248. }
  249. else if (c == '-' && isdigit(d)) //saves first digit after '-'
  250. {
  251. s[i++] = d;
  252. ungets_string[ungets_index++] = d;
  253. }
  254.  
  255. if (isdigit((c = getchx()))) //saves number
  256. {
  257. ungets_string[ungets_index++] = s[i++] = c;
  258. while (isdigit(c = getchx()))
  259. ungets_string[ungets_index++] = s[i++] = c;
  260. }
  261.  
  262. if (c == '.') //saves decimals
  263. {
  264. ungets_string[ungets_index++] = s[i++] = c;
  265. while (isdigit(c = getchx()))
  266. ungets_string[ungets_index++] = s[i++] = c;
  267. }
  268.  
  269. if (c != EOF) //ungets the overread character: 1.2+, ungets +, saves 1.2 in op[].
  270. ungetchx(c);
  271.  
  272. s[i] = '\0';
  273. ungets_string[ungets_index++] = ' '; //spaces are used to avoid 'u' '\n' and '\0' repeating in ungets_string[].
  274.  
  275. return NUMBER;
  276. }
  277.  
  278. int getchx(void) //if there is a value in operator_or_error_overread[] read from it, else use getchar()
  279. {
  280. return (index_error > 0) ? operator_or_error_overread[--index_error] : getchar();
  281. }
  282. void ungetchx(int operator_or_error) //if there is space in operator_or_error_overread[] store operator_or_error, else error
  283. {
  284. if (index_error >= MAXARRAYSIZE)
  285. printf("Error: Stack full. Cannot push character.\n");
  286. else
  287. {
  288. if (operator_or_error == EOF)
  289. operator_or_error_overread[index_error++] = '0';
  290. else
  291. operator_or_error_overread[index_error++] = operator_or_error;
  292. }
  293. }
  294.  
  295. double atofx(char s[]) //convert string to floating-point number
  296. {
  297. int i = 0;
  298. int sign = 1;
  299. int val = 0;
  300. int power = 1;
  301. int e = 0;
  302. double exp = 0;
  303. if (s[i] == '-')
  304. {
  305. sign = -1;
  306. i++;
  307. }
  308. else if (s[i] == '+')
  309. i++;
  310. while (isdigit(s[i]))
  311. val = val * 10 + (s[i++] - '0');
  312. if (s[i] == '.')
  313. {
  314. i++;
  315. while (isdigit(s[i]))
  316. {
  317. val = val * 10 + (s[i++] - '0');
  318. power *= 10;
  319. }
  320. }
  321. val = sign * val / power;
  322. if (s[i] == 'e' || s[i] == 'E')
  323. {
  324. i++;
  325. if (s[i] == '-')
  326. {
  327. i++;
  328. while (isdigit(s[i])) //atoi
  329. e = e * 10 + (s[i] - '0');
  330. while (e-- > 0)
  331. val /= 10;
  332. return val;
  333. }
  334. else if (s[i] == '+')
  335. {
  336. i++;
  337. while (isdigit(s[i])) //atoi
  338. e = e * 10 + (s[i] - '0');
  339. while (e-- > 0)
  340. val *= 10;
  341. return val;
  342. }
  343. }
  344. else
  345. return val;
  346. }
  347.  
  348. void cleararray(char array[], int endofdata) //clear array
  349. {
  350. int i = 0;
  351. while (i <= endofdata)
  352. {
  353. array[i] = '\0';
  354. i++;
  355. }
  356. }
  357. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  358. while ((operator = getop(op)) != EOF)
  359. {
  360. switch (operator) {…
  361. }
  362. }
  363.  
  364.  
  365.  
  366. int getop(char s[]) //process characters and return to the switch with a number or a character
  367. {
  368. int c;
  369. int d = 0;
  370. int i = 0;
  371.  
  372. while ((s[i] = c = getchx()) == ' ' || c == '\t' || c == '\0') //skips white space by overwriting c into s[0] until an operand, operator, or error is read using getch() which reads an operand, operator, or error from getchar() overreading past any number onto a space or an operator 1.2+ or 1.2 .
  373. ;
  374.  
  375. if (s[i] != '\n' && s[i] != 'u')
  376. ungets_string[ungets_index++] = s[i]; //saves all characters into ungets_string[] that are not '\n' and 'u'. '\n' would create printing errors and 'u' would create infinite ungets operations
  377.  
  378. else if (s[i] == '\n' || s[i] == 'u')
  379. ungets_string[ungets_index++] = ' '; //spaces are used to avoid 'u' '\n' and '\0' repeating in ungets_string[].
  380.  
  381. i++; //increment op = s[i] to the next free space to save numbers and decimals
  382.  
  383. if (!isdigit(c) && c != '.' && c != '-') //saves character operand and returns character operand
  384. {
  385. return c;
  386. ungets_string[ungets_index++] = ' ';
  387. }
  388.  
  389. if (c == '-')
  390. d = getchx();
  391.  
  392. if (c == '-' && !isdigit(d)) //saves negative '-' character and return character '-'
  393. {
  394. ungetchx(d);
  395. ungets_string[ungets_index++] = ' ';
  396. return c;
  397. }
  398. else if (c == '-' && isdigit(d)) //saves first digit after '-'
  399. {
  400. s[i++] = d;
  401. ungets_string[ungets_index++] = d;
  402. }
  403.  
  404. if (isdigit((c = getchx()))) //saves number
  405. {
  406. ungets_string[ungets_index++] = s[i++] = c;
  407. while (isdigit(c = getchx()))
  408. ungets_string[ungets_index++] = s[i++] = c;
  409. }
  410.  
  411. if (c == '.') //saves decimals
  412. {
  413. ungets_string[ungets_index++] = s[i++] = c;
  414. while (isdigit(c = getchx()))
  415. ungets_string[ungets_index++] = s[i++] = c;
  416. }
  417.  
  418. if (c != EOF) //ungets the overread character: 1.2+, ungets +, saves 1.2 in op[].
  419. ungetchx(c);
  420.  
  421. s[i] = '\0';
  422. ungets_string[ungets_index++] = ' '; //spaces are used to avoid 'u' '\n' and '\0' repeating in ungets_string[].
  423.  
  424. return NUMBER;
  425. }
Advertisement
Add Comment
Please, Sign In to add comment