rmoronsv

Untitled

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