ChipMaster's bwBASIC This also includes history going back to v2.10. *WARN* some binary files might have been corrupted by CRLF.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1933 lines
46 KiB

  1. /****************************************************************
  2. bwb_ops.c Expression Parsing Operations
  3. for Bywater BASIC Interpreter
  4. Copyright (c) 1993, Ted A. Campbell
  5. Bywater Software
  6. email: tcamp@delphi.com
  7. Copyright and Permissions Information:
  8. All U.S. and international rights are claimed by the author,
  9. Ted A. Campbell.
  10. This software is released under the terms of the GNU General
  11. Public License (GPL), which is distributed with this software
  12. in the file "COPYING". The GPL specifies the terms under
  13. which users may copy and use the software in this distribution.
  14. A separate license is available for commercial distribution,
  15. for information on which you should contact the author.
  16. ****************************************************************/
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <math.h>
  20. #include "bwbasic.h"
  21. #include "bwb_mes.h"
  22. /* declarations for functions visible in this file only */
  23. #if ANSI_C
  24. static int op_oplevel( int level );
  25. static int op_add( int level, int precision );
  26. static int op_subtract( int level, int precision );
  27. static int op_multiply( int level, int precision );
  28. static int op_divide( int level, int precision );
  29. static int op_assign( int level, int precision );
  30. static int op_equals( int level, int precision );
  31. static int op_lessthan( int level, int precision );
  32. static int op_greaterthan( int level, int precision );
  33. static int op_lteq( int level, int precision );
  34. static int op_gteq( int level, int precision );
  35. static int op_notequal( int level, int precision );
  36. static int op_modulus( int level, int precision );
  37. static int op_exponent( int level, int precision );
  38. static int op_intdiv( int level, int precision );
  39. static int op_or( int level, int precision );
  40. static int op_and( int level, int precision );
  41. static int op_not( int level, int precision );
  42. static int op_xor( int level, int precision );
  43. static int op_islevelstr( int level );
  44. static int op_getprecision( int level );
  45. static int op_isoperator( int operation );
  46. static int op_pulldown( int how_far );
  47. #else
  48. static int op_oplevel();
  49. static int op_add();
  50. static int op_subtract();
  51. static int op_multiply();
  52. static int op_divide();
  53. static int op_assign();
  54. static int op_equals();
  55. static int op_lessthan();
  56. static int op_greaterthan();
  57. static int op_lteq();
  58. static int op_gteq();
  59. static int op_notequal();
  60. static int op_modulus();
  61. static int op_exponent();
  62. static int op_intdiv();
  63. static int op_or();
  64. static int op_and();
  65. static int op_not();
  66. static int op_xor();
  67. static int op_islevelstr();
  68. static int op_getprecision();
  69. static int op_isoperator();
  70. static int op_pulldown();
  71. #endif /* ANSI_C for prototypes */
  72. static int op_level;
  73. /***************************************************************
  74. FUNCTION: exp_operation()
  75. DESCRIPTION: This function performs whatever operations
  76. are necessary at the end of function bwb_exp()
  77. (i.e., the end of the parsing of an expression;
  78. see file bwb_exp.c).
  79. ***************************************************************/
  80. #if ANSI_C
  81. int
  82. exp_operation( int entry_level )
  83. #else
  84. int
  85. exp_operation( entry_level )
  86. int entry_level;
  87. #endif
  88. {
  89. register int precedence;
  90. int operator;
  91. #if INTENSIVE_DEBUG
  92. sprintf( bwb_ebuf, "in exp_operation(): entered function." );
  93. bwb_debug( bwb_ebuf );
  94. #endif
  95. /* cycle through all levels of precedence and perform required
  96. operations */
  97. for ( precedence = 0; precedence <= MAX_PRECEDENCE; ++precedence )
  98. {
  99. /* Operation loop: cycle through every level above entry level
  100. and perform required operations as needed */
  101. op_level = entry_level + 1;
  102. while( ( op_level < CURTASK expsc )
  103. && ( op_isoperator( CURTASK exps[ op_level ].operation ) == FALSE ))
  104. {
  105. ++op_level;
  106. }
  107. while ( ( op_level > entry_level ) && ( op_level < CURTASK expsc ) )
  108. {
  109. /* see if the operation at this level is an operator with the
  110. appropriate precedence level by running through the table
  111. of operators */
  112. for ( operator = 0; operator < N_OPERATORS; ++operator )
  113. {
  114. if ( exp_ops[ operator ].operation == CURTASK exps[ op_level ].operation )
  115. {
  116. /* check for appropriate level of precedence */
  117. if ( exp_ops[ operator ].precedence == precedence )
  118. {
  119. #if INTENSIVE_DEBUG
  120. sprintf( bwb_ebuf, "in exp_operation(): level <%d> operation <%d>",
  121. op_level, CURTASK exps[ op_level ].operation );
  122. bwb_debug( bwb_ebuf );
  123. #endif
  124. op_oplevel( op_level ); /* perform the operation */
  125. }
  126. }
  127. }
  128. /* advance level if appropriate; one must check, however, since
  129. the op_oplevel() function may have decremented CURTASK expsc */
  130. if ( op_level < CURTASK expsc )
  131. {
  132. ++op_level;
  133. #if INTENSIVE_DEBUG
  134. sprintf( bwb_ebuf, "in exp_operation() first increment op_level to <%d>",
  135. op_level );
  136. bwb_debug( bwb_ebuf );
  137. #endif
  138. while ( ( op_isoperator( CURTASK exps [ op_level ].operation ) == FALSE )
  139. && ( op_level < CURTASK expsc ) )
  140. {
  141. ++op_level;
  142. #if INTENSIVE_DEBUG
  143. sprintf( bwb_ebuf, "in exp_operation() further increment op_level to <%d>",
  144. op_level );
  145. bwb_debug( bwb_ebuf );
  146. #endif
  147. }
  148. } /* end of increment of op_level */
  149. } /* end of for loop for stack levels */
  150. } /* end of for loop for precedence levels */
  151. return TRUE;
  152. } /* end of function exp_operation() */
  153. /***************************************************************
  154. FUNCTION: op_oplevel()
  155. DESCRIPTION: This function performs a specific operation
  156. at a specific level as the expression parser
  157. resolves its arguments.
  158. ***************************************************************/
  159. #if ANSI_C
  160. static int
  161. op_oplevel( int level )
  162. #else
  163. static int
  164. op_oplevel( level )
  165. int level;
  166. #endif
  167. {
  168. int precision;
  169. /* set the precision */
  170. if ( ( precision = op_getprecision( level ) ) == OP_ERROR )
  171. {
  172. #if PROG_ERRORS
  173. sprintf( bwb_ebuf, "exp_operation(): failed to set precision." );
  174. bwb_error( bwb_ebuf );
  175. #else
  176. bwb_error( err_mismatch ); /*** ??? ***/
  177. #endif
  178. op_pulldown( 2 );
  179. }
  180. /* precision is set correctly */
  181. else
  182. {
  183. #if INTENSIVE_DEBUG
  184. sprintf( bwb_ebuf, "in op_oplevel(): level <%d>, precision <%c>",
  185. level, precision );
  186. bwb_debug( bwb_ebuf );
  187. #endif
  188. switch ( CURTASK exps[ level ].operation )
  189. {
  190. case OP_ADD:
  191. op_add( level, precision );
  192. break;
  193. case OP_SUBTRACT:
  194. op_subtract( level, precision );
  195. break;
  196. case OP_MULTIPLY:
  197. op_multiply( level, precision );
  198. break;
  199. case OP_DIVIDE:
  200. op_divide( level, precision );
  201. break;
  202. case OP_ASSIGN:
  203. op_assign( level, precision );
  204. break;
  205. case OP_EQUALS:
  206. op_equals( level, precision );
  207. break;
  208. case OP_LESSTHAN:
  209. op_lessthan( level, precision );
  210. break;
  211. case OP_GREATERTHAN:
  212. op_greaterthan( level, precision );
  213. break;
  214. case OP_LTEQ:
  215. op_lteq( level, precision );
  216. break;
  217. case OP_GTEQ:
  218. op_gteq( level, precision );
  219. break;
  220. case OP_NOTEQUAL:
  221. op_notequal( level, precision );
  222. break;
  223. case OP_MODULUS:
  224. op_modulus( level, precision );
  225. break;
  226. case OP_INTDIVISION:
  227. op_intdiv( level, precision );
  228. break;
  229. case OP_OR:
  230. op_or( level, precision );
  231. break;
  232. case OP_AND:
  233. op_and( level, precision );
  234. break;
  235. case OP_NOT:
  236. op_not( level, precision );
  237. break;
  238. case OP_XOR:
  239. op_xor( level, precision );
  240. break;
  241. case OP_EXPONENT:
  242. op_exponent( level, precision );
  243. break;
  244. default:
  245. #if PROG_ERRORS
  246. sprintf( bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported.", CURTASK exps[ level ].operation );
  247. op_pulldown( 2 );
  248. bwb_error( bwb_ebuf );
  249. #else
  250. bwb_error( err_syntax );
  251. #endif
  252. break;
  253. } /* end of case statement for operators */
  254. } /* end of else statement, precision set */
  255. return TRUE;
  256. } /* end of function op_oplevel() */
  257. /***************************************************************
  258. FUNCTION: op_isoperator()
  259. DESCRIPTION: This function detects whether its argument
  260. is an operator.
  261. ***************************************************************/
  262. #if ANSI_C
  263. static int
  264. op_isoperator( int operation )
  265. #else
  266. static int
  267. op_isoperator( operation )
  268. int operation;
  269. #endif
  270. {
  271. register int c;
  272. for( c = 0; c < N_OPERATORS; ++c )
  273. {
  274. if ( operation == exp_ops[ c ].operation )
  275. {
  276. #if INTENSIVE_DEBUG
  277. sprintf( bwb_ebuf, "in op_isoperator(): found match <%s>",
  278. exp_ops[ c ].symbol );
  279. bwb_debug( bwb_ebuf );
  280. #endif
  281. return TRUE;
  282. }
  283. }
  284. /* test failed; return FALSE */
  285. #if INTENSIVE_DEBUG
  286. sprintf( bwb_ebuf, "in op_isoperator(): no match found for operation <%d>",
  287. operation );
  288. bwb_debug( bwb_ebuf );
  289. #endif
  290. return FALSE;
  291. }
  292. /***************************************************************
  293. FUNCTION: op_add()
  294. DESCRIPTION: This function adds two numbers or
  295. concatenates two strings.
  296. ***************************************************************/
  297. #if ANSI_C
  298. static int
  299. op_add( int level, int precision )
  300. #else
  301. static int
  302. op_add( level, precision )
  303. int level;
  304. int precision;
  305. #endif
  306. {
  307. int error_condition;
  308. error_condition = FALSE;
  309. switch( precision )
  310. {
  311. case STRING:
  312. /* both sides of the operation should be strings for
  313. string addition; if not, report an error */
  314. if ( ( op_islevelstr( level - 1 ) != TRUE )
  315. || ( op_islevelstr( level + 1 ) != TRUE ) )
  316. {
  317. #if PROG_ERRORS
  318. sprintf( bwb_ebuf, "in op_add(): Type mismatch in string addition." );
  319. bwb_error( bwb_ebuf );
  320. #else
  321. bwb_error( err_mismatch );
  322. #endif
  323. error_condition = TRUE;
  324. }
  325. /* concatenate the two strings */
  326. if ( error_condition == FALSE )
  327. {
  328. #if INTENSIVE_DEBUG
  329. sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  330. level - 1, CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );
  331. bwb_debug( bwb_ebuf );
  332. exp_getsval( &( CURTASK exps[ level - 1 ] ));
  333. sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  334. level + 1, CURTASK exps[ level + 1 ].operation, CURTASK exps[ level + 1 ].type );
  335. bwb_debug( bwb_ebuf );
  336. exp_getsval( &( CURTASK exps[ level + 1 ] ));
  337. sprintf( bwb_ebuf, "in op_add(): string addition, exp_getsval()s completed" );
  338. bwb_debug( bwb_ebuf );
  339. #endif
  340. str_cat( exp_getsval( &( CURTASK exps[ level - 1 ] ) ),
  341. exp_getsval( &( CURTASK exps[ level + 1 ] ) ) );
  342. #if INTENSIVE_DEBUG
  343. sprintf( bwb_ebuf, "in op_add(): str_cat() returns <%d>-byte string to level <%d>",
  344. exp_getsval( &( CURTASK exps[ level - 1 ] ) )->length, level - 1 );
  345. bwb_debug( bwb_ebuf );
  346. #endif
  347. }
  348. break;
  349. case NUMBER:
  350. CURTASK exps[ level - 1 ].nval
  351. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  352. + exp_getnval( &( CURTASK exps[ level + 1 ] ));
  353. CURTASK exps[ level - 1 ].operation = NUMBER;
  354. break;
  355. }
  356. /* set variable to requested precision */
  357. CURTASK exps[ level - 1 ].type = (char) precision;
  358. #if INTENSIVE_DEBUG
  359. sprintf( bwb_ebuf, "in op_add() returns with operation <%d> type <%c>",
  360. CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );
  361. bwb_debug( bwb_ebuf );
  362. #endif
  363. /* decrement the stack twice */
  364. op_pulldown( 2 );
  365. return TRUE;
  366. }
  367. /***************************************************************
  368. FUNCTION: op_subtract()
  369. DESCRIPTION: This function subtracts the number on
  370. the left from the number on the right.
  371. ***************************************************************/
  372. #if ANSI_C
  373. static int
  374. op_subtract( int level, int precision )
  375. #else
  376. static int
  377. op_subtract( level, precision )
  378. int level;
  379. int precision;
  380. #endif
  381. {
  382. switch( precision )
  383. {
  384. case STRING:
  385. /* both sides of the operation should be numbers for
  386. string addition; if not, report an error */
  387. #if PROG_ERRORS
  388. sprintf( bwb_ebuf, "Strings cannot be subtracted." );
  389. bwb_error( bwb_ebuf );
  390. #else
  391. bwb_error( err_mismatch );
  392. #endif
  393. break;
  394. case NUMBER:
  395. CURTASK exps[ level - 1 ].nval
  396. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  397. - exp_getnval( &( CURTASK exps[ level + 1 ] ));
  398. break;
  399. }
  400. /* set variable to requested precision */
  401. CURTASK exps[ level - 1 ].type = (char) precision;
  402. CURTASK exps[ level - 1 ].operation = NUMBER;
  403. /* decrement the stack twice */
  404. op_pulldown( 2 );
  405. return TRUE;
  406. }
  407. /***************************************************************
  408. FUNCTION: op_multiply()
  409. DESCRIPTION: This function multiplies the number on
  410. the left by the number on the right.
  411. ***************************************************************/
  412. #if ANSI_C
  413. static int
  414. op_multiply( int level, int precision )
  415. #else
  416. static int
  417. op_multiply( level, precision )
  418. int level;
  419. int precision;
  420. #endif
  421. {
  422. switch( precision )
  423. {
  424. case STRING:
  425. /* both sides of the operation should be numbers for
  426. string addition; if not, report an error */
  427. #if PROG_ERRORS
  428. sprintf( bwb_ebuf, "Strings cannot be multiplied." );
  429. bwb_error( bwb_ebuf );
  430. #else
  431. bwb_error( err_mismatch );
  432. #endif
  433. break;
  434. case NUMBER:
  435. CURTASK exps[ level - 1 ].nval
  436. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  437. * exp_getnval( &( CURTASK exps[ level + 1 ] ));
  438. break;
  439. }
  440. /* set variable to requested precision */
  441. CURTASK exps[ level - 1 ].type = (char) precision;
  442. CURTASK exps[ level - 1 ].operation = NUMBER;
  443. /* decrement the stack twice */
  444. op_pulldown( 2 );
  445. return TRUE;
  446. }
  447. /***************************************************************
  448. FUNCTION: op_divide()
  449. DESCRIPTION: This function divides the number on
  450. the left by the number on the right.
  451. ***************************************************************/
  452. #if ANSI_C
  453. static int
  454. op_divide( int level, int precision )
  455. #else
  456. static int
  457. op_divide( level, precision )
  458. int level;
  459. int precision;
  460. #endif
  461. {
  462. switch( precision )
  463. {
  464. case STRING:
  465. /* both sides of the operation should be numbers for
  466. division; if not, report an error */
  467. #if PROG_ERRORS
  468. sprintf( bwb_ebuf, "Strings cannot be divided." );
  469. bwb_error( bwb_ebuf );
  470. #else
  471. bwb_error( err_mismatch );
  472. #endif
  473. break;
  474. case NUMBER:
  475. if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  476. == (bnumber) 0 )
  477. {
  478. CURTASK exps[ level - 1 ].nval = (bnumber) -1.0;
  479. op_pulldown( 2 );
  480. #if PROG_ERRORS
  481. sprintf( bwb_ebuf, "Divide by 0." );
  482. bwb_error( bwb_ebuf );
  483. #else
  484. bwb_error( err_dbz );
  485. #endif
  486. return FALSE;
  487. }
  488. CURTASK exps[ level - 1 ].nval
  489. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  490. / exp_getnval( &( CURTASK exps[ level + 1 ] ));
  491. break;
  492. }
  493. /* set variable to requested precision */
  494. CURTASK exps[ level - 1 ].type = (char) precision;
  495. CURTASK exps[ level - 1 ].operation = NUMBER;
  496. /* decrement the stack twice */
  497. op_pulldown( 2 );
  498. return TRUE;
  499. }
  500. /***************************************************************
  501. FUNCTION: op_assign()
  502. DESCRIPTION: This function assigns the value in the
  503. right hand side to the variable in the
  504. left hand side.
  505. ***************************************************************/
  506. #if ANSI_C
  507. static int
  508. op_assign( int level, int precision )
  509. #else
  510. static int
  511. op_assign( level, precision )
  512. int level;
  513. int precision;
  514. #endif
  515. {
  516. /* Make sure the position one level below is a variable */
  517. if ( CURTASK exps[ level - 1 ].operation != VARIABLE )
  518. {
  519. op_pulldown( 2 );
  520. #if PROG_ERRORS
  521. sprintf( bwb_ebuf, "in op_assign(): Assignment must be to variable: level -1 <%d> op <%d>",
  522. level - 1, CURTASK exps[ level - 1 ].operation );
  523. bwb_error( bwb_ebuf );
  524. #else
  525. bwb_error( err_syntax );
  526. #endif
  527. return FALSE;
  528. }
  529. #if INTENSIVE_DEBUG
  530. sprintf( bwb_ebuf, "in op_assign(): entered function level <%d>",
  531. level );
  532. bwb_debug( bwb_ebuf );
  533. #endif
  534. /* if the assignment is numerical, then the precision should be set
  535. to that of the variable on the left-hand side of the assignment */
  536. if ( precision != STRING )
  537. {
  538. precision = (int) CURTASK exps[ level - 1 ].type;
  539. }
  540. switch( precision )
  541. {
  542. case STRING:
  543. #if INTENSIVE_DEBUG
  544. sprintf( bwb_ebuf, "in op_assign(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  545. level - 1, CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );
  546. bwb_debug( bwb_ebuf );
  547. exp_getsval( &( CURTASK exps[ level - 1 ] ));
  548. sprintf( bwb_ebuf, "in op_assign(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  549. level + 1, CURTASK exps[ level + 1 ].operation, CURTASK exps[ level + 1 ].type );
  550. bwb_debug( bwb_ebuf );
  551. exp_getsval( &( CURTASK exps[ level + 1 ] ));
  552. sprintf( bwb_ebuf, "in op_assign(): string addition, exp_getsval()s completed" );
  553. bwb_debug( bwb_ebuf );
  554. #endif
  555. str_btob( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  556. exp_getsval( &( CURTASK exps[ level + 1 ] )) );
  557. break;
  558. case NUMBER:
  559. * var_findnval( CURTASK exps[ level - 1 ].xvar,
  560. #ifdef OLDWAY
  561. CURTASK exps[ level - 1 ].xvar->array_pos ) =
  562. #else
  563. CURTASK exps[ level - 1 ].array_pos ) =
  564. #endif
  565. CURTASK exps[ level - 1 ].nval =
  566. exp_getnval( &( CURTASK exps[ level + 1 ] ) );
  567. break;
  568. default:
  569. #if PROG_ERRORS
  570. sprintf( bwb_ebuf, "in op_assign(): Variable before assignment operator has unidentified type." );
  571. bwb_error( bwb_ebuf );
  572. #else
  573. bwb_error( err_mismatch );
  574. #endif
  575. return FALSE;
  576. }
  577. /* set variable to requested precision */
  578. CURTASK exps[ level - 1 ].type = (char) precision;
  579. /* decrement the stack twice */
  580. op_pulldown( 2 );
  581. return TRUE;
  582. }
  583. /***************************************************************
  584. FUNCTION: op_equals()
  585. DESCRIPTION: This function compares two values and
  586. returns an integer value: TRUE if they are
  587. the same and FALSE if they are not.
  588. ***************************************************************/
  589. #if ANSI_C
  590. static int
  591. op_equals( int level, int precision )
  592. #else
  593. static int
  594. op_equals( level, precision )
  595. int level;
  596. int precision;
  597. #endif
  598. {
  599. int error_condition;
  600. static bstring b;
  601. bstring *bp;
  602. error_condition = FALSE;
  603. b.rab = FALSE;
  604. switch( precision )
  605. {
  606. case STRING:
  607. /* both sides of the operation should be strings for
  608. string addition; if not, report an error */
  609. if ( ( op_islevelstr( level - 1 ) != TRUE )
  610. || ( op_islevelstr( level + 1 ) != TRUE ) )
  611. {
  612. #if PROG_ERRORS
  613. sprintf( bwb_ebuf, "in op_equals(): Type mismatch in string comparison." );
  614. bwb_error( bwb_ebuf );
  615. #else
  616. bwb_error( err_mismatch );
  617. #endif
  618. error_condition = TRUE;
  619. }
  620. /* compare the two strings */
  621. if ( error_condition == FALSE )
  622. {
  623. bp = exp_getsval( &( CURTASK exps[ level - 1 ] ));
  624. #if OLDWAY
  625. b.length = bp->length;
  626. b.sbuffer = bp->sbuffer;
  627. #endif
  628. str_btob( &b, bp );
  629. if ( str_cmp( &b,
  630. exp_getsval( &( CURTASK exps[ level + 1 ] )) ) == 0 )
  631. {
  632. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  633. }
  634. else
  635. {
  636. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  637. }
  638. }
  639. break;
  640. case NUMBER:
  641. if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  642. == exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  643. {
  644. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  645. }
  646. else
  647. {
  648. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  649. }
  650. break;
  651. }
  652. /* set variable to integer and operation to NUMBER:
  653. this must be done at the end, since at the beginning it
  654. might cause op_islevelstr() to return a false error */
  655. CURTASK exps[ level - 1 ].type = NUMBER;
  656. CURTASK exps[ level - 1 ].operation = NUMBER;
  657. /* decrement the stack */
  658. op_pulldown( 2 );
  659. return TRUE;
  660. }
  661. /***************************************************************
  662. FUNCTION: op_lessthan()
  663. DESCRIPTION: This function compares two values and
  664. returns an integer value: TRUE if the
  665. left hand value is less than the right,
  666. and FALSE if it is not.
  667. ***************************************************************/
  668. #if ANSI_C
  669. static int
  670. op_lessthan( int level, int precision )
  671. #else
  672. static int
  673. op_lessthan( level, precision )
  674. int level;
  675. int precision;
  676. #endif
  677. {
  678. int error_condition;
  679. error_condition = FALSE;
  680. switch( precision )
  681. {
  682. case STRING:
  683. /* both sides of the operation should be numbers for
  684. string addition; if not, report an error */
  685. if ( ( op_islevelstr( level - 1 ) != TRUE )
  686. || ( op_islevelstr( level + 1 ) != TRUE ) )
  687. {
  688. #if PROG_ERRORS
  689. sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  690. bwb_error( bwb_ebuf );
  691. #else
  692. bwb_error( err_mismatch );
  693. #endif
  694. error_condition = TRUE;
  695. }
  696. /* compare the two strings */
  697. if ( error_condition == FALSE )
  698. {
  699. if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  700. exp_getsval( &( CURTASK exps[ level + 1 ] )) ) < 0 )
  701. {
  702. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  703. }
  704. else
  705. {
  706. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  707. }
  708. }
  709. break;
  710. case NUMBER:
  711. if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  712. < exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  713. {
  714. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  715. }
  716. else
  717. {
  718. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  719. }
  720. break;
  721. }
  722. /* set variable to integer and operation to NUMBER:
  723. this must be done at the end, since at the beginning it
  724. might cause op_islevelstr() to return a false error */
  725. CURTASK exps[ level - 1 ].type = NUMBER;
  726. CURTASK exps[ level - 1 ].operation = NUMBER;
  727. /* decrement the stack */
  728. op_pulldown( 2 );
  729. return TRUE;
  730. }
  731. /***************************************************************
  732. FUNCTION: op_greaterthan()
  733. DESCRIPTION: This function compares two values and
  734. returns an integer value: TRUE if the
  735. left hand value is greater than the right,
  736. and FALSE if it is not.
  737. ***************************************************************/
  738. #if ANSI_C
  739. static int
  740. op_greaterthan( int level, int precision )
  741. #else
  742. static int
  743. op_greaterthan( level, precision )
  744. int level;
  745. int precision;
  746. #endif
  747. {
  748. int error_condition;
  749. error_condition = FALSE;
  750. switch( precision )
  751. {
  752. case STRING:
  753. /* both sides of the operation should be numbers for
  754. string addition; if not, report an error */
  755. if ( ( op_islevelstr( level - 1 ) != TRUE )
  756. || ( op_islevelstr( level + 1 ) != TRUE ) )
  757. {
  758. #if PROG_ERRORS
  759. sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  760. bwb_error( bwb_ebuf );
  761. #else
  762. bwb_error( err_mismatch );
  763. #endif
  764. error_condition = TRUE;
  765. }
  766. /* compare the two strings */
  767. if ( error_condition == FALSE )
  768. {
  769. if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  770. exp_getsval( &( CURTASK exps[ level + 1 ] )) ) > 0 )
  771. {
  772. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  773. }
  774. else
  775. {
  776. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  777. }
  778. }
  779. break;
  780. case NUMBER:
  781. if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  782. > exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  783. {
  784. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  785. }
  786. else
  787. {
  788. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  789. }
  790. break;
  791. }
  792. /* set variable to integer and operation to NUMBER:
  793. this must be done at the end, since at the beginning it
  794. might cause op_islevelstr() to return a false error */
  795. CURTASK exps[ level - 1 ].type = NUMBER;
  796. CURTASK exps[ level - 1 ].operation = NUMBER;
  797. /* decrement the stack */
  798. op_pulldown( 2 );
  799. return TRUE;
  800. }
  801. /***************************************************************
  802. FUNCTION: op_lteq()
  803. DESCRIPTION: This function compares two values and
  804. returns an integer value: TRUE if the
  805. left hand value is less than or equal
  806. to the right, and FALSE if it is not.
  807. ***************************************************************/
  808. #if ANSI_C
  809. static int
  810. op_lteq( int level, int precision )
  811. #else
  812. static int
  813. op_lteq( level, precision )
  814. int level;
  815. int precision;
  816. #endif
  817. {
  818. int error_condition;
  819. error_condition = FALSE;
  820. switch( precision )
  821. {
  822. case STRING:
  823. /* both sides of the operation should be numbers for
  824. string addition; if not, report an error */
  825. if ( ( op_islevelstr( level - 1 ) != TRUE )
  826. || ( op_islevelstr( level + 1 ) != TRUE ) )
  827. {
  828. #if PROG_ERRORS
  829. sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  830. bwb_error( bwb_ebuf );
  831. #else
  832. bwb_error( err_mismatch );
  833. #endif
  834. error_condition = TRUE;
  835. }
  836. /* compare the two strings */
  837. if ( error_condition == FALSE )
  838. {
  839. if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  840. exp_getsval( &( CURTASK exps[ level + 1 ] )) ) <= 0 )
  841. {
  842. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  843. }
  844. else
  845. {
  846. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  847. }
  848. }
  849. break;
  850. case NUMBER:
  851. if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  852. <= exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  853. {
  854. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  855. }
  856. else
  857. {
  858. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  859. }
  860. break;
  861. }
  862. /* set variable to integer and operation to NUMBER:
  863. this must be done at the end, since at the beginning it
  864. might cause op_islevelstr() to return a false error */
  865. CURTASK exps[ level - 1 ].type = NUMBER;
  866. CURTASK exps[ level - 1 ].operation = NUMBER;
  867. /* decrement the stack */
  868. op_pulldown( 2 );
  869. return TRUE;
  870. }
  871. /***************************************************************
  872. FUNCTION: op_gteq()
  873. DESCRIPTION: This function compares two values and
  874. returns an integer value: TRUE if the
  875. left hand value is greater than or equal
  876. to the right, and FALSE if it is not.
  877. ***************************************************************/
  878. #if ANSI_C
  879. static int
  880. op_gteq( int level, int precision )
  881. #else
  882. static int
  883. op_gteq( level, precision )
  884. int level;
  885. int precision;
  886. #endif
  887. {
  888. int error_condition;
  889. error_condition = FALSE;
  890. switch( precision )
  891. {
  892. case STRING:
  893. /* both sides of the operation should be numbers for
  894. string addition; if not, report an error */
  895. if ( ( op_islevelstr( level - 1 ) != TRUE )
  896. || ( op_islevelstr( level + 1 ) != TRUE ) )
  897. {
  898. #if PROG_ERRORS
  899. sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  900. bwb_error( bwb_ebuf );
  901. #else
  902. bwb_error( err_mismatch );
  903. #endif
  904. error_condition = TRUE;
  905. }
  906. /* compare the two strings */
  907. if ( error_condition == FALSE )
  908. {
  909. if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  910. exp_getsval( &( CURTASK exps[ level + 1 ] )) ) >= 0 )
  911. {
  912. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  913. }
  914. else
  915. {
  916. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  917. }
  918. }
  919. break;
  920. case NUMBER:
  921. if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  922. >= exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  923. {
  924. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  925. }
  926. else
  927. {
  928. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  929. }
  930. break;
  931. }
  932. /* set variable to integer and operation to NUMBER:
  933. this must be done at the end, since at the beginning it
  934. might cause op_islevelstr() to return a false error */
  935. CURTASK exps[ level - 1 ].type = NUMBER;
  936. CURTASK exps[ level - 1 ].operation = NUMBER;
  937. /* decrement the stack */
  938. op_pulldown( 2 );
  939. return TRUE;
  940. }
  941. /***************************************************************
  942. FUNCTION: op_notequal()
  943. DESCRIPTION: This function compares two values and
  944. returns an integer value: TRUE if they
  945. are not the same and FALSE if they are.
  946. ***************************************************************/
  947. #if ANSI_C
  948. static int
  949. op_notequal( int level, int precision )
  950. #else
  951. static int
  952. op_notequal( level, precision )
  953. int level;
  954. int precision;
  955. #endif
  956. {
  957. int error_condition;
  958. error_condition = FALSE;
  959. switch( precision )
  960. {
  961. case STRING:
  962. /* both sides of the operation should be numbers for
  963. string addition; if not, report an error */
  964. if ( ( op_islevelstr( level - 1 ) != TRUE )
  965. || ( op_islevelstr( level + 1 ) != TRUE ) )
  966. {
  967. #if PROG_ERRORS
  968. sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  969. bwb_error( bwb_ebuf );
  970. #else
  971. bwb_error( err_mismatch );
  972. #endif
  973. error_condition = TRUE;
  974. }
  975. /* compare the two strings */
  976. if ( error_condition == FALSE )
  977. {
  978. if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
  979. exp_getsval( &( CURTASK exps[ level + 1 ] )) ) != 0 )
  980. {
  981. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  982. }
  983. else
  984. {
  985. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  986. }
  987. }
  988. break;
  989. case NUMBER:
  990. if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
  991. != exp_getnval( &( CURTASK exps[ level + 1 ] )) )
  992. {
  993. CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
  994. }
  995. else
  996. {
  997. CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
  998. }
  999. break;
  1000. }
  1001. /* set variable to integer and operation to NUMBER:
  1002. this must be done at the end, since at the beginning it
  1003. might cause op_islevelstr() to return a false error */
  1004. CURTASK exps[ level - 1 ].type = NUMBER;
  1005. CURTASK exps[ level - 1 ].operation = NUMBER;
  1006. /* decrement the stack */
  1007. op_pulldown( 2 );
  1008. return TRUE;
  1009. }
  1010. /***************************************************************
  1011. FUNCTION: op_modulus()
  1012. DESCRIPTION: This function divides the number on
  1013. the left by the number on the right
  1014. and returns the remainder.
  1015. ***************************************************************/
  1016. #if ANSI_C
  1017. static int
  1018. op_modulus( int level, int precision )
  1019. #else
  1020. static int
  1021. op_modulus( level, precision )
  1022. int level;
  1023. int precision;
  1024. #endif
  1025. {
  1026. static double iportion;
  1027. switch( precision )
  1028. {
  1029. case STRING:
  1030. /* both sides of the operation should be numbers for
  1031. string addition; if not, report an error */
  1032. #if PROG_ERRORS
  1033. sprintf( bwb_ebuf, "Strings cannot be divided." );
  1034. bwb_error( bwb_ebuf );
  1035. #else
  1036. bwb_error( err_syntax );
  1037. #endif
  1038. break;
  1039. case NUMBER:
  1040. if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1041. == (bnumber) 0 )
  1042. {
  1043. CURTASK exps[ level - 1 ].nval = (bnumber) -1;
  1044. op_pulldown( 2 );
  1045. #if PROG_ERRORS
  1046. sprintf( bwb_ebuf, "Divide by 0." );
  1047. bwb_error( bwb_ebuf );
  1048. #else
  1049. bwb_error( err_dbz );
  1050. #endif
  1051. return FALSE;
  1052. }
  1053. CURTASK exps[ level ].nval
  1054. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1055. / exp_getnval( &( CURTASK exps[ level + 1 ] ));
  1056. modf( (double) CURTASK exps[ level ].nval, &iportion );
  1057. CURTASK exps[ level - 1 ].nval
  1058. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1059. - ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1060. * iportion );
  1061. break;
  1062. }
  1063. /* set variable to requested precision */
  1064. CURTASK exps[ level - 1 ].type = (char) precision;
  1065. CURTASK exps[ level - 1 ].operation = NUMBER;
  1066. /* decrement the stack twice */
  1067. op_pulldown( 2 );
  1068. return TRUE;
  1069. }
  1070. /***************************************************************
  1071. FUNCTION: op_exponent()
  1072. DESCRIPTION: This function finds the exponential value
  1073. of a number (on the left) to the power
  1074. indicated on the right-hand side.
  1075. ***************************************************************/
  1076. #if ANSI_C
  1077. static int
  1078. op_exponent( int level, int precision )
  1079. #else
  1080. static int
  1081. op_exponent( level, precision )
  1082. int level;
  1083. int precision;
  1084. #endif
  1085. {
  1086. #if INTENSIVE_DEBUG
  1087. sprintf( bwb_ebuf, "in op_exponent(): entered function level <%d>.",
  1088. level );
  1089. bwb_debug ( bwb_ebuf );
  1090. #endif
  1091. switch( precision )
  1092. {
  1093. case STRING:
  1094. /* both sides of the operation should be numbers for
  1095. string addition; if not, report an error */
  1096. #if PROG_ERRORS
  1097. sprintf( bwb_ebuf, "Strings cannot be taken as exponents." );
  1098. bwb_error( bwb_ebuf );
  1099. #else
  1100. bwb_error( err_mismatch );
  1101. #endif
  1102. break;
  1103. case NUMBER:
  1104. CURTASK exps[ level - 1 ].nval
  1105. = (bnumber) pow( (double) exp_getnval( &( CURTASK exps[ level - 1 ] )),
  1106. (double) exp_getnval( &( CURTASK exps[ level + 1 ] )) );
  1107. break;
  1108. }
  1109. /* set variable to requested precision */
  1110. CURTASK exps[ level - 1 ].type = (char) precision;
  1111. CURTASK exps[ level - 1 ].operation = NUMBER;
  1112. /* decrement the stack twice */
  1113. op_pulldown( 2 );
  1114. return TRUE;
  1115. }
  1116. /***************************************************************
  1117. FUNCTION: op_intdiv()
  1118. DESCRIPTION: This function divides the number on
  1119. the left by the number on the right,
  1120. returning the result as an integer.
  1121. ***************************************************************/
  1122. #if ANSI_C
  1123. static int
  1124. op_intdiv( int level, int precision )
  1125. #else
  1126. static int
  1127. op_intdiv( level, precision )
  1128. int level;
  1129. int precision;
  1130. #endif
  1131. {
  1132. switch( precision )
  1133. {
  1134. case STRING:
  1135. /* both sides of the operation should be numbers for
  1136. string addition; if not, report an error */
  1137. #if PROG_ERRORS
  1138. sprintf( bwb_ebuf, "Strings cannot be divided." );
  1139. bwb_error( bwb_ebuf );
  1140. #else
  1141. bwb_error( err_mismatch );
  1142. #endif
  1143. break;
  1144. default:
  1145. if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
  1146. == (bnumber) 0 )
  1147. {
  1148. CURTASK exps[ level - 1 ].nval = (bnumber) -1;
  1149. op_pulldown( 2 );
  1150. #if PROG_ERRORS
  1151. sprintf( bwb_ebuf, "Divide by 0." );
  1152. bwb_error( bwb_ebuf );
  1153. #else
  1154. bwb_error( err_dbz );
  1155. #endif
  1156. return FALSE;
  1157. }
  1158. CURTASK exps[ level - 1 ].nval
  1159. = exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1160. / exp_getnval( &( CURTASK exps[ level + 1 ] ));
  1161. break;
  1162. }
  1163. /* set variable to requested precision */
  1164. CURTASK exps[ level - 1 ].type = NUMBER;
  1165. CURTASK exps[ level - 1 ].operation = NUMBER;
  1166. /* decrement the stack twice */
  1167. op_pulldown( 2 );
  1168. return TRUE;
  1169. }
  1170. /***************************************************************
  1171. FUNCTION: op_or()
  1172. DESCRIPTION: This function compares two integers and
  1173. performs a logical NOT on them.
  1174. ***************************************************************/
  1175. #if ANSI_C
  1176. static int
  1177. op_or( int level, int precision )
  1178. #else
  1179. static int
  1180. op_or( level, precision )
  1181. int level;
  1182. int precision;
  1183. #endif
  1184. {
  1185. switch( precision )
  1186. {
  1187. case STRING:
  1188. /* both sides of the operation should be numbers for
  1189. logical comparison; if not, report an error */
  1190. #if PROG_ERRORS
  1191. sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1192. bwb_error( bwb_ebuf );
  1193. #else
  1194. bwb_error( err_mismatch );
  1195. #endif
  1196. break;
  1197. case NUMBER:
  1198. CURTASK exps[ level - 1 ].nval
  1199. = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1200. | (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
  1201. break;
  1202. }
  1203. /* set variable type to integer */
  1204. CURTASK exps[ level - 1 ].type = NUMBER;
  1205. CURTASK exps[ level - 1 ].operation = NUMBER;
  1206. /* decrement the stack twice */
  1207. op_pulldown( 2 );
  1208. return TRUE;
  1209. }
  1210. /***************************************************************
  1211. FUNCTION: op_and()
  1212. DESCRIPTION: This function compares two integers and
  1213. performs a logical NOT on them.
  1214. ***************************************************************/
  1215. #if ANSI_C
  1216. static int
  1217. op_and( int level, int precision )
  1218. #else
  1219. static int
  1220. op_and( level, precision )
  1221. int level;
  1222. int precision;
  1223. #endif
  1224. {
  1225. switch( precision )
  1226. {
  1227. case STRING:
  1228. /* both sides of the operation should be numbers for
  1229. logical comparison; if not, report an error */
  1230. #if PROG_ERRORS
  1231. sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1232. bwb_error( bwb_ebuf );
  1233. #else
  1234. bwb_error( err_mismatch );
  1235. #endif
  1236. break;
  1237. case NUMBER:
  1238. CURTASK exps[ level - 1 ].nval
  1239. = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1240. & (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
  1241. break;
  1242. }
  1243. /* set variable type to integer */
  1244. CURTASK exps[ level - 1 ].type = NUMBER;
  1245. CURTASK exps[ level - 1 ].operation = NUMBER;
  1246. /* decrement the stack twice */
  1247. op_pulldown( 2 );
  1248. return TRUE;
  1249. }
  1250. /***************************************************************
  1251. FUNCTION: op_not()
  1252. DESCRIPTION: This function compares two integers and
  1253. performs a logical NOT on them.
  1254. ***************************************************************/
  1255. #if ANSI_C
  1256. static int
  1257. op_not( int level, int precision )
  1258. #else
  1259. static int
  1260. op_not( level, precision )
  1261. int level;
  1262. int precision;
  1263. #endif
  1264. {
  1265. switch( precision )
  1266. {
  1267. case STRING:
  1268. /* both sides of the operation should be numbers for
  1269. logical comparison; if not, report an error */
  1270. #if PROG_ERRORS
  1271. sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1272. bwb_error( bwb_ebuf );
  1273. #else
  1274. bwb_error( err_mismatch );
  1275. #endif
  1276. break;
  1277. default:
  1278. #if INTENSIVE_DEBUG
  1279. sprintf( bwb_ebuf, "in op_not(): argument is <%d>, precision <%c>",
  1280. (unsigned int) exp_getnval( &( CURTASK exps[ level + 1 ] )), precision );
  1281. bwb_debug( bwb_ebuf );
  1282. #endif
  1283. CURTASK exps[ level ].nval = (bnumber)
  1284. ~( (int) exp_getnval( &( CURTASK exps[ level + 1 ] )) );
  1285. #if INTENSIVE_DEBUG
  1286. sprintf( bwb_ebuf, "in op_not(): result is <%d>, precision <%c>",
  1287. (int) r, precision );
  1288. bwb_debug( bwb_ebuf );
  1289. #endif
  1290. break;
  1291. }
  1292. /* set variable type to integer */
  1293. CURTASK exps[ level ].type = NUMBER;
  1294. CURTASK exps[ level ].operation = NUMBER;
  1295. /* decrement the stack once */
  1296. op_pulldown( 1 );
  1297. #if INTENSIVE_DEBUG
  1298. sprintf( bwb_ebuf, "in op_not(): CURTASK expsc <%d>, level <%d> result <%d>",
  1299. CURTASK expsc, level, CURTASK exps[ CURTASK expsc ].nval );
  1300. bwb_debug( bwb_ebuf );
  1301. #endif
  1302. return TRUE;
  1303. }
  1304. /***************************************************************
  1305. FUNCTION: op_xor()
  1306. DESCRIPTION: This function compares two integers and
  1307. performs a logical NOT on them.
  1308. ***************************************************************/
  1309. #if ANSI_C
  1310. static int
  1311. op_xor( int level, int precision )
  1312. #else
  1313. static int
  1314. op_xor( level, precision )
  1315. int level;
  1316. int precision;
  1317. #endif
  1318. {
  1319. switch( precision )
  1320. {
  1321. case STRING:
  1322. /* both sides of the operation should be numbers for
  1323. logical comparison; if not, report an error */
  1324. #if PROG_ERRORS
  1325. sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1326. bwb_error( bwb_ebuf );
  1327. #else
  1328. bwb_error( err_mismatch );
  1329. #endif
  1330. break;
  1331. case NUMBER:
  1332. CURTASK exps[ level - 1 ].nval
  1333. = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
  1334. ^ (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
  1335. break;
  1336. }
  1337. /* set variable type to integer */
  1338. CURTASK exps[ level - 1 ].type = NUMBER;
  1339. CURTASK exps[ level - 1 ].operation = NUMBER;
  1340. /* decrement the stack twice */
  1341. op_pulldown( 2 );
  1342. return TRUE;
  1343. }
  1344. /***************************************************************
  1345. FUNCTION: op_islevelstr()
  1346. DESCRIPTION: This function determines whether the
  1347. operation at a specified level involves a
  1348. string constant or variable.
  1349. ***************************************************************/
  1350. #if ANSI_C
  1351. static int
  1352. op_islevelstr( int level )
  1353. #else
  1354. static int
  1355. op_islevelstr( level )
  1356. int level;
  1357. #endif
  1358. {
  1359. /* first see if the level holds a string constant */
  1360. if ( CURTASK exps[ level ].operation == CONST_STRING )
  1361. {
  1362. #if INTENSIVE_DEBUG
  1363. sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
  1364. level );
  1365. bwb_debug( bwb_ebuf );
  1366. #endif
  1367. return TRUE;
  1368. }
  1369. /* see if the level holds a string variable */
  1370. if ( CURTASK exps[ level ].operation == VARIABLE )
  1371. {
  1372. if ( CURTASK exps[ level ].xvar->type == STRING )
  1373. {
  1374. #if INTENSIVE_DEBUG
  1375. sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
  1376. level );
  1377. bwb_debug( bwb_ebuf );
  1378. #endif
  1379. return TRUE;
  1380. }
  1381. }
  1382. /* test has failed, return FALSE */
  1383. #if INTENSIVE_DEBUG
  1384. sprintf( bwb_ebuf, "in op_islevelstr(): string not detected at level <%d>.",
  1385. level );
  1386. bwb_debug( bwb_ebuf );
  1387. #endif
  1388. return FALSE;
  1389. }
  1390. /***************************************************************
  1391. FUNCTION: op_getprecision()
  1392. DESCRIPTION: This function finds the precision for
  1393. an operation by comparing the precision
  1394. at this level and that two levels below.
  1395. ***************************************************************/
  1396. #if ANSI_C
  1397. static int
  1398. op_getprecision( int level )
  1399. #else
  1400. static int
  1401. op_getprecision( level )
  1402. int level;
  1403. #endif
  1404. {
  1405. /* first test for string value */
  1406. if ( ( CURTASK exps[ level + 1 ].type == STRING )
  1407. || ( CURTASK exps[ level - 1 ].type == STRING ) )
  1408. {
  1409. return STRING;
  1410. }
  1411. /* Both are numbers, so we should be able to find a suitable
  1412. precision level by starting with the top and moving down;
  1413. check first for double precision */
  1414. else
  1415. {
  1416. return NUMBER;
  1417. }
  1418. }
  1419. /***************************************************************
  1420. FUNCTION: op_pulldown()
  1421. DESCRIPTION: This function pulls the expression stack
  1422. down a specified number of levels, decrementing
  1423. the expression stack counter (bycalling dec_esc())
  1424. and decrementing the current "level" of operation
  1425. processing.
  1426. ***************************************************************/
  1427. #if ANSI_C
  1428. static int
  1429. op_pulldown( int how_far )
  1430. #else
  1431. static int
  1432. op_pulldown( how_far )
  1433. int how_far;
  1434. #endif
  1435. {
  1436. int level;
  1437. register int c;
  1438. #if INTENSIVE_DEBUG
  1439. sprintf( bwb_ebuf, "in op_pulldown(): pull down e stack <%d> place(s)",
  1440. how_far );
  1441. bwb_debug( bwb_ebuf );
  1442. #endif
  1443. /* first pull down the actual variables themselves */
  1444. level = op_level + ( 2 - how_far );
  1445. while ( CURTASK expsc >= ( level + how_far ) )
  1446. {
  1447. memcpy( &CURTASK exps[ level ], &CURTASK exps[ level + how_far ],
  1448. (size_t) ( sizeof( struct exp_ese )) );
  1449. ++level;
  1450. }
  1451. /* decrement the expression stack counter */
  1452. for ( c = 0; c < how_far; ++c )
  1453. {
  1454. if ( dec_esc() == TRUE )
  1455. {
  1456. --op_level;
  1457. }
  1458. else
  1459. {
  1460. return FALSE;
  1461. }
  1462. }
  1463. return TRUE;
  1464. }