home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / bwbasic / part02 < prev    next >
Encoding:
Text File  |  1992-11-03  |  60.0 KB  |  2,232 lines

  1. Newsgroups: comp.sources.misc
  2. From: tcamp@acpub.duke.edu (Ted A. Campbell)
  3. Subject:  v33i038:  bwbasic - Bywater BASIC interpreter version 1.10, Part02/11
  4. Message-ID: <1992Nov5.035001.14688@sparky.imd.sterling.com>
  5. X-Md4-Signature: 21de9fc68d3a550e63e545c954aab183
  6. Date: Thu, 5 Nov 1992 03:50:01 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: tcamp@acpub.duke.edu (Ted A. Campbell)
  10. Posting-number: Volume 33, Issue 38
  11. Archive-name: bwbasic/part02
  12. Environment: ANSI-C
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  bwb_ops.c
  19. # Wrapped by kent@sparky on Wed Nov  4 21:34:22 1992
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 2 (of 11)."'
  23. if test -f 'bwb_ops.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'bwb_ops.c'\"
  25. else
  26.   echo shar: Extracting \"'bwb_ops.c'\" \(57586 characters\)
  27.   sed "s/^X//" >'bwb_ops.c' <<'END_OF_FILE'
  28. X/****************************************************************
  29. X
  30. X        bwb_ops.c       Expression Parsing Operations
  31. X                        for Bywater BASIC Interpreter
  32. X
  33. X                        Copyright (c) 1992, Ted A. Campbell
  34. X
  35. X                        Bywater Software
  36. X                        P. O. Box 4023
  37. X                        Duke Station
  38. X                        Durham, NC  27706
  39. X
  40. X                        email: tcamp@acpub.duke.edu
  41. X
  42. X        Copyright and Permissions Information:
  43. X
  44. X        All U.S. and international copyrights are claimed by the
  45. X        author. The author grants permission to use this code
  46. X        and software based on it under the following conditions:
  47. X        (a) in general, the code and software based upon it may be
  48. X        used by individuals and by non-profit organizations; (b) it
  49. X        may also be utilized by governmental agencies in any country,
  50. X        with the exception of military agencies; (c) the code and/or
  51. X        software based upon it may not be sold for a profit without
  52. X        an explicit and specific permission from the author, except
  53. X        that a minimal fee may be charged for media on which it is
  54. X        copied, and for copying and handling; (d) the code must be
  55. X        distributed in the form in which it has been released by the
  56. X        author; and (e) the code and software based upon it may not
  57. X        be used for illegal activities.
  58. X
  59. X****************************************************************/
  60. X
  61. X#include <stdio.h>
  62. X#include <stdlib.h>
  63. X#include <string.h>
  64. X#include <ctype.h>
  65. X#include <math.h>
  66. X
  67. X#include "bwbasic.h"
  68. X#include "bwb_mes.h"
  69. X
  70. X/* declarations for functions visible in this file only */
  71. X
  72. Xstatic int op_oplevel( int level );
  73. Xstatic int op_add( int level, int precision );
  74. Xstatic int op_subtract( int level, int precision );
  75. Xstatic int op_multiply( int level, int precision );
  76. Xstatic int op_divide( int level, int precision );
  77. Xstatic int op_assign( int level, int precision );
  78. Xstatic int op_equals( int level, int precision );
  79. Xstatic int op_lessthan( int level, int precision );
  80. Xstatic int op_greaterthan( int level, int precision );
  81. Xstatic int op_lteq( int level, int precision );
  82. Xstatic int op_gteq( int level, int precision );
  83. Xstatic int op_notequal( int level, int precision );
  84. Xstatic int op_modulus( int level, int precision );
  85. Xstatic int op_exponent( int level, int precision );
  86. Xstatic int op_intdiv( int level, int precision );
  87. Xstatic int op_or( int level, int precision );
  88. Xstatic int op_and( int level, int precision );
  89. Xstatic int op_not( int level, int precision );
  90. Xstatic int op_xor( int level, int precision );
  91. Xstatic int op_islevelstr( int level );
  92. Xstatic int op_getprecision( int level );
  93. Xstatic int op_isoperator( int operation );
  94. Xstatic int op_pulldown( int how_far );
  95. X
  96. Xstatic int op_level;
  97. X
  98. X/***************************************************************
  99. X
  100. X        FUNCTION:   exp_operation()
  101. X
  102. X        DESCRIPTION:  This function performs whatever operations
  103. X        are necessary at the end of function bwb_exp.
  104. X
  105. X***************************************************************/
  106. X
  107. Xint
  108. Xexp_operation( int entry_level )
  109. X   {
  110. X   register int precedence;
  111. X   int operator;
  112. X
  113. X   #if INTENSIVE_DEBUG
  114. X   sprintf( bwb_ebuf, "in exp_operation(): entered function." );
  115. X   bwb_debug( bwb_ebuf );
  116. X   #endif
  117. X
  118. X   /* cycle through all levels of precedence and perform required
  119. X      operations */
  120. X
  121. X   for ( precedence = 0; precedence <= MAX_PRECEDENCE; ++precedence )
  122. X      {
  123. X
  124. X      /* Operation loop: cycle through every level above entry level
  125. X         and perform required operations as needed */
  126. X
  127. X      op_level = entry_level + 1;
  128. X      while( ( op_level < exp_esc )
  129. X         && ( op_isoperator( exp_es[ op_level ].operation ) == FALSE ))
  130. X         {
  131. X         ++op_level;
  132. X         }
  133. X
  134. X      while ( ( op_level > entry_level ) && ( op_level < exp_esc ) )
  135. X         {
  136. X
  137. X         /* see if the operation at this level is an operator with the
  138. X            appropriate precedence level by running through the table
  139. X            of operators */
  140. X
  141. X         for ( operator = 0; operator < N_OPERATORS; ++operator )
  142. X            {
  143. X
  144. X            if ( exp_ops[ operator ].operation == exp_es[ op_level ].operation )
  145. X               {
  146. X
  147. X               /* check for appropriate level of precedence */
  148. X
  149. X               if ( exp_ops[ operator ].precedence == precedence )
  150. X                  {
  151. X
  152. X                  #if INTENSIVE_DEBUG
  153. X                  sprintf( bwb_ebuf, "in exp_operation(): level <%d> operation <%d>",
  154. X                     op_level, exp_es[ op_level ].operation );
  155. X                  bwb_debug( bwb_ebuf );
  156. X                  #endif
  157. X
  158. X                  op_oplevel( op_level );     /* perform the operation */
  159. X
  160. X                  }
  161. X               }
  162. X            }
  163. X
  164. X         /* advance level if appropriate; one must check, however, since
  165. X            the op_oplevel() function may have decremented exp_esc */
  166. X
  167. X         if ( op_level < exp_esc )
  168. X            {
  169. X            ++op_level;
  170. X
  171. X            #if INTENSIVE_DEBUG
  172. X            sprintf( bwb_ebuf, "in exp_operation() first increment op_level to <%d>",
  173. X               op_level );
  174. X            bwb_debug( bwb_ebuf );
  175. X            #endif
  176. X
  177. X            while ( ( op_isoperator( exp_es [ op_level ].operation ) == FALSE )
  178. X               && ( op_level < exp_esc ) )
  179. X               {
  180. X               ++op_level;
  181. X
  182. X               #if INTENSIVE_DEBUG
  183. X               sprintf( bwb_ebuf, "in exp_operation() further increment op_level to <%d>",
  184. X                  op_level );
  185. X               bwb_debug( bwb_ebuf );
  186. X               #endif
  187. X
  188. X               }
  189. X            }                           /* end of increment of op_level */
  190. X
  191. X         }                              /* end of for loop for stack levels */
  192. X
  193. X      }                                 /* end of for loop for precedence levels */
  194. X
  195. X   return TRUE;
  196. X
  197. X   }                                    /* end of function exp_operation() */
  198. X
  199. X
  200. X/***************************************************************
  201. X
  202. X        FUNCTION:   op_oplevel()
  203. X
  204. X        DESCRIPTION:  This function performs a specific operation
  205. X        at a specific level.
  206. X
  207. X***************************************************************/
  208. X
  209. Xint
  210. Xop_oplevel( int level )
  211. X   {
  212. X   int precision;
  213. X
  214. X   /* set the precision */
  215. X
  216. X   if ( ( precision = op_getprecision( level ) ) == OP_ERROR )
  217. X      {
  218. X      #if PROG_ERRORS
  219. X      sprintf( bwb_ebuf, "exp_operation(): failed to set precision." );
  220. X      bwb_error( bwb_ebuf );
  221. X      #else
  222. X      bwb_error( err_mismatch );            /*** ??? ***/
  223. X      #endif
  224. X      op_pulldown( 2 );
  225. X      }
  226. X
  227. X   /* precision is set correctly */
  228. X
  229. X   else
  230. X      {
  231. X      #if INTENSIVE_DEBUG
  232. X      sprintf( bwb_ebuf, "in op_oplevel(): level <%d>, precision <%c>",
  233. X         level, precision );
  234. X      bwb_debug( bwb_ebuf );
  235. X      #endif
  236. X
  237. X      switch ( exp_es[ level ].operation )
  238. X         {
  239. X         case OP_ADD:
  240. X            op_add( level, precision );
  241. X            break;
  242. X
  243. X         case OP_SUBTRACT:
  244. X            op_subtract( level, precision );
  245. X            break;
  246. X
  247. X         case OP_MULTIPLY:
  248. X            op_multiply( level, precision );
  249. X            break;
  250. X
  251. X         case OP_DIVIDE:
  252. X            op_divide( level, precision );
  253. X            break;
  254. X
  255. X         case OP_ASSIGN:
  256. X            op_assign( level, precision );
  257. X            break;
  258. X
  259. X         case OP_EQUALS:
  260. X            op_equals( level, precision );
  261. X            break;
  262. X
  263. X         case OP_LESSTHAN:
  264. X            op_lessthan( level, precision );
  265. X            break;
  266. X
  267. X         case OP_GREATERTHAN:
  268. X            op_greaterthan( level, precision );
  269. X            break;
  270. X
  271. X         case OP_LTEQ:
  272. X            op_lteq( level, precision );
  273. X            break;
  274. X
  275. X         case OP_GTEQ:
  276. X            op_gteq( level, precision );
  277. X            break;
  278. X
  279. X         case OP_NOTEQUAL:
  280. X            op_notequal( level, precision );
  281. X            break;
  282. X
  283. X         case OP_MODULUS:
  284. X            op_modulus( level, precision );
  285. X            break;
  286. X
  287. X         case OP_INTDIVISION:
  288. X            op_intdiv( level, precision );
  289. X            break;
  290. X
  291. X         case OP_OR:
  292. X            op_or( level, precision );
  293. X            break;
  294. X
  295. X         case OP_AND:
  296. X            op_and( level, precision );
  297. X            break;
  298. X
  299. X         case OP_NOT:
  300. X            op_not( level, precision );
  301. X            break;
  302. X
  303. X         case OP_XOR:
  304. X            op_xor( level, precision );
  305. X            break;
  306. X
  307. X         case OP_EXPONENT:
  308. X            op_exponent( level, precision );
  309. X            break;
  310. X
  311. X         default:
  312. X            #if PROG_ERRORS
  313. X            sprintf( bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported." );
  314. X            op_pulldown( 2 );
  315. X            bwb_error( bwb_ebuf );
  316. X            #else
  317. X            bwb_error( err_syntax );
  318. X            #endif
  319. X            break;
  320. X         }                              /* end of case statement for operators */
  321. X      }                                 /* end of else statement, precision set */
  322. X
  323. X   return TRUE;
  324. X
  325. X   }                                    /* end of function op_oplevel() */
  326. X
  327. X/***************************************************************
  328. X
  329. X        FUNCTION:   op_isoperator()
  330. X
  331. X        DESCRIPTION:  This function detects whether its argument
  332. X        is an operator.
  333. X
  334. X***************************************************************/
  335. X
  336. Xint
  337. Xop_isoperator( int operation )
  338. X   {
  339. X   register int c;
  340. X
  341. X   for( c = 0; c < N_OPERATORS; ++c )
  342. X      {
  343. X      if ( operation == exp_ops[ c ].operation )
  344. X         {
  345. X
  346. X         #if INTENSIVE_DEBUG
  347. X         sprintf( bwb_ebuf, "in op_isoperator(): found match <%s>",
  348. X            exp_ops[ c ].symbol );
  349. X         bwb_debug( bwb_ebuf );
  350. X         #endif
  351. X
  352. X         return TRUE;
  353. X         }
  354. X      }
  355. X
  356. X   /* test failed; return FALSE */
  357. X
  358. X   #if INTENSIVE_DEBUG
  359. X   sprintf( bwb_ebuf, "in op_isoperator(): no match found for operation <%d>",
  360. X      operation );
  361. X   bwb_debug( bwb_ebuf );
  362. X   #endif
  363. X
  364. X   return FALSE;
  365. X
  366. X   }
  367. X
  368. X/***************************************************************
  369. X
  370. X        FUNCTION:   op_add()
  371. X
  372. X        DESCRIPTION:  This function adds two numbers or
  373. X        concatenates two strings.
  374. X
  375. X***************************************************************/
  376. X
  377. Xint
  378. Xop_add( int level, int precision )
  379. X   {
  380. X   int error_condition;
  381. X
  382. X   error_condition = FALSE;
  383. X
  384. X   switch( precision )
  385. X      {
  386. X      case STRING:
  387. X
  388. X         /* both sides of the operation should be strings for
  389. X            string addition; if not, report an error */
  390. X
  391. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  392. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  393. X            {
  394. X            #if PROG_ERRORS
  395. X            sprintf( bwb_ebuf, "in op_add(): Type mismatch in string addition." );
  396. X            bwb_error( bwb_ebuf );
  397. X            #else
  398. X            bwb_error( err_mismatch );
  399. X            #endif
  400. X            error_condition = TRUE;
  401. X            }
  402. X
  403. X         /* concatenate the two strings */
  404. X
  405. X         if ( error_condition == FALSE )
  406. X            {
  407. X
  408. X            #if INTENSIVE_DEBUG
  409. X            sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  410. X               level - 1, exp_es[ level - 1 ].operation, exp_es[ level - 1 ].type );
  411. X            bwb_debug( bwb_ebuf );
  412. X            exp_getsval( &( exp_es[ level - 1 ] ));
  413. X            sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  414. X               level + 1, exp_es[ level + 1 ].operation, exp_es[ level + 1 ].type );
  415. X            bwb_debug( bwb_ebuf );
  416. X            exp_getsval( &( exp_es[ level + 1 ] ));
  417. X            sprintf( bwb_ebuf, "in op_add(): string addition, exp_getsval()s completed" );
  418. X            bwb_debug( bwb_ebuf );
  419. X            #endif
  420. X
  421. X            str_cat( exp_getsval( &( exp_es[ level - 1 ] ) ), 
  422. X               exp_getsval( &( exp_es[ level + 1 ] ) ) );
  423. X            }
  424. X         exp_es[ level - 1 ].operation = CONST_STRING;
  425. X
  426. X         break;
  427. X
  428. X      case DOUBLE:
  429. X         exp_es[ level - 1 ].dval
  430. X            = exp_getdval( &( exp_es[ level - 1 ] ))
  431. X            + exp_getdval( &( exp_es[ level + 1 ] ));
  432. X         exp_es[ level - 1 ].operation = NUMBER;
  433. X         break;
  434. X
  435. X      case SINGLE:
  436. X
  437. X         #if INTENSIVE_DEBUG
  438. X         sprintf( bwb_ebuf, "in op_add(): single, (level <%d>) <%f> + <%f> (level <%d>",
  439. X            level - 1, exp_getfval( &( exp_es[ level - 1 ] )),
  440. X            exp_getfval( &( exp_es[ level + 1 ] )), level + 1 );
  441. X         bwb_debug( bwb_ebuf );
  442. X         #endif
  443. X
  444. X         exp_es[ level - 1 ].fval
  445. X            = exp_getfval( &( exp_es[ level - 1 ] ))
  446. X            + exp_getfval( &( exp_es[ level + 1 ] ));
  447. X
  448. X         #if INTENSIVE_DEBUG
  449. X         sprintf( bwb_ebuf, "in op_add(): single, = <%f>",
  450. X            exp_es[ level - 1 ].fval );
  451. X         bwb_debug( bwb_ebuf );
  452. X         #endif
  453. X
  454. X         exp_es[ level - 1 ].operation = NUMBER;
  455. X         break;
  456. X
  457. X      case INTEGER:
  458. X
  459. X         #if INTENSIVE_DEBUG
  460. X         sprintf( bwb_ebuf, "in op_add(): Integer precision." );
  461. X         bwb_debug ( bwb_ebuf );
  462. X         sprintf( bwb_ebuf, "in op_add(): precisions: lhs <%d> rhs <%d>.",
  463. X            exp_es[ level - 1 ].type,
  464. X            exp_es[ level + 1 ].type );
  465. X         bwb_debug ( bwb_ebuf );
  466. X         #endif
  467. X
  468. X         exp_es[ level - 1 ].ival
  469. X            = exp_getival( &( exp_es[ level - 1 ] ))
  470. X            + exp_getival( &( exp_es[ level + 1 ] ));
  471. X
  472. X         #if INTENSIVE_DEBUG
  473. X         sprintf( bwb_ebuf, "in op_add(): integer addition, result is <%d>",
  474. X            exp_es[ level - 1 ].ival );
  475. X         bwb_debug( bwb_ebuf );
  476. X         #endif
  477. X
  478. X         exp_es[ level - 1 ].operation = NUMBER;
  479. X         break;
  480. X      }
  481. X
  482. X   /* set variable to requested precision */
  483. X
  484. X   exp_es[ level - 1 ].type = (char) precision;
  485. X
  486. X   #if INTENSIVE_DEBUG
  487. X   sprintf( bwb_ebuf, "in op_add() returns with operation <%d> type <%c>",
  488. X      exp_es[ level - 1 ].operation, exp_es[ level - 1 ].type );
  489. X   bwb_debug( bwb_ebuf );
  490. X   #endif
  491. X
  492. X   /* decrement the stack twice */
  493. X
  494. X   op_pulldown( 2 );
  495. X
  496. X   return TRUE;
  497. X
  498. X   }
  499. X
  500. X/***************************************************************
  501. X
  502. X        FUNCTION:   op_subtract()
  503. X
  504. X        DESCRIPTION:  This function subtracts the number on
  505. X        the left from the number on the right.
  506. X
  507. X
  508. X***************************************************************/
  509. X
  510. Xint
  511. Xop_subtract( int level, int precision )
  512. X   {
  513. X
  514. X   switch( precision )
  515. X      {
  516. X      case STRING:
  517. X
  518. X         /* both sides of the operation should be numbers for
  519. X            string addition; if not, report an error */
  520. X
  521. X         #if PROG_ERRORS
  522. X         sprintf( bwb_ebuf, "Strings cannot be subtracted." );
  523. X         bwb_error( bwb_ebuf );
  524. X         #else
  525. X         bwb_error( err_mismatch );
  526. X         #endif
  527. X
  528. X         break;
  529. X
  530. X      case DOUBLE:
  531. X         exp_es[ level - 1 ].dval
  532. X            = exp_getdval( &( exp_es[ level - 1 ] ))
  533. X            - exp_getdval( &( exp_es[ level + 1 ] ));
  534. X         break;
  535. X
  536. X      case SINGLE:
  537. X
  538. X         #if INTENSIVE_DEBUG
  539. X         sprintf( bwb_ebuf, "in op_subtract(): Single precision." );
  540. X         bwb_debug ( bwb_ebuf );
  541. X         sprintf( bwb_ebuf, "in op_subtract(): precisions: lhs <%d> rhs <%d>.",
  542. X            exp_es[ level - 1 ].type,
  543. X            exp_es[ level + 1 ].type );
  544. X         bwb_debug ( bwb_ebuf );
  545. X         sprintf( bwb_ebuf, "in op_subtract(): values: lhs <%f> rhs <%f>.",
  546. X            exp_getfval( &( exp_es[ level - 1 ] )),
  547. X            exp_getfval( &( exp_es[ level + 1 ] )) );
  548. X         bwb_debug ( bwb_ebuf );
  549. X         #endif
  550. X
  551. X         exp_es[ level - 1 ].fval
  552. X            = exp_getfval( &( exp_es[ level - 1 ] ))
  553. X            - exp_getfval( &( exp_es[ level + 1 ] ));
  554. X
  555. X         #if INTENSIVE_DEBUG
  556. X         sprintf( bwb_ebuf, "in op_subtract(): SINGLE subtraction, result is <%f>",
  557. X            exp_es[ level - 1 ].fval );
  558. X         bwb_debug( bwb_ebuf );
  559. X         #endif
  560. X
  561. X         break;
  562. X
  563. X      case INTEGER:
  564. X
  565. X         #if INTENSIVE_DEBUG
  566. X         sprintf( bwb_ebuf, "in op_subtract(): Integer precision." );
  567. X         bwb_debug ( bwb_ebuf );
  568. X         sprintf( bwb_ebuf, "in op_subtract(): precisions: lhs <%d> rhs <%d>.",
  569. X            exp_es[ level - 1 ].type,
  570. X            exp_es[ level + 1 ].type );
  571. X         bwb_debug ( bwb_ebuf );
  572. X         #endif
  573. X
  574. X         exp_es[ level - 1 ].ival
  575. X            = exp_getival( &( exp_es[ level - 1 ] ))
  576. X            - exp_getival( &( exp_es[ level + 1 ] ));
  577. X
  578. X         #if INTENSIVE_DEBUG
  579. X         sprintf( bwb_ebuf, "in op_subtract(): integer subtraction, result is <%d>",
  580. X            exp_es[ level - 1 ].ival );
  581. X         bwb_debug( bwb_ebuf );
  582. X         #endif
  583. X
  584. X         break;
  585. X      }
  586. X
  587. X   /* set variable to requested precision */
  588. X
  589. X   exp_es[ level - 1 ].type = (char) precision;
  590. X   exp_es[ level - 1 ].operation = NUMBER;
  591. X
  592. X   /* decrement the stack twice */
  593. X
  594. X   op_pulldown( 2 );
  595. X
  596. X   return TRUE;
  597. X
  598. X   }
  599. X
  600. X/***************************************************************
  601. X
  602. X        FUNCTION:   op_multiply()
  603. X
  604. X        DESCRIPTION:  This function multiplies the number on
  605. X        the left from the number on the right.
  606. X
  607. X***************************************************************/
  608. X
  609. Xint
  610. Xop_multiply( int level, int precision )
  611. X   {
  612. X
  613. X   switch( precision )
  614. X      {
  615. X      case STRING:
  616. X
  617. X         /* both sides of the operation should be numbers for
  618. X            string addition; if not, report an error */
  619. X
  620. X         #if PROG_ERRORS
  621. X         sprintf( bwb_ebuf, "Strings cannot be multiplied." );
  622. X         bwb_error( bwb_ebuf );
  623. X         #else
  624. X         bwb_error( err_mismatch );
  625. X         #endif
  626. X
  627. X         break;
  628. X
  629. X      case DOUBLE:
  630. X         exp_es[ level - 1 ].dval
  631. X            = exp_getdval( &( exp_es[ level - 1 ] ))
  632. X            * exp_getdval( &( exp_es[ level + 1 ] ));
  633. X         break;
  634. X
  635. X      case SINGLE:
  636. X         exp_es[ level - 1 ].fval
  637. X            = exp_getfval( &( exp_es[ level - 1 ] ))
  638. X            * exp_getfval( &( exp_es[ level + 1 ] ));
  639. X         break;
  640. X
  641. X      case INTEGER:
  642. X         exp_es[ level - 1 ].ival
  643. X            = exp_getival( &( exp_es[ level - 1 ] ))
  644. X            * exp_getival( &( exp_es[ level + 1 ] ));
  645. X         break;
  646. X      }
  647. X
  648. X   /* set variable to requested precision */
  649. X
  650. X   exp_es[ level - 1 ].type = (char) precision;
  651. X   exp_es[ level - 1 ].operation = NUMBER;
  652. X
  653. X   /* decrement the stack twice */
  654. X
  655. X   op_pulldown( 2 );
  656. X
  657. X   return TRUE;
  658. X
  659. X   }
  660. X
  661. X/***************************************************************
  662. X
  663. X        FUNCTION:   op_divide()
  664. X
  665. X        DESCRIPTION:  This function divides the number on
  666. X        the left by the number on the right.
  667. X
  668. X***************************************************************/
  669. X
  670. Xint
  671. Xop_divide( int level, int precision )
  672. X   {
  673. X
  674. X   switch( precision )
  675. X      {
  676. X      case STRING:
  677. X
  678. X         /* both sides of the operation should be numbers for
  679. X            string addition; if not, report an error */
  680. X
  681. X         #if PROG_ERRORS
  682. X         sprintf( bwb_ebuf, "Strings cannot be divided." );
  683. X         bwb_error( bwb_ebuf );
  684. X         #else
  685. X         bwb_error( err_mismatch );
  686. X         #endif
  687. X
  688. X         break;
  689. X
  690. X      case DOUBLE:
  691. X         if ( exp_getdval( &( exp_es[ level + 1 ] ))
  692. X            == 0.0 )
  693. X            {
  694. X            exp_es[ level - 1 ].dval = -1.0;
  695. X            op_pulldown( 2 );
  696. X            #if PROG_ERRORS
  697. X            sprintf( bwb_ebuf, "Divide by 0." );
  698. X            bwb_error( bwb_ebuf );
  699. X            #else
  700. X            bwb_error( err_dbz );
  701. X            #endif
  702. X            return FALSE;
  703. X            }
  704. X         exp_es[ level - 1 ].dval
  705. X            = exp_getdval( &( exp_es[ level - 1 ] ))
  706. X            / exp_getdval( &( exp_es[ level + 1 ] ));
  707. X         break;
  708. X
  709. X      case SINGLE:
  710. X         if ( exp_getfval( &( exp_es[ level + 1 ] ))
  711. X            == (float) 0.0 )
  712. X            {
  713. X            exp_es[ level - 1 ].fval = (float) -1.0;
  714. X            op_pulldown( 2 );
  715. X            #if PROG_ERRORS
  716. X            sprintf( bwb_ebuf, "Divide by 0." );
  717. X            bwb_error( bwb_ebuf );
  718. X            #else
  719. X            bwb_error( err_dbz );
  720. X            #endif
  721. X            return FALSE;
  722. X            }
  723. X         exp_es[ level - 1 ].fval
  724. X            = exp_getfval( &( exp_es[ level - 1 ] ))
  725. X            / exp_getfval( &( exp_es[ level + 1 ] ));
  726. X         break;
  727. X
  728. X      case INTEGER:
  729. X         if ( exp_getival( &( exp_es[ level + 1 ] ))
  730. X            == 0 )
  731. X            {
  732. X            exp_es[ level - 1 ].ival = -1;
  733. X            op_pulldown( 2 );
  734. X            #if PROG_ERRORS
  735. X            sprintf( bwb_ebuf, "Divide by 0." );
  736. X            bwb_error( bwb_ebuf );
  737. X            #else
  738. X            bwb_error( err_dbz );
  739. X            #endif
  740. X            return FALSE;
  741. X            }
  742. X         exp_es[ level - 1 ].ival
  743. X            = exp_getival( &( exp_es[ level - 1 ] ))
  744. X            / exp_getival( &( exp_es[ level + 1 ] ));
  745. X         break;
  746. X      }
  747. X
  748. X   /* set variable to requested precision */
  749. X
  750. X   exp_es[ level - 1 ].type = (char) precision;
  751. X   exp_es[ level - 1 ].operation = NUMBER;
  752. X
  753. X   /* decrement the stack twice */
  754. X
  755. X   op_pulldown( 2 );
  756. X
  757. X   return TRUE;
  758. X
  759. X   }
  760. X
  761. X/***************************************************************
  762. X
  763. X        FUNCTION:   op_assign()
  764. X
  765. X        DESCRIPTION:  This function assigns the value in the
  766. X        right hand side to the variable in the left hand side.
  767. X
  768. X***************************************************************/
  769. X
  770. Xint
  771. Xop_assign( int level, int precision )
  772. X   {
  773. X   bstring *s, *d;
  774. X
  775. X   /* Make sure the position one level below is a variable */
  776. X
  777. X   if ( exp_es[ level - 1 ].operation != VARIABLE )
  778. X      {
  779. X      op_pulldown( 2 );
  780. X      #if PROG_ERRORS
  781. X      sprintf( bwb_ebuf, "in op_assign(): Assignment must be to variable: level -1 <%d> op <%d>",
  782. X         level - 1, exp_es[ level - 1 ].operation );
  783. X      bwb_error( bwb_ebuf );
  784. X      #else
  785. X      bwb_error( err_syntax );
  786. X      #endif
  787. X      return FALSE;
  788. X      }
  789. X
  790. X   #if INTENSIVE_DEBUG
  791. X   sprintf( bwb_ebuf, "in op_assign(): entered function level <%d>",
  792. X      level );
  793. X   bwb_debug( bwb_ebuf );
  794. X   #endif
  795. X
  796. X  /* if the assignment is numerical, then the precision should be set
  797. X     to that of the variable on the left-hand side of the assignment */
  798. X
  799. X   if ( precision != STRING )
  800. X      {
  801. X      precision = (int) exp_es[ level - 1 ].type;
  802. X      }
  803. X
  804. X   switch( precision )
  805. X      {
  806. X      case STRING:
  807. X
  808. X         #if INTENSIVE_DEBUG
  809. X         sprintf( bwb_ebuf, "in op_assign(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  810. X            level - 1, exp_es[ level - 1 ].operation, exp_es[ level - 1 ].type );
  811. X         bwb_debug( bwb_ebuf );
  812. X         exp_getsval( &( exp_es[ level - 1 ] ));
  813. X         sprintf( bwb_ebuf, "in op_assign(): try exp_getsval(), level <%d> op <%d> type <%c>:",
  814. X            level + 1, exp_es[ level + 1 ].operation, exp_es[ level + 1 ].type );
  815. X         bwb_debug( bwb_ebuf );
  816. X         exp_getsval( &( exp_es[ level + 1 ] ));
  817. X         sprintf( bwb_ebuf, "in op_assign(): string addition, exp_getsval()s completed" );
  818. X         bwb_debug( bwb_ebuf );
  819. X         #endif
  820. X
  821. X         str_btob( exp_getsval( &( exp_es[ level - 1 ] )),
  822. X                   exp_getsval( &( exp_es[ level + 1 ] )) );
  823. X         break;
  824. X
  825. X      case DOUBLE:
  826. X         * var_finddval( exp_es[ level - 1 ].xvar, 
  827. X            exp_es[ level - 1 ].xvar->array_pos )  = 
  828. X            exp_es[ level - 1 ].dval = 
  829. X            exp_getdval( &( exp_es[ level + 1 ] ) );
  830. X         break;
  831. X
  832. X      case SINGLE:
  833. X         * var_findfval( exp_es[ level - 1 ].xvar, 
  834. X            exp_es[ level - 1 ].xvar->array_pos )  = 
  835. X            exp_es[ level - 1 ].fval =
  836. X            exp_getfval( &( exp_es[ level + 1 ] ) );
  837. X         #if INTENSIVE_DEBUG
  838. X         sprintf( bwb_ebuf, "in op_assign(): SINGLE assignment var <%s> val <%f>",
  839. X            exp_es[ level - 1 ].xvar->name, exp_getfval( &( exp_es[ level - 1 ] )) );
  840. X         bwb_debug( bwb_ebuf );
  841. X         #endif
  842. X         break;
  843. X
  844. X      case INTEGER:
  845. X         * var_findival( exp_es[ level - 1 ].xvar, 
  846. X            exp_es[ level - 1 ].xvar->array_pos )  = 
  847. X            exp_es[ level - 1 ].ival =
  848. X            exp_getival( &( exp_es[ level + 1 ] ) );
  849. X         break;
  850. X
  851. X      default:
  852. X         #if PROG_ERRORS
  853. X         sprintf( bwb_ebuf, "in op_assign(): Variable before assignment operator has unidentified type." );
  854. X         bwb_error( bwb_ebuf );
  855. X         #else
  856. X         bwb_error( err_mismatch );
  857. X         #endif
  858. X         return FALSE;
  859. X
  860. X      }
  861. X
  862. X   /* set variable to requested precision */
  863. X
  864. X   exp_es[ level - 1 ].type = (char) precision;
  865. X
  866. X   /* decrement the stack twice */
  867. X
  868. X   op_pulldown( 2 );
  869. X
  870. X   return TRUE;
  871. X
  872. X   }
  873. X
  874. X/***************************************************************
  875. X
  876. X        FUNCTION:   op_equals()
  877. X
  878. X        DESCRIPTION:  This function compares two values and
  879. X        returns an integer value: TRUE if they are the same
  880. X        and FALSE if they are not.
  881. X
  882. X***************************************************************/
  883. X
  884. Xint
  885. Xop_equals( int level, int precision )
  886. X   {
  887. X   int error_condition;
  888. X   bstring b;
  889. X   bstring *bp;
  890. X
  891. X   error_condition = FALSE;
  892. X   b.rab = FALSE;
  893. X
  894. X   switch( precision )
  895. X      {
  896. X      case STRING:
  897. X
  898. X         /* both sides of the operation should be strings for
  899. X            string addition; if not, report an error */
  900. X
  901. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  902. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  903. X            {
  904. X            #if PROG_ERRORS
  905. X            sprintf( bwb_ebuf, "in op_equals(): Type mismatch in string comparison." );
  906. X            bwb_error( bwb_ebuf );
  907. X            #else
  908. X            bwb_error( err_mismatch );
  909. X            #endif
  910. X            error_condition = TRUE;
  911. X            }
  912. X
  913. X         /* compare the two strings */
  914. X
  915. X         if ( error_condition == FALSE )
  916. X            {
  917. X            bp = exp_getsval( &( exp_es[ level - 1 ] ));
  918. X            b.length = bp->length;
  919. X            b.buffer = bp->buffer;
  920. X            if ( str_cmp( &b,
  921. X               exp_getsval( &( exp_es[ level + 1 ] )) ) == 0 )
  922. X               {
  923. X               exp_es[ level - 1 ].ival = TRUE;
  924. X               }
  925. X            else
  926. X               {
  927. X               exp_es[ level - 1 ].ival = FALSE;
  928. X               }
  929. X            }
  930. X         break;
  931. X
  932. X      case DOUBLE:
  933. X         if ( exp_getdval( &( exp_es[ level - 1 ] ))
  934. X            == exp_getdval( &( exp_es[ level + 1 ] )) )
  935. X            {
  936. X
  937. X            exp_es[ level - 1 ].ival = TRUE;
  938. X            }
  939. X         else
  940. X            {
  941. X            exp_es[ level - 1 ].ival = FALSE;
  942. X            }
  943. X         break;
  944. X
  945. X      case SINGLE:
  946. X         if ( exp_getfval( &( exp_es[ level - 1 ] ))
  947. X            == exp_getfval( &( exp_es[ level + 1 ] )) )
  948. X            {
  949. X            exp_es[ level - 1 ].ival = TRUE;
  950. X            }
  951. X         else
  952. X            {
  953. X            exp_es[ level - 1 ].ival = FALSE;
  954. X            }
  955. X         break;
  956. X
  957. X      case INTEGER:
  958. X         if ( exp_getival( &( exp_es[ level - 1 ] ))
  959. X            == exp_getival( &( exp_es[ level + 1 ] )) )
  960. X            {
  961. X            exp_es[ level - 1 ].ival = TRUE;
  962. X            }
  963. X         else
  964. X            {
  965. X            exp_es[ level - 1 ].ival = FALSE;
  966. X            }
  967. X         break;
  968. X      }
  969. X
  970. X   /* set variable to integer and operation to NUMBER:
  971. X      this must be done at the end, since at the beginning it
  972. X      might cause op_islevelstr() to return a false error */
  973. X
  974. X   exp_es[ level - 1 ].type = INTEGER;
  975. X   exp_es[ level - 1 ].operation = NUMBER;
  976. X
  977. X   /* decrement the stack */
  978. X
  979. X   op_pulldown( 2 );
  980. X
  981. X   return TRUE;
  982. X
  983. X   }
  984. X
  985. X/***************************************************************
  986. X
  987. X        FUNCTION:   op_lessthan()
  988. X
  989. X        DESCRIPTION:  This function compares two values and
  990. X        returns an integer value: TRUE if the left hand value
  991. X        is less than the right, and FALSE if it is not.
  992. X
  993. X***************************************************************/
  994. X
  995. Xint
  996. Xop_lessthan( int level, int precision )
  997. X   {
  998. X   int error_condition;
  999. X
  1000. X   error_condition = FALSE;
  1001. X
  1002. X   switch( precision )
  1003. X      {
  1004. X      case STRING:
  1005. X
  1006. X         /* both sides of the operation should be numbers for
  1007. X            string addition; if not, report an error */
  1008. X
  1009. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1010. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1011. X            {
  1012. X            #if PROG_ERRORS
  1013. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1014. X            bwb_error( bwb_ebuf );
  1015. X            #else
  1016. X            bwb_error( err_mismatch );
  1017. X            #endif
  1018. X            error_condition = TRUE;
  1019. X            }
  1020. X
  1021. X         /* compare the two strings */
  1022. X
  1023. X         if ( error_condition == FALSE )
  1024. X            {
  1025. X            if ( str_cmp( exp_getsval( &( exp_es[ level - 1 ] )),
  1026. X               exp_getsval( &( exp_es[ level + 1 ] )) ) < 0 )
  1027. X               {
  1028. X               exp_es[ level - 1 ].ival = TRUE;
  1029. X               }
  1030. X            else
  1031. X               {
  1032. X               exp_es[ level - 1 ].ival = FALSE;
  1033. X               }
  1034. X            }
  1035. X         break;
  1036. X
  1037. X      case DOUBLE:
  1038. X         if ( exp_getdval( &( exp_es[ level - 1 ] ))
  1039. X            < exp_getdval( &( exp_es[ level + 1 ] )) )
  1040. X            {
  1041. X            exp_es[ level - 1 ].ival = TRUE;
  1042. X            }
  1043. X         else
  1044. X            {
  1045. X            exp_es[ level - 1 ].ival = FALSE;
  1046. X            }
  1047. X         break;
  1048. X
  1049. X      case SINGLE:
  1050. X         if ( exp_getfval( &( exp_es[ level - 1 ] ))
  1051. X            < exp_getfval( &( exp_es[ level + 1 ] )) )
  1052. X            {
  1053. X            exp_es[ level - 1 ].ival = TRUE;
  1054. X            }
  1055. X         else
  1056. X            {
  1057. X            exp_es[ level - 1 ].ival = FALSE;
  1058. X            }
  1059. X         break;
  1060. X
  1061. X      case INTEGER:
  1062. X         if ( exp_getival( &( exp_es[ level - 1 ] ))
  1063. X            < exp_getival( &( exp_es[ level + 1 ] )) )
  1064. X            {
  1065. X
  1066. X            exp_es[ level - 1 ].ival = TRUE;
  1067. X            }
  1068. X         else
  1069. X            {
  1070. X            exp_es[ level - 1 ].ival = FALSE;
  1071. X            }
  1072. X         break;
  1073. X      }
  1074. X
  1075. X   /* set variable to integer and operation to NUMBER:
  1076. X      this must be done at the end, since at the beginning it
  1077. X      might cause op_islevelstr() to return a false error */
  1078. X
  1079. X   exp_es[ level - 1 ].type = INTEGER;
  1080. X   exp_es[ level - 1 ].operation = NUMBER;
  1081. X
  1082. X   /* decrement the stack */
  1083. X
  1084. X   op_pulldown( 2 );
  1085. X
  1086. X   return TRUE;
  1087. X
  1088. X   }
  1089. X
  1090. X/***************************************************************
  1091. X
  1092. X        FUNCTION:   op_greaterthan()
  1093. X
  1094. X        DESCRIPTION:  This function compares two values and
  1095. X        returns an integer value: TRUE if the left hand value
  1096. X        is greater than the right, and FALSE if it is not.
  1097. X
  1098. X***************************************************************/
  1099. X
  1100. Xint
  1101. Xop_greaterthan( int level, int precision )
  1102. X   {
  1103. X   int error_condition;
  1104. X
  1105. X   error_condition = FALSE;
  1106. X
  1107. X   switch( precision )
  1108. X      {
  1109. X      case STRING:
  1110. X
  1111. X         /* both sides of the operation should be numbers for
  1112. X            string addition; if not, report an error */
  1113. X
  1114. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1115. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1116. X            {
  1117. X            #if PROG_ERRORS
  1118. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1119. X            bwb_error( bwb_ebuf );
  1120. X            #else
  1121. X            bwb_error( err_mismatch );
  1122. X            #endif
  1123. X            error_condition = TRUE;
  1124. X            }
  1125. X
  1126. X         /* compare the two strings */
  1127. X
  1128. X         if ( error_condition == FALSE )
  1129. X            {
  1130. X            if ( str_cmp( exp_getsval( &( exp_es[ level - 1 ] )),
  1131. X               exp_getsval( &( exp_es[ level + 1 ] )) ) > 0 )
  1132. X               {
  1133. X               exp_es[ level - 1 ].ival = TRUE;
  1134. X               }
  1135. X            else
  1136. X               {
  1137. X               exp_es[ level - 1 ].ival = FALSE;
  1138. X               }
  1139. X            }
  1140. X         break;
  1141. X
  1142. X      case DOUBLE:
  1143. X         if ( exp_getdval( &( exp_es[ level - 1 ] ))
  1144. X            > exp_getdval( &( exp_es[ level + 1 ] )) )
  1145. X            {
  1146. X            exp_es[ level - 1 ].ival = TRUE;
  1147. X            }
  1148. X         else
  1149. X            {
  1150. X            exp_es[ level - 1 ].ival = FALSE;
  1151. X            }
  1152. X         break;
  1153. X
  1154. X      case SINGLE:
  1155. X         if ( exp_getfval( &( exp_es[ level - 1 ] ))
  1156. X            > exp_getfval( &( exp_es[ level + 1 ] )) )
  1157. X            {
  1158. X            exp_es[ level - 1 ].ival = TRUE;
  1159. X            }
  1160. X         else
  1161. X            {
  1162. X            exp_es[ level - 1 ].ival = FALSE;
  1163. X            }
  1164. X         break;
  1165. X
  1166. X      case INTEGER:
  1167. X         if ( exp_getival( &( exp_es[ level - 1 ] ))
  1168. X            > exp_getival( &( exp_es[ level + 1 ] )) )
  1169. X            {
  1170. X            exp_es[ level - 1 ].ival = TRUE;
  1171. X            }
  1172. X         else
  1173. X            {
  1174. X            exp_es[ level - 1 ].ival = FALSE;
  1175. X            }
  1176. X         break;
  1177. X      }
  1178. X
  1179. X   /* set variable to integer and operation to NUMBER:
  1180. X      this must be done at the end, since at the beginning it
  1181. X      might cause op_islevelstr() to return a false error */
  1182. X
  1183. X   exp_es[ level - 1 ].type = INTEGER;
  1184. X   exp_es[ level - 1 ].operation = NUMBER;
  1185. X
  1186. X   /* decrement the stack */
  1187. X
  1188. X   op_pulldown( 2 );
  1189. X
  1190. X   return TRUE;
  1191. X
  1192. X   }
  1193. X
  1194. X/***************************************************************
  1195. X
  1196. X        FUNCTION:   op_lteq()
  1197. X
  1198. X        DESCRIPTION:  This function compares two values and
  1199. X        returns an integer value: TRUE if the left hand value
  1200. X        is less than or equal to the right, and FALSE if it is not.
  1201. X
  1202. X***************************************************************/
  1203. X
  1204. Xint
  1205. Xop_lteq( int level, int precision )
  1206. X   {
  1207. X   int error_condition;
  1208. X
  1209. X   error_condition = FALSE;
  1210. X
  1211. X   switch( precision )
  1212. X      {
  1213. X      case STRING:
  1214. X
  1215. X         /* both sides of the operation should be numbers for
  1216. X            string addition; if not, report an error */
  1217. X
  1218. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1219. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1220. X            {
  1221. X            #if PROG_ERRORS
  1222. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1223. X            bwb_error( bwb_ebuf );
  1224. X            #else
  1225. X            bwb_error( err_mismatch );
  1226. X            #endif
  1227. X            error_condition = TRUE;
  1228. X            }
  1229. X
  1230. X         /* compare the two strings */
  1231. X
  1232. X         if ( error_condition == FALSE )
  1233. X            {
  1234. X            if ( str_cmp( exp_getsval( &( exp_es[ level - 1 ] )),
  1235. X               exp_getsval( &( exp_es[ level + 1 ] )) ) <= 0 )
  1236. X               {
  1237. X               exp_es[ level - 1 ].ival = TRUE;
  1238. X               }
  1239. X            else
  1240. X               {
  1241. X               exp_es[ level - 1 ].ival = FALSE;
  1242. X               }
  1243. X            }
  1244. X         break;
  1245. X
  1246. X      case DOUBLE:
  1247. X         if ( exp_getdval( &( exp_es[ level - 1 ] ))
  1248. X            <= exp_getdval( &( exp_es[ level + 1 ] )) )
  1249. X            {
  1250. X            exp_es[ level - 1 ].ival = TRUE;
  1251. X            }
  1252. X         else
  1253. X            {
  1254. X            exp_es[ level - 1 ].ival = FALSE;
  1255. X            }
  1256. X         break;
  1257. X
  1258. X      case SINGLE:
  1259. X
  1260. X         if ( exp_getfval( &( exp_es[ level - 1 ] ))
  1261. X            <= exp_getfval( &( exp_es[ level + 1 ] )) )
  1262. X            {
  1263. X            exp_es[ level - 1 ].ival = TRUE;
  1264. X            }
  1265. X         else
  1266. X            {
  1267. X            exp_es[ level - 1 ].ival = FALSE;
  1268. X            }
  1269. X         break;
  1270. X
  1271. X      case INTEGER:
  1272. X         if ( exp_getival( &( exp_es[ level - 1 ] ))
  1273. X            <= exp_getival( &( exp_es[ level + 1 ] )) )
  1274. X            {
  1275. X            exp_es[ level - 1 ].ival = TRUE;
  1276. X            }
  1277. X         else
  1278. X            {
  1279. X            exp_es[ level - 1 ].ival = FALSE;
  1280. X            }
  1281. X         break;
  1282. X      }
  1283. X
  1284. X   /* set variable to integer and operation to NUMBER:
  1285. X      this must be done at the end, since at the beginning it
  1286. X      might cause op_islevelstr() to return a false error */
  1287. X
  1288. X   exp_es[ level - 1 ].type = INTEGER;
  1289. X   exp_es[ level - 1 ].operation = NUMBER;
  1290. X
  1291. X   /* decrement the stack */
  1292. X
  1293. X   op_pulldown( 2 );
  1294. X
  1295. X   return TRUE;
  1296. X
  1297. X   }
  1298. X
  1299. X/***************************************************************
  1300. X
  1301. X        FUNCTION:   op_gteq()
  1302. X
  1303. X        DESCRIPTION:  This function compares two values and
  1304. X        returns an integer value: TRUE if the left hand value
  1305. X        is greater than or equal to the right, and FALSE if
  1306. X        it is not.
  1307. X
  1308. X***************************************************************/
  1309. X
  1310. Xint
  1311. Xop_gteq( int level, int precision )
  1312. X   {
  1313. X   int error_condition;
  1314. X
  1315. X   error_condition = FALSE;
  1316. X
  1317. X   switch( precision )
  1318. X      {
  1319. X      case STRING:
  1320. X
  1321. X         /* both sides of the operation should be numbers for
  1322. X            string addition; if not, report an error */
  1323. X
  1324. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1325. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1326. X            {
  1327. X            #if PROG_ERRORS
  1328. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1329. X            bwb_error( bwb_ebuf );
  1330. X            #else
  1331. X            bwb_error( err_mismatch );
  1332. X            #endif
  1333. X            error_condition = TRUE;
  1334. X            }
  1335. X
  1336. X         /* compare the two strings */
  1337. X
  1338. X         if ( error_condition == FALSE )
  1339. X            {
  1340. X            if ( str_cmp( exp_getsval( &( exp_es[ level - 1 ] )),
  1341. X               exp_getsval( &( exp_es[ level + 1 ] )) ) >= 0 )
  1342. X               {
  1343. X               exp_es[ level - 1 ].ival = TRUE;
  1344. X               }
  1345. X            else
  1346. X               {
  1347. X               exp_es[ level - 1 ].ival = FALSE;
  1348. X               }
  1349. X            }
  1350. X         break;
  1351. X
  1352. X      case DOUBLE:
  1353. X         if ( exp_getdval( &( exp_es[ level - 1 ] ))
  1354. X            >= exp_getdval( &( exp_es[ level + 1 ] )) )
  1355. X            {
  1356. X            exp_es[ level - 1 ].ival = TRUE;
  1357. X            }
  1358. X         else
  1359. X            {
  1360. X            exp_es[ level - 1 ].ival = FALSE;
  1361. X            }
  1362. X         break;
  1363. X
  1364. X      case SINGLE:
  1365. X         if ( exp_getfval( &( exp_es[ level - 1 ] ))
  1366. X            >= exp_getfval( &( exp_es[ level + 1 ] )) )
  1367. X            {
  1368. X            exp_es[ level - 1 ].ival = TRUE;
  1369. X            }
  1370. X         else
  1371. X            {
  1372. X            exp_es[ level - 1 ].ival = FALSE;
  1373. X            }
  1374. X         break;
  1375. X
  1376. X      case INTEGER:
  1377. X         if ( exp_getival( &( exp_es[ level - 1 ] ))
  1378. X            >= exp_getival( &( exp_es[ level + 1 ] )) )
  1379. X            {
  1380. X            exp_es[ level - 1 ].ival = TRUE;
  1381. X            }
  1382. X         else
  1383. X            {
  1384. X            exp_es[ level - 1 ].ival = FALSE;
  1385. X            }
  1386. X         break;
  1387. X      }
  1388. X
  1389. X   /* set variable to integer and operation to NUMBER:
  1390. X      this must be done at the end, since at the beginning it
  1391. X      might cause op_islevelstr() to return a false error */
  1392. X
  1393. X   exp_es[ level - 1 ].type = INTEGER;
  1394. X   exp_es[ level - 1 ].operation = NUMBER;
  1395. X
  1396. X   /* decrement the stack */
  1397. X
  1398. X   op_pulldown( 2 );
  1399. X
  1400. X   return TRUE;
  1401. X
  1402. X   }
  1403. X
  1404. X/***************************************************************
  1405. X
  1406. X        FUNCTION:   op_notequal()
  1407. X
  1408. X        DESCRIPTION:  This function compares two values and
  1409. X        returns an integer value: TRUE if they are not the
  1410. X        same and FALSE if they are.
  1411. X
  1412. X***************************************************************/
  1413. X
  1414. Xint
  1415. Xop_notequal( int level, int precision )
  1416. X   {
  1417. X   int error_condition;
  1418. X
  1419. X   error_condition = FALSE;
  1420. X
  1421. X   switch( precision )
  1422. X      {
  1423. X      case STRING:
  1424. X
  1425. X         /* both sides of the operation should be numbers for
  1426. X            string addition; if not, report an error */
  1427. X
  1428. X         if (  ( op_islevelstr( level - 1 ) != TRUE )
  1429. X            || ( op_islevelstr( level + 1 ) != TRUE ) )
  1430. X            {
  1431. X            #if PROG_ERRORS
  1432. X            sprintf( bwb_ebuf, "Type mismatch in string comparison." );
  1433. X            bwb_error( bwb_ebuf );
  1434. X            #else
  1435. X            bwb_error( err_mismatch );
  1436. X            #endif
  1437. X            error_condition = TRUE;
  1438. X            }
  1439. X
  1440. X         /* compare the two strings */
  1441. X
  1442. X         if ( error_condition == FALSE )
  1443. X
  1444. X            {
  1445. X            if ( str_cmp( exp_getsval( &( exp_es[ level - 1 ] )),
  1446. X               exp_getsval( &( exp_es[ level + 1 ] )) ) != 0 )
  1447. X               {
  1448. X               exp_es[ level - 1 ].ival = TRUE;
  1449. X               }
  1450. X            else
  1451. X               {
  1452. X               exp_es[ level - 1 ].ival = FALSE;
  1453. X               }
  1454. X            }
  1455. X         break;
  1456. X
  1457. X      case DOUBLE:
  1458. X         if ( exp_getdval( &( exp_es[ level - 1 ] ))
  1459. X            != exp_getdval( &( exp_es[ level + 1 ] )) )
  1460. X            {
  1461. X            exp_es[ level - 1 ].ival = TRUE;
  1462. X            }
  1463. X         else
  1464. X            {
  1465. X            exp_es[ level - 1 ].ival = FALSE;
  1466. X            }
  1467. X         break;
  1468. X
  1469. X      case SINGLE:
  1470. X         if ( exp_getfval( &( exp_es[ level - 1 ] ))
  1471. X            != exp_getfval( &( exp_es[ level + 1 ] )) )
  1472. X            {
  1473. X            exp_es[ level - 1 ].ival = TRUE;
  1474. X            }
  1475. X         else
  1476. X            {
  1477. X            exp_es[ level - 1 ].ival = FALSE;
  1478. X            }
  1479. X         break;
  1480. X
  1481. X      case INTEGER:
  1482. X         if ( exp_getival( &( exp_es[ level - 1 ] ))
  1483. X            != exp_getival( &( exp_es[ level + 1 ] )) )
  1484. X            {
  1485. X            exp_es[ level - 1 ].ival = TRUE;
  1486. X            }
  1487. X         else
  1488. X            {
  1489. X            exp_es[ level - 1 ].ival = FALSE;
  1490. X            }
  1491. X         break;
  1492. X      }
  1493. X
  1494. X   /* set variable to integer and operation to NUMBER:
  1495. X      this must be done at the end, since at the beginning it
  1496. X      might cause op_islevelstr() to return a false error */
  1497. X
  1498. X   exp_es[ level - 1 ].type = INTEGER;
  1499. X   exp_es[ level - 1 ].operation = NUMBER;
  1500. X
  1501. X   /* decrement the stack */
  1502. X
  1503. X   op_pulldown( 2 );
  1504. X
  1505. X   return TRUE;
  1506. X
  1507. X   }
  1508. X
  1509. X/***************************************************************
  1510. X
  1511. X        FUNCTION:   op_modulus()
  1512. X
  1513. X        DESCRIPTION:  This function divides the number on
  1514. X        the left by the number on the right and return the
  1515. X        remainder.
  1516. X
  1517. X***************************************************************/
  1518. X
  1519. Xint
  1520. Xop_modulus( int level, int precision )
  1521. X   {
  1522. X   static double iportion;
  1523. X
  1524. X   switch( precision )
  1525. X      {
  1526. X      case STRING:
  1527. X
  1528. X         /* both sides of the operation should be numbers for
  1529. X            string addition; if not, report an error */
  1530. X
  1531. X         #if PROG_ERRORS
  1532. X         sprintf( bwb_ebuf, "Strings cannot be divided." );
  1533. X         bwb_error( bwb_ebuf );
  1534. X         #else
  1535. X         bwb_error( err_syntax );
  1536. X         #endif
  1537. X
  1538. X         break;
  1539. X
  1540. X      case DOUBLE:
  1541. X         if ( exp_getdval( &( exp_es[ level + 1 ] ))
  1542. X            == 0.0 )
  1543. X            {
  1544. X            exp_es[ level - 1 ].dval = -1.0;
  1545. X            op_pulldown( 2 );
  1546. X            #if PROG_ERRORS
  1547. X            sprintf( bwb_ebuf, "Divide by 0." );
  1548. X            bwb_error( bwb_ebuf );
  1549. X            #else
  1550. X            bwb_error( err_dbz );
  1551. X            #endif
  1552. X            return FALSE;
  1553. X            }
  1554. X         exp_es[ level ].dval
  1555. X            = exp_getdval( &( exp_es[ level - 1 ] ))
  1556. X            / exp_getdval( &( exp_es[ level + 1 ] ));
  1557. X         modf( exp_es[ level ].dval, &iportion );
  1558. X         exp_es[ level - 1 ].dval
  1559. X            = exp_getdval( &( exp_es[ level - 1 ] ))
  1560. X            - ( exp_getdval( &( exp_es[ level + 1 ] ))
  1561. X            * iportion );
  1562. X         break;
  1563. X
  1564. X      case SINGLE:
  1565. X         if ( exp_getfval( &( exp_es[ level + 1 ] ))
  1566. X            == (float) 0.0 )
  1567. X            {
  1568. X            exp_es[ level - 1 ].fval = (float) -1.0;
  1569. X            op_pulldown( 2 );
  1570. X            #if PROG_ERRORS
  1571. X            sprintf( bwb_ebuf, "Divide by 0." );
  1572. X            bwb_error( bwb_ebuf );
  1573. X            #else
  1574. X            bwb_error( err_dbz );
  1575. X            #endif
  1576. X            return FALSE;
  1577. X            }
  1578. X         exp_es[ level ].fval
  1579. X            = exp_getfval( &( exp_es[ level - 1 ] ))
  1580. X            / exp_getfval( &( exp_es[ level + 1 ] ));
  1581. X         modf( (double) exp_es[ level ].fval, &iportion );
  1582. X
  1583. X         #if INTENSIVE_DEBUG
  1584. X         sprintf( bwb_ebuf, "in op_modulus(): integer portion is %f",
  1585. X            iportion );
  1586. X         bwb_debug( bwb_ebuf );
  1587. X         #endif
  1588. X
  1589. X         exp_es[ level - 1 ].fval
  1590. X            = exp_getfval( &( exp_es[ level - 1 ] ))
  1591. X            - ( exp_getfval( &( exp_es[ level + 1 ] ))
  1592. X            * (float) iportion );
  1593. X         break;
  1594. X
  1595. X      case INTEGER:
  1596. X         if ( exp_getival( &( exp_es[ level + 1 ] ))
  1597. X            == 0 )
  1598. X            {
  1599. X            exp_es[ level - 1 ].ival = -1;
  1600. X            op_pulldown( 2 );
  1601. X
  1602. X            #if PROG_ERRORS
  1603. X            sprintf( bwb_ebuf, "Divide by 0." );
  1604. X            bwb_error( bwb_ebuf );
  1605. X            #else
  1606. X            bwb_error( err_dbz );
  1607. X            #endif
  1608. X            return FALSE;
  1609. X            }
  1610. X         exp_es[ level - 1 ].ival
  1611. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1612. X            % exp_getival( &( exp_es[ level + 1 ] ));
  1613. X         break;
  1614. X      }
  1615. X
  1616. X   /* set variable to requested precision */
  1617. X
  1618. X   exp_es[ level - 1 ].type = (char) precision;
  1619. X   exp_es[ level - 1 ].operation = NUMBER;
  1620. X
  1621. X   /* decrement the stack twice */
  1622. X
  1623. X   op_pulldown( 2 );
  1624. X
  1625. X   return TRUE;
  1626. X
  1627. X   }
  1628. X
  1629. X/***************************************************************
  1630. X
  1631. X        FUNCTION:   op_exponent()
  1632. X
  1633. X        DESCRIPTION:  This function divides the number on
  1634. X        the left by the number on the right and return the
  1635. X        remainder.
  1636. X
  1637. X***************************************************************/
  1638. X
  1639. Xint
  1640. Xop_exponent( int level, int precision )
  1641. X   {
  1642. X
  1643. X   #if INTENSIVE_DEBUG
  1644. X   sprintf( bwb_ebuf, "in op_exponent(): entered function level <%d>.",
  1645. X      level );
  1646. X   bwb_debug ( bwb_ebuf );
  1647. X   #endif
  1648. X
  1649. X   switch( precision )
  1650. X      {
  1651. X      case STRING:
  1652. X
  1653. X         /* both sides of the operation should be numbers for
  1654. X            string addition; if not, report an error */
  1655. X
  1656. X         #if PROG_ERRORS
  1657. X         sprintf( bwb_ebuf, "Strings cannot be taken as exponents." );
  1658. X         bwb_error( bwb_ebuf );
  1659. X         #else
  1660. X         bwb_error( err_mismatch );
  1661. X         #endif
  1662. X
  1663. X         break;
  1664. X
  1665. X      case DOUBLE:
  1666. X         exp_es[ level - 1 ].dval
  1667. X           = pow( exp_getdval( &( exp_es[ level - 1 ] )),
  1668. X                  exp_getdval( &( exp_es[ level + 1 ] )) );
  1669. X         break;
  1670. X
  1671. X      case SINGLE:
  1672. X         exp_es[ level - 1 ].fval
  1673. X           = (float) pow( exp_getdval( &( exp_es[ level - 1 ] )),
  1674. X                  exp_getdval( &( exp_es[ level + 1 ] )) );
  1675. X         break;
  1676. X
  1677. X      case INTEGER:
  1678. X
  1679. X         #if INTENSIVE_DEBUG
  1680. X         sprintf( bwb_ebuf, "in op_exponent(): Integer precision." );
  1681. X         bwb_debug ( bwb_ebuf );
  1682. X         sprintf( bwb_ebuf, "in op_exponent(): lhs <%f> rhs <%f>.",
  1683. X            exp_getdval( &( exp_es[ level - 1 ] )),
  1684. X            exp_getdval( &( exp_es[ level + 1 ] )) );
  1685. X         bwb_debug ( bwb_ebuf );
  1686. X         #endif
  1687. X
  1688. X         exp_es[ level - 1 ].ival
  1689. X           = (int) pow( exp_getdval( &( exp_es[ level - 1 ] )),
  1690. X                  exp_getdval( &( exp_es[ level + 1 ] )) );
  1691. X         break;
  1692. X      }
  1693. X
  1694. X   /* set variable to requested precision */
  1695. X
  1696. X   exp_es[ level - 1 ].type = (char) precision;
  1697. X   exp_es[ level - 1 ].operation = NUMBER;
  1698. X
  1699. X   /* decrement the stack twice */
  1700. X
  1701. X   op_pulldown( 2 );
  1702. X
  1703. X   return TRUE;
  1704. X
  1705. X   }
  1706. X
  1707. X/***************************************************************
  1708. X
  1709. X        FUNCTION:   op_intdiv()
  1710. X
  1711. X        DESCRIPTION:  This function divides the number on
  1712. X        the left by the number on the right and returns the
  1713. X        result as an integer.
  1714. X
  1715. X***************************************************************/
  1716. X
  1717. Xint
  1718. Xop_intdiv( int level, int precision )
  1719. X   {
  1720. X
  1721. X   switch( precision )
  1722. X      {
  1723. X      case STRING:
  1724. X
  1725. X         /* both sides of the operation should be numbers for
  1726. X            string addition; if not, report an error */
  1727. X
  1728. X         #if PROG_ERRORS
  1729. X         sprintf( bwb_ebuf, "Strings cannot be divided." );
  1730. X         bwb_error( bwb_ebuf );
  1731. X         #else
  1732. X         bwb_error( err_mismatch );
  1733. X         #endif
  1734. X
  1735. X         break;
  1736. X
  1737. X      default:
  1738. X         if ( exp_getival( &( exp_es[ level + 1 ] ))
  1739. X            == 0 )
  1740. X            {
  1741. X            exp_es[ level - 1 ].ival = -1;
  1742. X            op_pulldown( 2 );
  1743. X            #if PROG_ERRORS
  1744. X            sprintf( bwb_ebuf, "Divide by 0." );
  1745. X            bwb_error( bwb_ebuf );
  1746. X            #else
  1747. X            bwb_error( err_dbz );
  1748. X            #endif
  1749. X            return FALSE;
  1750. X            }
  1751. X
  1752. X         #if INTENSIVE_DEBUG
  1753. X         sprintf( bwb_ebuf, "in op_intdiv(): <%d> / <%d>",
  1754. X            exp_getival( &( exp_es[ level - 1 ] )),
  1755. X            exp_getival( &( exp_es[ level + 1 ] )) );
  1756. X         bwb_debug( bwb_ebuf );
  1757. X         #endif
  1758. X
  1759. X         exp_es[ level - 1 ].ival
  1760. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1761. X            / exp_getival( &( exp_es[ level + 1 ] ));
  1762. X         break;
  1763. X      }
  1764. X
  1765. X   /* set variable to requested precision */
  1766. X
  1767. X   exp_es[ level - 1 ].type = INTEGER;
  1768. X   exp_es[ level - 1 ].operation = NUMBER;
  1769. X
  1770. X   /* decrement the stack twice */
  1771. X
  1772. X   op_pulldown( 2 );
  1773. X
  1774. X   return TRUE;
  1775. X
  1776. X   }
  1777. X
  1778. X/***************************************************************
  1779. X
  1780. X        FUNCTION:   op_or()
  1781. X
  1782. X        DESCRIPTION:  This function compares two integers and
  1783. X        performs a logical NOT on them, returning the result
  1784. X        as an integer.
  1785. X
  1786. X***************************************************************/
  1787. X
  1788. Xint
  1789. Xop_or( int level, int precision )
  1790. X   {
  1791. X
  1792. X   switch( precision )
  1793. X      {
  1794. X      case STRING:
  1795. X
  1796. X         /* both sides of the operation should be numbers for
  1797. X            logical comparison; if not, report an error */
  1798. X
  1799. X         #if PROG_ERRORS
  1800. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1801. X         bwb_error( bwb_ebuf );
  1802. X         #else
  1803. X         bwb_error( err_mismatch );
  1804. X         #endif
  1805. X
  1806. X         break;
  1807. X
  1808. X      case DOUBLE:
  1809. X         exp_es[ level - 1 ].ival
  1810. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1811. X            | exp_getival( &( exp_es[ level + 1 ] ));
  1812. X         break;
  1813. X
  1814. X      case SINGLE:
  1815. X         exp_es[ level - 1 ].ival
  1816. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1817. X            | exp_getival( &( exp_es[ level + 1 ] ));
  1818. X         break;
  1819. X
  1820. X      case INTEGER:
  1821. X         exp_es[ level - 1 ].ival
  1822. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1823. X            | exp_getival( &( exp_es[ level + 1 ] ));
  1824. X         break;
  1825. X      }
  1826. X
  1827. X   /* set variable type to integer */
  1828. X
  1829. X   exp_es[ level - 1 ].type = INTEGER;
  1830. X   exp_es[ level - 1 ].operation = NUMBER;
  1831. X
  1832. X   /* decrement the stack twice */
  1833. X
  1834. X   op_pulldown( 2 );
  1835. X
  1836. X   return TRUE;
  1837. X
  1838. X   }
  1839. X
  1840. X/***************************************************************
  1841. X
  1842. X        FUNCTION:   op_and()
  1843. X
  1844. X        DESCRIPTION:  This function compares two integers and
  1845. X        performs a logical NOT on them, returning the result
  1846. X        as an integer.
  1847. X
  1848. X***************************************************************/
  1849. X
  1850. Xint
  1851. Xop_and( int level, int precision )
  1852. X   {
  1853. X
  1854. X   switch( precision )
  1855. X      {
  1856. X      case STRING:
  1857. X
  1858. X
  1859. X         /* both sides of the operation should be numbers for
  1860. X            logical comparison; if not, report an error */
  1861. X
  1862. X         #if PROG_ERRORS
  1863. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1864. X         bwb_error( bwb_ebuf );
  1865. X         #else
  1866. X         bwb_error( err_mismatch );
  1867. X         #endif
  1868. X
  1869. X         break;
  1870. X
  1871. X      case DOUBLE:
  1872. X         exp_es[ level - 1 ].ival
  1873. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1874. X            & exp_getival( &( exp_es[ level + 1 ] ));
  1875. X         break;
  1876. X
  1877. X      case SINGLE:
  1878. X         exp_es[ level - 1 ].ival
  1879. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1880. X            & exp_getival( &( exp_es[ level + 1 ] ));
  1881. X         break;
  1882. X
  1883. X      case INTEGER:
  1884. X         exp_es[ level - 1 ].ival
  1885. X            = exp_getival( &( exp_es[ level - 1 ] ))
  1886. X            & exp_getival( &( exp_es[ level + 1 ] ));
  1887. X         break;
  1888. X      }
  1889. X
  1890. X   /* set variable type to integer */
  1891. X
  1892. X   exp_es[ level - 1 ].type = INTEGER;
  1893. X   exp_es[ level - 1 ].operation = NUMBER;
  1894. X
  1895. X   /* decrement the stack twice */
  1896. X
  1897. X   op_pulldown( 2 );
  1898. X
  1899. X   return TRUE;
  1900. X
  1901. X   }
  1902. X
  1903. X/***************************************************************
  1904. X
  1905. X        FUNCTION:   op_not()
  1906. X
  1907. X        DESCRIPTION:  This function compares two integers and
  1908. X        performs a logical NOT on them, returning the result
  1909. X        as an integer.
  1910. X
  1911. X***************************************************************/
  1912. X
  1913. Xint
  1914. Xop_not( int level, int precision )
  1915. X   {
  1916. X   unsigned char r;
  1917. X
  1918. X   switch( precision )
  1919. X      {
  1920. X      case STRING:
  1921. X
  1922. X
  1923. X         /* both sides of the operation should be numbers for
  1924. X            logical comparison; if not, report an error */
  1925. X
  1926. X         #if PROG_ERRORS
  1927. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1928. X         bwb_error( bwb_ebuf );
  1929. X         #else
  1930. X         bwb_error( err_mismatch );
  1931. X         #endif
  1932. X
  1933. X         break;
  1934. X
  1935. X      default:
  1936. X
  1937. X         #if INTENSIVE_DEBUG
  1938. X         sprintf( bwb_ebuf, "in op_not(): argument is <%d>, precision <%c>",
  1939. X            (unsigned int) exp_getival( &( exp_es[ level + 1 ] )), precision );
  1940. X         bwb_debug( bwb_ebuf );
  1941. X         #endif
  1942. X
  1943. X         exp_es[ level ].ival =
  1944. X            ~( exp_getival( &( exp_es[ level + 1 ] )) );
  1945. X
  1946. X         #if INTENSIVE_DEBUG
  1947. X         sprintf( bwb_ebuf, "in op_not(): result is <%d>, precision <%c>",
  1948. X            (int) r, precision );
  1949. X         bwb_debug( bwb_ebuf );
  1950. X         #endif
  1951. X
  1952. X         break;
  1953. X      }
  1954. X
  1955. X   /* set variable type to integer */
  1956. X
  1957. X   exp_es[ level ].type = INTEGER;
  1958. X   exp_es[ level ].operation = NUMBER;
  1959. X
  1960. X   /* decrement the stack once */
  1961. X
  1962. X   op_pulldown( 1 );
  1963. X
  1964. X   #if INTENSIVE_DEBUG
  1965. X   sprintf( bwb_ebuf, "in op_not(): exp_esc <%d>, level <%d> result <%d>",
  1966. X      exp_esc, level, exp_es[ exp_esc ].ival );
  1967. X   bwb_debug( bwb_ebuf );
  1968. X   #endif
  1969. X
  1970. X   return TRUE;
  1971. X
  1972. X   }
  1973. X
  1974. X/***************************************************************
  1975. X
  1976. X        FUNCTION:   op_xor()
  1977. X
  1978. X        DESCRIPTION:  This function compares two integers and
  1979. X        performs a logical NOT on them, returning the result
  1980. X        as an integer.
  1981. X
  1982. X***************************************************************/
  1983. X
  1984. Xint
  1985. Xop_xor( int level, int precision )
  1986. X   {
  1987. X
  1988. X   switch( precision )
  1989. X      {
  1990. X      case STRING:
  1991. X
  1992. X         /* both sides of the operation should be numbers for
  1993. X            logical comparison; if not, report an error */
  1994. X
  1995. X         #if PROG_ERRORS
  1996. X         sprintf( bwb_ebuf, "Strings cannot be compared logically." );
  1997. X         bwb_error( bwb_ebuf );
  1998. X         #else
  1999. X         bwb_error( err_mismatch );
  2000. X         #endif
  2001. X
  2002. X         break;
  2003. X
  2004. X      case DOUBLE:
  2005. X         exp_es[ level - 1 ].ival
  2006. X            = exp_getival( &( exp_es[ level - 1 ] ))
  2007. X            ^ exp_getival( &( exp_es[ level + 1 ] ));
  2008. X         break;
  2009. X
  2010. X      case SINGLE:
  2011. X         exp_es[ level - 1 ].ival
  2012. X            = exp_getival( &( exp_es[ level - 1 ] ))
  2013. X            ^ exp_getival( &( exp_es[ level + 1 ] ));
  2014. X         break;
  2015. X
  2016. X      case INTEGER:
  2017. X         exp_es[ level - 1 ].ival   
  2018. X            = exp_getival( &( exp_es[ level - 1 ] ))
  2019. X            ^ exp_getival( &( exp_es[ level + 1 ] ));
  2020. X         break;
  2021. X      }
  2022. X
  2023. X   /* set variable type to integer */
  2024. X
  2025. X   exp_es[ level - 1 ].type = INTEGER;
  2026. X   exp_es[ level - 1 ].operation = NUMBER;
  2027. X
  2028. X   /* decrement the stack twice */
  2029. X
  2030. X   op_pulldown( 2 );
  2031. X
  2032. X   return TRUE;
  2033. X
  2034. X   }
  2035. X
  2036. X/***************************************************************
  2037. X
  2038. X        FUNCTION:   op_islevelstr()
  2039. X
  2040. X        DESCRIPTION:  This function determines whether the
  2041. X        operation at a specified level involves a string
  2042. X        constant or variable.
  2043. X
  2044. X***************************************************************/
  2045. X
  2046. Xint
  2047. Xop_islevelstr( int level )
  2048. X   {
  2049. X
  2050. X   /* first see if the level holds a string constant */
  2051. X
  2052. X   if ( exp_es[ level ].operation == CONST_STRING )
  2053. X      {
  2054. X
  2055. X      #if INTENSIVE_DEBUG
  2056. X      sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
  2057. X         level );
  2058. X      bwb_debug( bwb_ebuf );
  2059. X      #endif
  2060. X
  2061. X      return TRUE;
  2062. X      }
  2063. X
  2064. X   /* see if the level holds a string variable */
  2065. X
  2066. X   if ( exp_es[ level ].operation == VARIABLE )
  2067. X      {
  2068. X      if ( exp_es[ level ].xvar->type == STRING )
  2069. X         {
  2070. X
  2071. X         #if INTENSIVE_DEBUG
  2072. X         sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
  2073. X            level );
  2074. X         bwb_debug( bwb_ebuf );
  2075. X         #endif
  2076. X
  2077. X         return TRUE;
  2078. X         }
  2079. X      }
  2080. X
  2081. X   /* test has failed, return FALSE */
  2082. X
  2083. X   #if INTENSIVE_DEBUG
  2084. X   sprintf( bwb_ebuf, "in op_islevelstr(): string not detected at level <%d>.",
  2085. X      level );
  2086. X   bwb_debug( bwb_ebuf );
  2087. X   #endif
  2088. X
  2089. X   return FALSE;
  2090. X
  2091. X   }
  2092. X
  2093. X/***************************************************************
  2094. X
  2095. X        FUNCTION:   op_getprecision()
  2096. X
  2097. X        DESCRIPTION:  This function finds the precision for
  2098. X        an operation by comparing the precision at this level
  2099. X        and that two levels below.
  2100. X
  2101. X***************************************************************/
  2102. X
  2103. Xint
  2104. Xop_getprecision( int level )
  2105. X   {
  2106. X
  2107. X   /* first test for string value */
  2108. X
  2109. X   if (  ( exp_es[ level + 1 ].type == STRING )
  2110. X      || ( exp_es[ level - 1 ].type == STRING ) )
  2111. X      {
  2112. X      return STRING;
  2113. X      }
  2114. X
  2115. X   /* Both are numbers, so we should be able to find a suitable
  2116. X      precision level by starting with the top and moving down;
  2117. X      check first for double precision */
  2118. X
  2119. X   if (  ( exp_es[ level + 1 ].type == DOUBLE )
  2120. X      || ( exp_es[ level - 1 ].type == DOUBLE ) )
  2121. X      {
  2122. X      return DOUBLE;
  2123. X      }
  2124. X
  2125. X   /* check next for single precision */
  2126. X
  2127. X   if (  ( exp_es[ level + 1 ].type == SINGLE )
  2128. X      || ( exp_es[ level - 1 ].type == SINGLE ) )
  2129. X      {
  2130. X      return SINGLE;
  2131. X      }
  2132. X
  2133. X   /* test integer precision */
  2134. X
  2135. X   if (  ( exp_es[ level + 1 ].type == INTEGER )
  2136. X      && ( exp_es[ level - 1 ].type == INTEGER ) )
  2137. X      {
  2138. X      return INTEGER;
  2139. X      }
  2140. X
  2141. X   /* else error */
  2142. X
  2143. X   #if PROG_ERRORS
  2144. X   sprintf( bwb_ebuf, "in op_getprecision(): invalid precision level." );
  2145. X   bwb_error( bwb_ebuf );
  2146. X   #else
  2147. X   bwb_error( err_syntax );
  2148. X   #endif
  2149. X
  2150. X   return FALSE;
  2151. X
  2152. X   }
  2153. X
  2154. X/***************************************************************
  2155. X
  2156. X        FUNCTION:   op_pulldown()
  2157. X
  2158. X        DESCRIPTION:  This function pulls the expression stack
  2159. X        down a specified number of levels, decrementing the
  2160. X        expression stack counter (bycalling dec_esc()) and
  2161. X        decrementing the current "level" of operation processing.
  2162. X
  2163. X***************************************************************/
  2164. X
  2165. Xint
  2166. Xop_pulldown( int how_far )
  2167. X   {
  2168. X   int level;
  2169. X   register int c;
  2170. X
  2171. X   #if INTENSIVE_DEBUG
  2172. X   sprintf( bwb_ebuf, "in op_pulldown(): pull down e stack <%d> place(s)",
  2173. X      how_far );
  2174. X   bwb_debug( bwb_ebuf );
  2175. X   #endif
  2176. X
  2177. X   /* first pull down the actual variables themselves */
  2178. X
  2179. X   level = op_level + ( 2 - how_far );
  2180. X   while ( exp_esc >= ( level + how_far ) )
  2181. X      {
  2182. X
  2183. X      memcpy( &exp_es[ level ], &exp_es[ level + how_far ],
  2184. X         (size_t) ( sizeof( struct exp_ese )) );
  2185. X      ++level;
  2186. X
  2187. X      }
  2188. X
  2189. X   /* decrement the expression stack counter */
  2190. X
  2191. X   for ( c = 0; c < how_far; ++c )
  2192. X      {
  2193. X
  2194. X      if ( dec_esc() == TRUE )
  2195. X         {
  2196. X         --op_level;
  2197. X         }
  2198. X      else
  2199. X         {
  2200. X         return FALSE;
  2201. X         }
  2202. X
  2203. X      }
  2204. X
  2205. X   return TRUE;
  2206. X
  2207. X   }
  2208. X
  2209. END_OF_FILE
  2210.   if test 57586 -ne `wc -c <'bwb_ops.c'`; then
  2211.     echo shar: \"'bwb_ops.c'\" unpacked with wrong size!
  2212.   fi
  2213.   # end of 'bwb_ops.c'
  2214. fi
  2215. echo shar: End of archive 2 \(of 11\).
  2216. cp /dev/null ark2isdone
  2217. MISSING=""
  2218. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  2219.     if test ! -f ark${I}isdone ; then
  2220.     MISSING="${MISSING} ${I}"
  2221.     fi
  2222. done
  2223. if test "${MISSING}" = "" ; then
  2224.     echo You have unpacked all 11 archives.
  2225.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2226. else
  2227.     echo You still must unpack the following archives:
  2228.     echo "        " ${MISSING}
  2229. fi
  2230. exit 0
  2231. exit 0 # Just in case...
  2232.