home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / bwbasic.zip / src / bwb_ops.c < prev    next >
C/C++ Source or Header  |  1993-04-27  |  58KB  |  2,182 lines

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