expr.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. * Copyright (C) 2002 Gilead Kutnick - exophase@adelphia.net
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #include "expr.h"
  23. #include "string.h"
  24. #include "counter.h"
  25. #include "runrobot.h"
  26. #include <ctype.h>
  27. #include <stdlib.h>
  28. long int last_val;
  29. long int parse_expression(char far **expression, int &error, int id)
  30. {
  31. long int operand_val;
  32. int current_arg;
  33. long int c_operator;
  34. long int value;
  35. error = 0;
  36. // Skip initial whitespace..
  37. skip_whitespace(expression);
  38. value = parse_argument(expression, current_arg, id);
  39. if((current_arg != 0) && (current_arg != 2))
  40. {
  41. // First argument must be a value type.
  42. error = 1;
  43. return(-99);
  44. }
  45. skip_whitespace(expression);
  46. while(1)
  47. {
  48. if(**expression == ')')
  49. {
  50. // Close paren, safe to go.
  51. break;
  52. }
  53. c_operator = parse_argument(expression, current_arg, id);
  54. // Next arg must be an operator, unless it's a negative number,
  55. // in which case it's considered + num
  56. if(current_arg == 2)
  57. {
  58. value = evaluate_operation(value, 1, c_operator);
  59. }
  60. else
  61. {
  62. if(current_arg != 1)
  63. {
  64. error = 2;
  65. return(-100);
  66. }
  67. skip_whitespace(expression);
  68. operand_val = parse_argument(expression, current_arg, id);
  69. // And now it must be an integer.
  70. if((current_arg != 0) && (current_arg != 2))
  71. {
  72. error = 3;
  73. return(-102);
  74. }
  75. // Evaluate it.
  76. value = evaluate_operation(value, c_operator, operand_val);
  77. }
  78. skip_whitespace(expression);
  79. }
  80. last_val = value;
  81. return(value);
  82. }
  83. long int parse_argument(char far **argument, int &type, int id)
  84. {
  85. int first_char = **argument;
  86. // Test the first one.
  87. switch(first_char)
  88. {
  89. // Addition operator
  90. case '+':
  91. {
  92. type = 1;
  93. (*argument)++;
  94. return(1);
  95. }
  96. // Subtraction operator
  97. case '-':
  98. {
  99. (*argument)++;
  100. if(!isspace(**argument))
  101. {
  102. int t2;
  103. long int val = parse_argument(argument, t2, id);
  104. if((t2 == 0) || (t2 == 2))
  105. {
  106. val = -val;
  107. type = 2;
  108. return(val);
  109. }
  110. else
  111. {
  112. type = -1;
  113. return(-1);
  114. }
  115. }
  116. type = 1;
  117. return(2);
  118. }
  119. // Multiplication operator
  120. case '*':
  121. {
  122. type = 1;
  123. (*argument)++;
  124. return(3);
  125. }
  126. // Division operator
  127. case '/':
  128. {
  129. type = 1;
  130. (*argument)++;
  131. return(4);
  132. }
  133. // Modulus operator
  134. case '%':
  135. {
  136. type = 1;
  137. (*argument)++;
  138. return(5);
  139. }
  140. // Exponent operator
  141. case '^':
  142. {
  143. type = 1;
  144. (*argument)++;
  145. return(6);
  146. }
  147. // Bitwise AND operator
  148. case 'a':
  149. {
  150. type = 1;
  151. (*argument)++;
  152. return(7);
  153. }
  154. // Bitwise OR operator
  155. case 'o':
  156. {
  157. type = 1;
  158. (*argument)++;
  159. return(8);
  160. }
  161. // Bitwise XOR operator
  162. case 'x':
  163. {
  164. type = 1;
  165. (*argument)++;
  166. return(9);
  167. }
  168. // Less than/bitshift left
  169. case '<':
  170. {
  171. type = 1;
  172. (*argument)++;
  173. if(**argument == '<')
  174. {
  175. (*argument)++;
  176. return(10);
  177. }
  178. if(**argument == '=')
  179. {
  180. (*argument)++;
  181. return(14);
  182. }
  183. return(13);
  184. }
  185. // Greater than/bitshift right
  186. case '>':
  187. {
  188. type = 1;
  189. (*argument)++;
  190. if(**argument == '>')
  191. {
  192. (*argument)++;
  193. return(11);
  194. }
  195. if(**argument == '=')
  196. {
  197. (*argument)++;
  198. return(16);
  199. }
  200. return(15);
  201. }
  202. // Equality
  203. case '=':
  204. {
  205. type = 1;
  206. (*argument)++;
  207. return(12);
  208. }
  209. // Logical negation
  210. case '!':
  211. {
  212. type = 1;
  213. if(*(*argument + 1) == '=')
  214. {
  215. (*argument) += 2;
  216. return(17);
  217. }
  218. }
  219. // One's complement
  220. case '~':
  221. {
  222. (*argument)++;
  223. if(!isspace(**argument))
  224. {
  225. int t2;
  226. long int val = parse_argument(argument, t2, id);
  227. if((t2 == 0) || (t2 == 2))
  228. {
  229. val = ~val;
  230. type = 2;
  231. return(val);
  232. }
  233. else
  234. {
  235. type = -1;
  236. return(-1);
  237. }
  238. }
  239. }
  240. // # is the last expression value, 32bit.
  241. case '#':
  242. {
  243. type = 0;
  244. (*argument)++;
  245. return(last_val);
  246. }
  247. // The evil null terminator...
  248. case '\0':
  249. {
  250. type = -1;
  251. return(-1);
  252. }
  253. // Parentheses! Recursive goodness...
  254. // Treat a valid return as an argument.
  255. case '(':
  256. {
  257. int error;
  258. long int val;
  259. char far *a_ptr = (*argument) + 1;
  260. val = parse_expression(&a_ptr, error, id);
  261. if(error)
  262. {
  263. type = -1;
  264. return(-1);
  265. }
  266. else
  267. {
  268. *argument = a_ptr + 1;
  269. type = 0;
  270. return(val);
  271. }
  272. }
  273. // Begins with a ' or a & makes it a message ('counter')
  274. case '&':
  275. case '\'':
  276. {
  277. // Find where the next ' or & is
  278. char t_char = first_char;
  279. (*argument)++;
  280. int count = 0;
  281. char temp[80];
  282. char temp2[80];
  283. // Remember, null terminator is evil; if it's hit exit completely.
  284. while(((**argument) != t_char) && (count < 80))
  285. {
  286. // If a nested expression is hit closing 's should be ignored
  287. if((**argument) == '(')
  288. {
  289. int close_paren_count = 1;
  290. // The number of )'s to expect.. finding one decreases it..
  291. // And finding a ( increases it.
  292. while((close_paren_count) && (count < 80))
  293. {
  294. temp[count] = **argument;
  295. (*argument)++;
  296. count++;
  297. switch(**argument)
  298. {
  299. case '\0':
  300. {
  301. type = -1;
  302. return(-1);
  303. }
  304. case ')':
  305. {
  306. close_paren_count--;
  307. break;
  308. }
  309. case '(':
  310. {
  311. close_paren_count++;
  312. break;
  313. }
  314. }
  315. }
  316. }
  317. else
  318. {
  319. if(**argument == '\0')
  320. {
  321. type = -1;
  322. return(-1);
  323. }
  324. temp[count] = **argument;
  325. (*argument)++;
  326. count++;
  327. }
  328. }
  329. type = 0;
  330. (*argument)++;
  331. temp[count] = '\0';
  332. tr_msg(temp, id, temp2);
  333. return((long int)get_counter(temp2, id));
  334. }
  335. // Otherwise, it must be an integer, or just something invalid.
  336. default:
  337. {
  338. if((first_char >= '0') && (first_char <= '9'))
  339. {
  340. // It's good.
  341. char *end_p;
  342. long int val = strtol(*argument, &end_p, 0);
  343. *argument = end_p;
  344. type = 0;
  345. return(val);
  346. }
  347. else
  348. {
  349. // It's not so good..
  350. type = -1;
  351. return(-1);
  352. }
  353. }
  354. }
  355. }
  356. void skip_whitespace(char **expression)
  357. {
  358. while(isspace(**expression))
  359. {
  360. (*expression)++;
  361. }
  362. }
  363. long int evaluate_operation(long int operand_a, int c_operator,
  364. long int operand_b)
  365. {
  366. switch(c_operator)
  367. {
  368. // Addition
  369. case 1:
  370. {
  371. return(operand_a + operand_b);
  372. }
  373. // Subtraction
  374. case 2:
  375. {
  376. return(operand_a - operand_b);
  377. }
  378. // Multiplication
  379. case 3:
  380. {
  381. return(operand_a * operand_b);
  382. }
  383. // Division
  384. case 4:
  385. {
  386. if(operand_b == 0)
  387. {
  388. return 0;
  389. }
  390. return(operand_a / operand_b);
  391. }
  392. // Modulo
  393. case 5:
  394. {
  395. return(operand_a % operand_b);
  396. }
  397. // Exponent
  398. case 6:
  399. {
  400. int i;
  401. long int val = 1;
  402. if(operand_a == 0)
  403. {
  404. return(0);
  405. }
  406. if(operand_a == 1)
  407. {
  408. return(1);
  409. }
  410. if(operand_b < 0)
  411. {
  412. if(operand_a == -1)
  413. {
  414. operand_b *= -1;
  415. }
  416. else
  417. {
  418. return(0);
  419. }
  420. }
  421. for(i = 0; i < operand_b; i++)
  422. {
  423. val *= operand_a;
  424. }
  425. return(val);
  426. }
  427. // Bitwise AND
  428. case 7:
  429. {
  430. return(operand_a & operand_b);
  431. }
  432. // Bitwise OR
  433. case 8:
  434. {
  435. return(operand_a | operand_b);
  436. }
  437. // Bitwise XOR
  438. case 9:
  439. {
  440. return(operand_a ^ operand_b);
  441. }
  442. // Logical bitshift left
  443. case 10:
  444. {
  445. return(operand_a << operand_b);
  446. }
  447. // Locical bitshift right
  448. case 11:
  449. {
  450. return((long unsigned int)(operand_a) >> operand_b);
  451. }
  452. // Equality
  453. case 12:
  454. {
  455. return(operand_a == operand_b);
  456. }
  457. // less than
  458. case 13:
  459. {
  460. return(operand_a < operand_b);
  461. }
  462. // less than or equal to
  463. case 14:
  464. {
  465. return(operand_a <= operand_b);
  466. }
  467. // greater than
  468. case 15:
  469. {
  470. return(operand_a > operand_b);
  471. }
  472. // greater than or equal to
  473. case 16:
  474. {
  475. return(operand_a >= operand_b);
  476. }
  477. // not equal to
  478. case 17:
  479. {
  480. return(operand_a != operand_b);
  481. }
  482. default:
  483. {
  484. return(operand_a);
  485. }
  486. }
  487. }