Esempio n. 1
0
static int
op_modulus(int level, int precision)
{
   static double   iportion;

   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be numbers for string
       * addition; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be divided.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   case NUMBER:
      {
         /* N = X MOD Y */
         if (exp_getnval(&(CURTASK exps[level + 1]))
             == 0)
         {
            CURTASK         exps[level - 1].nval = -1;
            op_pulldown(2);
            sprintf(bwb_ebuf, "Modulus by 0.");
            bwb_error(bwb_ebuf);
            return FALSE;
         }
         CURTASK         exps[level].nval
         = exp_getnval(&(CURTASK exps[level - 1]))
         / exp_getnval(&(CURTASK exps[level + 1]));
         modf((double) CURTASK exps[level].nval, &iportion);
         CURTASK         exps[level - 1].nval
         = exp_getnval(&(CURTASK exps[level - 1]))
         - (exp_getnval(&(CURTASK exps[level + 1]))
            * iportion);
      }
      break;

   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = (char) precision;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 2
0
static int
op_intdiv(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be numbers for string
       * addition; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be divided.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   default:
      {
         /* N = X \ Y  */
         long            X;
         long            Y;
         long            N;
         X = exp_getival(&(CURTASK exps[level - 1]));
         Y = exp_getival(&(CURTASK exps[level + 1]));
         if (Y == 0)
         {
            sprintf(bwb_ebuf, "Integer Divide by 0.");
            bwb_error(bwb_ebuf);
            return FALSE;
         }
         N = X / Y;
         CURTASK         exps[level - 1].nval = N;
      }
      break;
   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = NUMBER;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 3
0
BasicNumberType
VerifyNumeric(BasicNumberType Value)
{
   bwx_DEBUG(__FUNCTION__);
   /* check Value */
   if (isnan(Value))
   {
      /*** FATAL - INTERNAL ERROR - SHOULD NEVER HAPPEN ***/
      bwb_error("NOT A NUMBER");
      return 0;
   }
   else
   if (isinf(Value))
   {
      /* - Evaluation of an expression results in an overflow
       * (nonfatal, the recommended recovery procedure is to supply
       * machine in- finity with the algebraically correct sign and
       * continue). */
      if (Value < 0)
      {
         Value = -DBL_MAX;
      }
      else
      {
         Value = DBL_MAX;
      }
      bwb_Warning_Overflow("*** Arithmetic Overflow ***");
   }
   return Value;
}
Esempio n. 4
0
static int
op_gteq(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be numbers for string
       * addition; if not, report an error */

      if ((op_islevelstr(level - 1) != TRUE)
          || (op_islevelstr(level + 1) != TRUE))
      {
         sprintf(bwb_ebuf, "Type mismatch in string comparison.");
         bwb_error(bwb_ebuf);
         return FALSE;
      }
      /* compare the two strings */

      if (str_cmp(exp_getsval(&(CURTASK exps[level - 1])),
             exp_getsval(&(CURTASK exps[level + 1]))) >= 0)
      {
         CURTASK         exps[level - 1].nval = TRUE;
      }
      else
      {
         CURTASK         exps[level - 1].nval = FALSE;
      }
      break;

   case NUMBER:
      if (exp_getnval(&(CURTASK exps[level - 1]))
          >= exp_getnval(&(CURTASK exps[level + 1])))
      {
         CURTASK         exps[level - 1].nval = TRUE;
      }
      else
      {
         CURTASK         exps[level - 1].nval = FALSE;
      }
      break;

   }

   /* set variable to integer and operation to NUMBER: this must be done
    * at the end, since at the beginning it might cause op_islevelstr()
    * to return a false error */

   CURTASK         exps[level - 1].type = NUMBER;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 5
0
int
exp_strconst(char *expression)
{
   int             e_pos, s_pos;

   bwx_DEBUG(__FUNCTION__);

   /* assign values to structure */

   CURTASK         exps[CURTASK expsc].type = STRING;
   CURTASK         exps[CURTASK expsc].operation = CONST_STRING;

   /* set counters */

   s_pos = 0;
   CURTASK         exps[CURTASK expsc].pos_adv = e_pos = 1;
   CURTASK         exps[CURTASK expsc].string[0] = '\0';

   /* read the string up until the next quotation mark */

   /* While yer at it, check for a null terminator too (JBV, found by
    * DD) */
   while ((expression[e_pos] != '\"') && (expression[e_pos] != '\0'))
   {
      CURTASK         exps[CURTASK expsc].string[s_pos] = expression[e_pos];
      ++e_pos;
      ++s_pos;
      ++CURTASK exps[CURTASK expsc].pos_adv;
      CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
      if (s_pos > BasicStringLengthMax)
      {
         sprintf(bwb_ebuf, "string <%s> exceeds maximum size (%d) for string constant.",
            expression, BasicStringLengthMax);
         bwb_error(bwb_ebuf);
         return OP_NULL;
      }
   }

   /* now write string over to bstring */

   str_ctob(&(CURTASK exps[CURTASK expsc].sval), CURTASK exps[CURTASK expsc].string);

   /* advance past last quotation mark */

   /*-------------------------------------------------------------*/
   /* Of course, it doesn't hurt to make sure it's really a quote */
   /* (JBV, found by DD)                                          */
   /*-------------------------------------------------------------*/
   if (expression[e_pos] == '\"')
      ++CURTASK exps[CURTASK expsc].pos_adv;

   /* return */

   return TRUE;

}
Esempio n. 6
0
static int
op_add(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be strings for string
       * addition; if not, report an error */

      if ((op_islevelstr(level - 1) != TRUE)
          || (op_islevelstr(level + 1) != TRUE))
      {
         sprintf(bwb_ebuf, "in op_add(): Type mismatch in string addition.");
         bwb_error(bwb_ebuf);
         return FALSE;
      }
      /* concatenate the two strings */

      {
         static bstring  b;   /* JBV */
         b.rab = FALSE; /* JBV */


         str_btob(&b, exp_getsval(&(CURTASK exps[level - 1])));
         str_cat(&b, exp_getsval(&(CURTASK exps[level + 1])));
         str_btob(&(CURTASK exps[level - 1].sval), &b);
         CURTASK         exps[level - 1].operation = CONST_STRING;

      }
      break;

   case NUMBER:
      CURTASK exps[level - 1].nval
         = exp_getnval(&(CURTASK exps[level - 1]))
         + exp_getnval(&(CURTASK exps[level + 1]));
      CURTASK         exps[level - 1].operation = NUMBER;
      break;

   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = (char) precision;


   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 7
0
struct bwb_line *
bwb_edit( struct bwb_line *l )
   {
   char tbuf[ MAXSTRINGSIZE + 1 ];
   char edname[ MAXSTRINGSIZE + 1 ];
   struct bwb_variable *ed;
   FILE *loadfile;

   ed = var_find( DEFVNAME_EDITOR );
   str_btoc( edname, var_getsval( ed ));

   sprintf( tbuf, "%s %s", edname, CURTASK progfile );

#if INTENSIVE_DEBUG
   sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
   bwb_debug( bwb_ebuf );
#else
   nl();
   endwin(); /* Added by JBV 10/11/97 */
   system( tbuf );

   /*-----------------------*/
   /* Added by JBV 10/11/97 */
   /*-----------------------*/
   fprintf( stderr, "Press RETURN when ready..." );
   fgets( tbuf, MAXREADLINESIZE, stdin );
   refresh();

   nonl();
#endif

   /* open edited file for read */

   if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
      {
      sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
      bwb_error( bwb_ebuf );

      ncu_setpos();
      return bwb_zline( l );
      }

   /* clear current contents */

   bwb_new( l ); /* Relocated by JBV (bug found by DD) */

   /* and (re)load the file into memory */

   bwb_fload( loadfile );


   ncu_setpos();
   return bwb_zline( l );
   }
Esempio n. 8
0
static int
op_and(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:


      /* both sides of the operation should be numbers for logical
       * comparison; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be compared logically.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   case NUMBER:
      {
         /* N = X AND Y  */
         long            X;
         long            Y;
         long            N;
         X = exp_getival(&(CURTASK exps[level - 1]));
         Y = exp_getival(&(CURTASK exps[level + 1]));
         N = X & Y;
         CURTASK         exps[level - 1].nval = N;
      }
      break;

   }

   /* set variable type to integer */

   CURTASK         exps[level - 1].type = NUMBER;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 9
0
struct bwb_line *
bwb_edit( struct bwb_line *l )
   {
   char tbuf[ MAXSTRINGSIZE + 1 ];
   char edname[ MAXSTRINGSIZE + 1 ];
   struct bwb_variable *ed;
   FILE *loadfile;

   ed = var_find( DEFVNAME_EDITOR );
   str_btoc( edname, var_getsval( ed ));

   sprintf( tbuf, "%s %s", edname, CURTASK progfile );

#if INTENSIVE_DEBUG
   sprintf( bwb_ebuf, "in bwb_edit(): command line <%s>", tbuf );
   bwb_debug( bwb_ebuf );
#else
   system( tbuf );
#endif

   /* open edited file for read */

   if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL )
      {
      sprintf( bwb_ebuf, err_openfile, CURTASK progfile );
      bwb_error( bwb_ebuf );

      iqc_setpos();
      return bwb_zline( l );
      }

   /* clear current contents */

   bwb_new( l ); /* Relocated by JBV (bug found by DD) */

   /* and (re)load the file into memory */

   bwb_fload( loadfile );


   iqc_setpos();
   return bwb_zline( l );
   }
Esempio n. 10
0
static int
op_posation(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:


      /* both sides of the operation should be numbers for logical
       * comparison; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be compared logically.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   default:


      CURTASK exps[level].nval =
         (exp_getnval(&(CURTASK exps[level + 1])));


      break;
   }

   /* set variable type to requested precision (JBV) */

   CURTASK         exps[level].type = (char) precision;
   CURTASK         exps[level].operation = NUMBER;

   /* decrement the stack once */

   op_pulldown(1);


   return TRUE;

}
Esempio n. 11
0
static int
op_multiply(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be numbers for string
       * addition; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be multiplied.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   case NUMBER:
      CURTASK exps[level - 1].nval
         = exp_getnval(&(CURTASK exps[level - 1]))
         * exp_getnval(&(CURTASK exps[level + 1]));
      break;

   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = (char) precision;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 12
0
struct bwb_line *
bwb_OPEN(struct bwb_line * l)
{
   /* OPEN filename [FOR mode] AS filenumber [LEN reclen] */
   char            filename[BasicStringLengthMax + 1];
   char            mode[BasicStringLengthMax + 1];
   char            filenumber[BasicStringLengthMax + 1];
   char            reclen[BasicStringLengthMax + 1];
   char            OutputBuffer[BasicStringLengthMax + 1];
   int             p;

   bwx_DEBUG(__FUNCTION__);

   /* OPEN filename [FOR mode] AS */
   if (GetKeyword(l, filename, " FOR "))
   {
      /* OPEN filename FOR */
      if (GetKeyword(l, mode, " AS "))
      {
         /* FOR mode AS */
      }
      else
      {
         bwb_error("syntax error");
      }
   }
   else
   if (GetKeyword(l, filename, " AS "))
   {
      /* OPEN filename AS */
      strcpy(mode, "BINARY"); /* default for structured OPEN */
   }
   else
   {
      bwb_error("syntax error");
   }

   /* AS filenumber [LEN reclen] */
   if (GetKeyword(l, filenumber, " LEN "))
   {
      /* AS filenumber LEN reclen */
      GetRestOfLine(l, reclen);
   }
   else
   {
      /* AS filenumber */
      GetRestOfLine(l, filenumber);
      strcpy(reclen, "128");  /* default for structured OPEN */
   }

   OutputBuffer[0] = '\0';
   strcat(OutputBuffer, "OPEN(");
   strcat(OutputBuffer, "\"");
   strcat(OutputBuffer, mode);
   strcat(OutputBuffer, "\"");
   strcat(OutputBuffer, ",");
   strcat(OutputBuffer, filenumber);
   strcat(OutputBuffer, ",");
   strcat(OutputBuffer, filename);
   strcat(OutputBuffer, ",");
   strcat(OutputBuffer, reclen);
   strcat(OutputBuffer, ")");


   p = 0;
   bwb_exp(OutputBuffer, FALSE, &p);
   if (ERROR_PENDING)
   {
      /* oops */
   }
   return bwb_zline(l);
}
Esempio n. 13
0
static struct bwb_line *
dio_lrset(struct bwb_line * l, int rset)
{
   char            varname[BasicNameLengthMax + 1];
   bstring        *d, *s;
   int            *pp;
   int             n_params;
   int             p;
   register int    n, i;
   int             startpos;
   struct exp_ese *e;
   struct bwb_variable *v;
   int             pos;

   bwx_DEBUG(__FUNCTION__);
   /* find the variable name */

   bwb_getvarname(l->buffer, varname, &(l->position));
   v = var_find(varname);

   if (v == NULL)
   {
      sprintf(bwb_ebuf, "in dio_lrset(): failed to find variable");
      bwb_error(bwb_ebuf);
   }
   if (v->type != STRING)
   {
      sprintf(bwb_ebuf, "in dio_lrset(): assignment must be to string variable");
      bwb_error(bwb_ebuf);
   }
   /* read subscripts */

   pos = 0;
   if ((v->dimensions == 1) && (v->array_sizes[0] == 1))
   {
      n_params = 1;
      pp = &p;
      pp[0] = dim_base;
   }
   else
   {
      dim_getparams(l->buffer, &(l->position), &n_params, &pp);
   }

   CURTASK         exps[CURTASK expsc].pos_adv = pos;
   for (n = 0; n < v->dimensions; ++n)
   {
      v->array_pos[n] = pp[n];
   }

   /* get bstring pointer */

   d = var_findsval(v, pp);

   /* find equals sign */

   adv_ws(l->buffer, &(l->position));
   if (l->buffer[l->position] != '=')
   {
      sprintf(bwb_ebuf, "in dio_lrset(): failed to find equal sign");
      bwb_error(bwb_ebuf);
   }
   ++(l->position);
   adv_ws(l->buffer, &(l->position));

   /* read remainder of line to get value */

   e = bwb_exp(l->buffer, FALSE, &(l->position));
   if (ERROR_PENDING)
   {
      return bwb_zline(l);
   }
   s = exp_getsval(e);

   /* set starting position */

   startpos = 0;
   if (rset == TRUE)
   {
      if (s->length < d->length)
      {
         startpos = d->length - s->length;
      }
   }
   /* write characters to new position */

   i = 0;
   for (n = startpos; (i < (int) s->length) && (n < (int) d->length); ++n)
   {
      d->sbuffer[n] = s->sbuffer[i];
      ++i;
   }

   /* return */

   return bwb_zline(l);

}
Esempio n. 14
0
struct bwb_line *
bwb_FIELD(struct bwb_line * l)
{
   int             dev_number;
   struct exp_ese *e;
   int             current_pos;
   char            atbuf[BasicStringLengthMax + 1];
   int             pos;

   bwx_DEBUG(__FUNCTION__);

   current_pos = 0;

   /* first read device number */

   adv_ws(l->buffer, &(l->position));
   if (l->buffer[l->position] == BasicFileNumberPrefix)
   {
      ++(l->position);
      adv_ws(l->buffer, &(l->position));
   }
   adv_element(l->buffer, &(l->position), atbuf);

   pos = 0;
   e = bwb_exp(atbuf, FALSE, &pos);
   if (ERROR_PENDING)
   {
      return bwb_zline(l);
   }
   if (e->type != NUMBER)
   {
      bwb_error("in bwb_field(): Number was expected for device number");
      return bwb_zline(l);
   }
   dev_number = exp_getival(e);


   if (dev_number < 1 || dev_number > BasicFileNumberMax)
   {
      bwb_error("in bwb_field(): Requested device number is not VALID.");
      return bwb_zline(l);
   }
   /* be sure that the requested device is open */

   if (dev_table[dev_number].mode != DEVMODE_RANDOM)
   {
      bwb_error("in bwb_field(): Requested device number is not RANDOM.");
      return bwb_zline(l);
   }
   /* loop to read variables */

   do
   {
      int             length;
      struct bwb_variable *v;
      bstring        *b;


      /* read the comma and advance beyond it */

      adv_ws(l->buffer, &(l->position));
      if (l->buffer[l->position] == ',')
      {
         ++(l->position);
      }
      /* first find the size of the field */

      adv_element(l->buffer, &(l->position), atbuf);  /* get element */

      pos = 0;
      e = bwb_exp(atbuf, FALSE, &pos);
      if (ERROR_PENDING)
      {
         return bwb_zline(l);
      }
      if (e->type != NUMBER)
      {
         bwb_error("in bwb_field(): number value for field size not found");
         return bwb_zline(l);
      }
      length = exp_getival(e);


      /* read the AS */

      adv_element(l->buffer, &(l->position), atbuf);  /* get element */


      if (strcasecmp(atbuf, "AS") != 0)
      {
         bwb_error("in bwb_field(): AS statement not found");
         return bwb_zline(l);
      }
      /* read the string variable name */
#if 0
      adv_element(l->buffer, &(l->position), atbuf);  /* get element */
#endif
      bwb_getvarname(l->buffer, atbuf, &(l->position));
      v = var_find(atbuf);

      if (v->type != STRING)
      {
         bwb_error("in bwb_field(): string variable name not found");
         return bwb_zline(l);
      }
      /* check for overflow of record length */

      if ((current_pos + length) > dev_table[dev_number].width)
      {
         bwb_error("in bwb_field(): record length exceeded");
         return bwb_zline(l);
      }
      /* set buffer */

      b = var_findsval(v, v->array_pos);
      b->sbuffer = dev_table[dev_number].buffer + current_pos;
      b->length = (unsigned int) length;  /* Was unsigned char
                      * (JBV 9/4/97) */
      b->rab = TRUE;

      current_pos += length;


      /* eat up any remaining whitespace */

      adv_ws(l->buffer, &(l->position));

   }

   while (l->buffer[l->position] == ',');

   /* return */

   return bwb_zline(l);

}
Esempio n. 15
0
struct bwb_line *
bwb_NAME(struct bwb_line * l)
{
   int             r;
   int             position;
   struct exp_ese *e;
   char            atbuf[BasicStringLengthMax + 1];
   char            btbuf[BasicStringLengthMax + 1];

   bwx_DEBUG(__FUNCTION__);

   /* get the first argument in atbuf */

   adv_element(l->buffer, &(l->position), atbuf);

   /* interpret the first argument */

   position = 0;
   e = bwb_exp(atbuf, FALSE, &position);
   if (ERROR_PENDING)
   {
      return bwb_zline(l);
   }
   if (e->type != STRING)
   {
      bwb_error(err_argstr);
      return bwb_zline(l);
   }
   /* this argument must be copied back to atbuf, else the next call to
    * bwb_exp() will overwrite the structure to which e refers */

   str_btoc(atbuf, &(e->sval));


   /* get the second argument in btbuf */

   adv_element(l->buffer, &(l->position), btbuf);


   if (strcasecmp(btbuf, "AS") != 0)
   {
      bwb_error(err_syntax);
      return bwb_zline(l);
   }
   /* get the third argument in btbuf */

   adv_element(l->buffer, &(l->position), btbuf);

   /* interpret the third argument */

   position = 0;
   e = bwb_exp(btbuf, FALSE, &position);
   if (ERROR_PENDING)
   {
      return bwb_zline(l);
   }
   if (e->type != STRING)
   {
      bwb_error(err_argstr);
      return bwb_zline(l);
   }
   str_btoc(btbuf, &(e->sval));


   /* try to rename the file */

   r = rename(atbuf, btbuf);

   /* detect error */

   if (r != 0)
   {
      bwb_error(err_opsys);
   }
   return bwb_zline(l);

}
Esempio n. 16
0
int
exp_paren(char *expression)
{
   struct exp_ese *e;
   int             s_pos;  /* position in build buffer */
   int             loop;
   int             paren_level;

   bwx_DEBUG(__FUNCTION__);

   /* find a string enclosed by parentheses */

   CURTASK         exps[CURTASK expsc].pos_adv = 1;   /* start beyond open
                         * paren */
   s_pos = 0;
   loop = TRUE;
   paren_level = 1;
   CURTASK         exps[CURTASK expsc].string[0] = '\0';

   while (loop == TRUE)
   {

      /* check the current character */

      switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
      {
      case '\0':
         bwb_error(err_incomplete);
         loop = FALSE;
         break;

      case '(':
         ++paren_level;
         CURTASK         exps[CURTASK expsc].string[s_pos]
         = expression[CURTASK exps[CURTASK expsc].pos_adv];
         ++s_pos;
         CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         break;

      case ')':

         --paren_level;
         if (paren_level == 0)
         {
            loop = FALSE;
         }
         else
         {
            CURTASK         exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         }
         break;

      case '\"':  /* embedded string constant */
         ++CURTASK exps[CURTASK expsc].pos_adv;
         while ((expression[CURTASK exps[CURTASK expsc].pos_adv] != '\"')
                && (expression[CURTASK exps[CURTASK expsc].pos_adv] != '\0'))
         {
            CURTASK         exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
            ++CURTASK exps[CURTASK expsc].pos_adv;
         }
         break;

      default:
         CURTASK exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
         ++s_pos;
         CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         break;
      }

      /* advance the counter */

      ++CURTASK exps[CURTASK expsc].pos_adv;

   }


   /* call bwb_exp() recursively to interpret this expression */

   CURTASK         exps[CURTASK expsc].rec_pos = 0;
   e = bwb_exp(CURTASK exps[CURTASK expsc].string, FALSE,
          &(CURTASK exps[CURTASK expsc].rec_pos));

   /* assign operation and value at this level */

   CURTASK         exps[CURTASK expsc].type = e->type;

   switch (e->type)
   {
   case STRING:
      CURTASK exps[CURTASK expsc].operation = CONST_STRING;
      str_btob(exp_getsval(&(CURTASK exps[CURTASK expsc])), exp_getsval(e));
      break;
   default:
      CURTASK exps[CURTASK expsc].operation = NUMBER;
      CURTASK         exps[CURTASK expsc].nval = exp_getnval(e);
      break;
   }

   return TRUE;

}
Esempio n. 17
0
static int
op_assign(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   /* Make sure the position one level below is a variable */

   if (CURTASK exps[level - 1].operation != VARIABLE)
   {
      op_pulldown(2);
      sprintf(bwb_ebuf, "in op_assign(): Assignment must be to variable: level -1 <%d> op <%d>",
         level - 1, CURTASK exps[level - 1].operation);
      bwb_error(bwb_ebuf);
      return FALSE;
   }
   if (CURTASK exps[level - 1].type != CURTASK exps[level + 1].type)
   {
      bwb_error("Type Mismatch");
      return FALSE;
   }
   /* if the assignment is numerical, then the precision should be set
    * to that of the variable on the left-hand side of the assignment */

   if (precision != STRING)
   {
      precision = (int) CURTASK exps[level - 1].type;
   }
   switch (precision)
   {
   case STRING:


      str_btob(exp_getsval(&(CURTASK exps[level - 1])),
          exp_getsval(&(CURTASK exps[level + 1])));
      break;

   case NUMBER:
      if (TRUE)
      {
         double          Value;
         Value = exp_getnval(&(CURTASK exps[level + 1]));
         Value = VerifyNumeric(Value);
         /* assign Value */
         *var_findnval(CURTASK exps[level - 1].xvar,
                  CURTASK exps[level - 1].array_pos) =
            CURTASK exps[level - 1].nval =
            Value;
      }
      break;

   default:
      sprintf(bwb_ebuf, "in op_assign(): Variable before assignment operator has unidentified type.");
      bwb_error(bwb_ebuf);
      return FALSE;

   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = (char) precision;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 18
0
int
exp_function(char *expression)
{
   struct exp_ese *e;
   int             s_pos;  /* position in build buffer */
   int             loop;
   int             paren_level;
   int             n_args;
   /* struct bwb_variable argv[ MAX_FARGS ]; *//* Removed by JBV */
   struct bwb_variable *argv; /* Added by JBV */
   struct bwb_variable *argn;
   bstring        *b;

   bwx_DEBUG(__FUNCTION__);


   argv = var_chain(NULL); /* RETURN variable */
   argn = NULL;

   /* assign pointers to argument stack */

   /* get the function name */

   exp_getvfname(expression, CURTASK exps[CURTASK expsc].string);


   /* now find the function itself */

   CURTASK         exps[CURTASK expsc].function = fnc_find(CURTASK exps[CURTASK expsc].string);

   /* check to see if it is valid */

   if (CURTASK exps[CURTASK expsc].function == NULL)
   {
      sprintf(bwb_ebuf, "Failed to find function <%s>.",
         CURTASK exps[CURTASK expsc].string);
      bwb_error(bwb_ebuf);
      return OP_ERROR;
   }
   /* note that this level is a function */

   CURTASK         exps[CURTASK expsc].operation = FUNCTION;
   CURTASK         exps[CURTASK expsc].pos_adv = strlen(CURTASK exps[CURTASK expsc].string);

   /* check for begin parenthesis */

   loop = TRUE;
   while (loop == TRUE)
   {
      switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
      {

      case ' ':   /* whitespace */
         ++CURTASK exps[CURTASK expsc].pos_adv; /* advance */
         break;

      case '(':   /* begin paren */


         ++CURTASK exps[CURTASK expsc].pos_adv; /* advance beyond it */
         paren_level = 1;  /* set paren_level */
         loop = FALSE;  /* and break out */
         break;

      default: /* anything else */
         loop = FALSE;
         paren_level = 0;  /* do not look for parameters */
         break;
      }
   }

   /* find parameters within parentheses */
   /* for each argument, find a string ending with ',' or with end
    * parenthesis */

   n_args = 0;
   s_pos = 0;
   CURTASK         exps[CURTASK expsc].string[0] = '\0';

   while (paren_level > 0)
   {

      /* check the current character */

      switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
      {

      case ',':   /* end of an argument */

         if (paren_level == 1)   /* ignore ',' within
                   * parentheses */
         {

            /* call bwb_exp() recursively to resolve the
             * argument */

            if (exp_validarg(CURTASK exps[CURTASK expsc].string) == TRUE)
            {

               CURTASK         exps[CURTASK expsc].rec_pos = 0;
               e = bwb_exp(CURTASK exps[CURTASK expsc].string, FALSE,
                      &(CURTASK exps[CURTASK expsc].rec_pos));

               /* assign operation and value at this
                * level */
               argn = var_chain(argv);
               /* 'argn' is the vaiable to use */
               var_make(argn, e->type);
               switch (argn->type)
               {
               case NUMBER:
                  *var_findnval(argn, argn->array_pos)
                     = exp_getnval(e);
                  break;
               case STRING:
                  str_btob(var_findsval(argn,
                              argn->array_pos), exp_getsval(e));
                  break;
               }
               ++n_args;   /* increment number of
                      * parameters */

            }
            s_pos = 0;  /* reset counter */
            CURTASK         exps[CURTASK expsc].string[0] = '\0';
         }
         else
         {
            CURTASK         exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         }
         break;

      case '(':
         ++paren_level;
         CURTASK         exps[CURTASK expsc].string[s_pos]
         = expression[CURTASK exps[CURTASK expsc].pos_adv];
         ++s_pos;
         CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         break;

      case ')':
         --paren_level;


         if (paren_level == 0)
         {


            /* call bwb_exp() recursively to resolve the
             * argument */

            if (exp_validarg(CURTASK exps[CURTASK expsc].string) == TRUE)
            {

               CURTASK         exps[CURTASK expsc].rec_pos = 0;
               e = bwb_exp(CURTASK exps[CURTASK expsc].string, FALSE,
                      &(CURTASK exps[CURTASK expsc].rec_pos));


               /* assign operation and value at this
                * level */
               argn = var_chain(argv);
               /* 'argn' is the vaiable to use */
               var_make(argn, e->type);
               switch (argn->type)
               {
               case NUMBER:
                  *var_findnval(argn, argn->array_pos)
                     = exp_getnval(e);
                  break;
               case STRING:
                  str_btob(var_findsval(argn,
                              argn->array_pos), exp_getsval(e));
                  break;
               }
               ++n_args;   /* increment number of
                      * parameters */

            }
            s_pos = 0;  /* reset counter */
            CURTASK         exps[CURTASK expsc].string[0] = '\0';
         }
         else
         {
            CURTASK         exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         }
         break;

      case '\"':  /* embedded string constant */

         /* add the initial quotation mark */

         CURTASK exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
         ++s_pos;
         CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         ++CURTASK exps[CURTASK expsc].pos_adv;

         /* add intervening characters */

         while ((expression[CURTASK exps[CURTASK expsc].pos_adv] != '\"')
                && (expression[CURTASK exps[CURTASK expsc].pos_adv] != '\0'))
         {
            CURTASK         exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
            ++CURTASK exps[CURTASK expsc].pos_adv;
         }

         /* add the concluding quotation mark */

         CURTASK         exps[CURTASK expsc].string[s_pos]
         = expression[CURTASK exps[CURTASK expsc].pos_adv];
         ++s_pos;
         CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         /* the following bracketed out 14 July 1992; since
          * this counter */
         /* incremented at the end of the switch statement,
          * this may */
         /* increment it past the next character needed */
         /* ++CURTASK exps[ CURTASK expsc ].pos_adv; */
         break;

      default:
         CURTASK exps[CURTASK expsc].string[s_pos]
            = expression[CURTASK exps[CURTASK expsc].pos_adv];
         ++s_pos;
         CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
         break;
      }

      /* advance the counter */

      ++CURTASK exps[CURTASK expsc].pos_adv;

   }


   /* call the function vector */


   if (TRUE)
   {
      /* Compare the parameter signature of the caller to the
       * callee. This allows for function overloading based upon
       * different parameter signatures. It also eliminates the
       * need for any intrinsic function to check it's parameter
       * count or check the type of it's parameters.  The function
       * will only be callled with the correct type and count of
       * parameters.  Examples of common intrinsic functions which
       * are overloaded based upon the parameter signature are
       * INSTR and MID$. INSTR( [Start], In$, Find$ ) -> instr(
       * string, string )          -> 2 parameters instr( number,
       * string, string )  -> 3 parameters */
      struct bwb_function *f;
      char           *name;

      f = CURTASK exps[CURTASK expsc].function;
      name = f->Name;


      /* There are two choices for USER DEFINE FUNCTIONS: #1 - A
       * fixed number of upto 32 parameters, declared as FUNCTION
       * FRED( A$, B$, X, Y ) #2 - A variant number of upto MAXINT
       * parameters, declared as FUNCTION FRED( ... ) */

      /* Determine the caller's parameter signature, using an
       * algorithm matching the intrinsic table: First argument is
       * bit 0; if it is 1 then STRING else NUMBER. Second argument
       * is bit 1, and so on. */
      if (TRUE)
      {
         /* VERIFY */
         unsigned char   ParameterCount;
         unsigned long   ParameterTypes;

         if (n_args > 32)
         {
            /* VARIANT */
            ParameterCount = 0xFF;
            ParameterTypes = 0;
         }
         else
         {
            int             i;
            ParameterCount = n_args;   /* <= 32 */
            ParameterTypes = 0;
            argn = argv;
            for (i = 0; i < ParameterCount; i++)
            {
               argn = argn->next;
               if (argn->type == STRING)
               {
                  ParameterTypes |= (1 << i);
               }
            }
         }
         /* did we find the correct function above? */
         if (f->ParameterCount != ParameterCount || f->ParameterTypes != ParameterTypes)
         {
            /* oops */

            f = fnc_find_exact(name, ParameterCount, ParameterTypes);
            if (f == NULL)
            {
               /* NOT FOUND */
               f = fnc_find_exact(name, 0xFF, 0);  /* look for VARIANT */
            }
            if (f == NULL)
            {
               /* NOT FOUND */
               sprintf(bwb_ebuf, "*** Illegal Function Call (%s) ***", name);
               bwb_error(bwb_ebuf);
               return OP_ERROR;
            }
            /* FOUND */
            CURTASK         exps[CURTASK expsc].function = f;
         }
      }
   }
   /* defaullt the return value */
#define RESULT_NUMBER  *argv->memnum
#define RESULT_BUFFER   argv->memstr->sbuffer
#define RESULT_LENGTH   argv->memstr->length
   /* defaullt the return value */
   {
      if ((CURTASK exps[CURTASK expsc].function->ReturnType & 0x00FF) == STRING)
      {
         var_make(argv, STRING);
         RESULT_BUFFER = (char *) CALLOC(BasicStringLengthMax + 1, 1, "exp_function");
         RESULT_LENGTH = 0;
         RESULT_BUFFER[RESULT_LENGTH] = '\0';
      }
      else
      {
         var_make(argv, NUMBER);
         RESULT_NUMBER = 0;
      }
      strcpy(argv->name, CURTASK exps[CURTASK expsc].function->Name);
   }
   if (CURTASK exps[CURTASK expsc].function->ReturnType & 0xFF00  /* UniqueID is a line
           number */ )
   {
      /* for all USER DEFINED FUNCTIONS: f->UniqueID == line number
       * of DEF FN... */
      unsigned short  cmdnum;
      cmdnum = (CURTASK exps[CURTASK expsc].function->ReturnType & 0xFF00) >> 8;
      switch (cmdnum)
      {
      case C_DEF: /* execute a user function declared using DEF
             * FN...(...) = ... */
      case C_FUNCTION:  /* execute a user function declared
                * using FUNCTION ...(...) */
      case C_SUB: /* execute a user subroutine declared using
             * SUB ...(...) */
         fnc_deffn(n_args, argv, CURTASK exps[CURTASK expsc].function->UniqueID);
         break;
      case C_USER_LBL:  /* IF ERL > label1 AND ERL < label2
                * THEN ... */
         if (n_args > 0)
         {
            bwb_error("SYNTAX ERROR");
         }
         /* return the line number associated with the label */
         RESULT_NUMBER = CURTASK exps[CURTASK expsc].function->UniqueID;
         break;
      default:
         sprintf(bwb_ebuf, "INTERNAL ERROR, in exp_function(): unexpected cmdnum %d", cmdnum);
         bwb_error(bwb_ebuf);
         break;
      }
   }
Esempio n. 19
0
static int
op_divide(int level, int precision)
{
   bwx_DEBUG(__FUNCTION__);

   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be numbers for
       * division; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be divided.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   case NUMBER:

      if (exp_getnval(&(CURTASK exps[level + 1]))
          == 0)
      {
         /* - Evaluation of an expression results in division
          * by zero (nonfatal, the recommended recovery
          * procedure is to supply machine infinity with the
          * sign of the numerator and continue) */

         if (exp_getnval(&(CURTASK exps[level - 1])) < 0)
         {
            /* NEGATIVE */
            CURTASK         exps[level - 1].nval = -(DBL_MAX); /* NEGATIVE INFINITY */
         }
         else
         {
            /* POSITIVE  */
            CURTASK         exps[level - 1].nval = (DBL_MAX);  /* POSITIVE INFINITY */
         }
         bwb_Warning_Overflow("*** WARNING:  Divide by 0 ***");
      }
      else
      {
         CURTASK         exps[level - 1].nval
         = exp_getnval(&(CURTASK exps[level - 1]))
         / exp_getnval(&(CURTASK exps[level + 1]));
      }

      break;
   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = (char) precision;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}
Esempio n. 20
0
extern int
bwx_shell( struct bwb_line *l )
   {
   static char *s_buffer;
   static int init = FALSE;
   static int position;

   /* get memory for temporary buffer if necessary */

   if ( init == FALSE )
      {
      init = TRUE;

      /* Revised to CALLOC pass-thru call by JBV */
      if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ),"bwx_shell" )) == NULL )
	 {
	 bwb_error( err_getmem );
	 return FALSE;
	 }
      }

   /* get the first element and check for a line number */

#if INTENSIVE_DEBUG
   sprintf( bwb_ebuf, "in bwx_shell(): line buffer is <%s>.", l->buffer );
   bwb_debug( bwb_ebuf );
#endif

   position = 0;
   adv_element( l->buffer, &position, s_buffer );
   if ( is_numconst( s_buffer ) != TRUE )                  /* not a line number */
      {

#if INTENSIVE_DEBUG
      sprintf( bwb_ebuf, "in bwx_shell(): no line number, command <%s>.",
	 l->buffer );
      bwb_debug( bwb_ebuf );
#endif
      nl();
      endwin(); /* Added by JBV 10/11/97 */
      if ( system( l->buffer ) == 0 )
	 {
         refresh(); /* Added by JBV 10/11/97 */
         nonl();
	 ncu_setpos();
	 return TRUE;
	 }
      else
	 {
         refresh(); /* Added by JBV 10/11/97 */
         nonl();
	 ncu_setpos();
	 return FALSE;
	 }
      }

   else                                         /* advance past line number */
      {
      adv_ws( l->buffer, &position );           /* advance past whitespace */

#if INTENSIVE_DEBUG
      sprintf( bwb_ebuf, "in bwx_shell(): line number, command <%s>.",
	 l->buffer );
      bwb_debug( bwb_ebuf );
#endif
      nl();
      endwin(); /* Added by JBV 10/11/97 */
      if ( system( &( l->buffer[ position ] ) ) == 0 )
	 {
         refresh(); /* Added by JBV 10/11/97 */
         nonl();
	 ncu_setpos();
	 return TRUE;
	 }
      else
	 {
         refresh(); /* Added by JBV 10/11/97 */
         nonl();
	 ncu_setpos();
	 return FALSE;
	 }
      }
   }
Esempio n. 21
0
static int
op_oplevel(int level)
{
   int             precision;

   bwx_DEBUG(__FUNCTION__);

   /* set the precision */

   if ((precision = op_getprecision(level)) == OP_ERROR)
   {
      op_pulldown(2);
      sprintf(bwb_ebuf, "exp_operation(): failed to set precision.");
      bwb_error(bwb_ebuf);
      return FALSE;
   }
   /* precision is set correctly */

   else
   {

      switch (CURTASK exps[level].operation)
      {
      case OP_ADD:
         op_add(level, precision);
         break;

      case OP_SUBTRACT:
         op_subtract(level, precision);
         break;

      case OP_MULTIPLY:
         op_multiply(level, precision);
         break;

      case OP_DIVIDE:
         op_divide(level, precision);
         break;

      case OP_ASSIGN:
         op_assign(level, precision);
         break;

      case OP_EQUALS:
         op_equals(level, precision);
         break;

      case OP_LESSTHAN:
         op_lessthan(level, precision);
         break;

      case OP_GREATERTHAN:
         op_greaterthan(level, precision);
         break;

      case OP_LTEQ:
         op_lteq(level, precision);
         break;

      case OP_GTEQ:
         op_gteq(level, precision);
         break;

      case OP_NOTEQUAL:
         op_notequal(level, precision);
         break;

      case OP_MODULUS:
         op_modulus(level, precision);
         break;

      case OP_INTDIVISION:
         op_intdiv(level, precision);
         break;

      case OP_OR:
         op_or(level, precision);
         break;

      case OP_AND:
         op_and(level, precision);
         break;

      case OP_NOT:
         op_not(level, precision);
         break;

      case OP_XOR:
         op_xor(level, precision);
         break;

      case OP_IMPLIES:
         op_imp(level, precision);
         break;

      case OP_EQUIV:
         op_eqv(level, precision);
         break;

      case OP_EXPONENT:
         op_exponent(level, precision);
         break;

      case OP_NEGATION: /* JBV */
         op_negation(level, precision);
         break;

      case OP_POSATION:
         op_posation(level, precision);
         break;

      default:
         sprintf(bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported.", CURTASK exps[level].operation);
         op_pulldown(2);
         bwb_error(bwb_ebuf);
         return FALSE;
         break;
      }     /* end of case statement for operators */
   }        /* end of else statement, precision set */

   return TRUE;

}           /* end of function op_oplevel() */
Esempio n. 22
0
int
exp_numconst(char *expression)
{
   int             base;   /* numerical base for the constant */
   static struct bwb_variable mantissa;   /* mantissa of floating-point
                   * number */
   static int      init = FALSE; /* is mantissa variable initialized? */
   int             exponent;  /* exponent for floating point number */
   int             man_start; /* starting point of mantissa */
   int             s_pos;  /* position in build string */
   int             build_loop;
   int             need_pm;
   unsigned int    u;

   bwx_DEBUG(__FUNCTION__);

   /* initialize the variable if necessary */


   if (init == FALSE)
   {
      init = TRUE;
      var_make(&mantissa, NUMBER);
   }
   /* be sure that the array_pos[ 0 ] for mantissa is set to dim_base;
    * this is necessary because mantissa might be used before dim_base
    * is set */

   mantissa.array_pos[0] = dim_base;


   need_pm = FALSE;
   CURTASK         exps[CURTASK expsc].nval = 0;

   /* check the first character(s) to determine numerical base and
    * starting point of the mantissa */

   switch (expression[0])
   {
   case '-':
   case '+':
   case '0':
   case '1':
   case '2':
   case '3':
   case '4':
   case '5':
   case '6':
   case '7':
   case '8':
   case '9':
   case '.':
      base = 10;  /* decimal constant */
      man_start = 0; /* starts at position 0 */
      need_pm = FALSE;
      break;
   case '&':      /* hex or octal constant */
      if ((expression[1] == 'H') || (expression[1] == 'h'))
      {
         base = 16;  /* hexadecimal constant */
         man_start = 2; /* starts at position 2 */
      }
      else
      {
         base = 8;   /* octal constant */
         if ((expression[1] == 'O') || (expression[1] == 'o'))
         {
            man_start = 2; /* starts at position 2 */
         }
         else
         {
            man_start = 1; /* starts at position 1 */
         }
      }
      break;
   default:

      sprintf(bwb_ebuf, "expression <%s> is not a numerical constant.",
         expression);
      bwb_error(bwb_ebuf);
      return OP_NULL;
   }

   /* now build the mantissa according to the numerical base */

   switch (base)
   {

   case 10:    /* decimal constant */

      /* initialize counters */

      CURTASK exps[CURTASK expsc].pos_adv = man_start;
      CURTASK         exps[CURTASK expsc].type = NUMBER;
      CURTASK         exps[CURTASK expsc].string[0] = '\0';
      s_pos = 0;
      exponent = OP_NULL;
      build_loop = TRUE;

      /* loop to build the string */

      while (build_loop == TRUE)
      {
         switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
         {
         case '-':   /* prefixed plus or minus */
         case '+':

            /* in the first position, a plus or minus
             * sign can be added to the beginning of the
             * string to be scanned */

            if (CURTASK exps[CURTASK expsc].pos_adv == man_start)
            {
               CURTASK         exps[CURTASK expsc].string[s_pos] = expression[CURTASK exps[CURTASK expsc].pos_adv];
               ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                               * character */
               ++s_pos;
               CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
            }
            /* but in any other position, the plus or
             * minus sign must be taken as an operator
             * and thus as terminating the string to be
             * scanned */

            else
            {
               build_loop = FALSE;
            }
            break;
         case '.':   /* note at least single precision */
         case '0':   /* or ordinary digit */
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
            CURTASK exps[CURTASK expsc].string[s_pos] = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                            * character */
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
            break;

         case BasicDoubleSuffix: /* Microsoft-type
                      * precision indicator;
                      * ignored but
                      * terminates */
         case BasicSingleSuffix: /* Microsoft-type
                      * precision indicator;
                      * ignored but
                      * terminates */
         case BasicCurrencySuffix:  /* Microsoft-type
                      * precision indicator;
                      * ignored but
                      * terminates */
         case BasicLongSuffix:   /* Microsoft-type precision
                   * indicator; ignored but
                   * terminates */
         case BasicIntegerSuffix:   /* Microsoft-type
                      * precision indicator;
                      * ignored but
                      * terminates */
            ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                            * character */
            CURTASK         exps[CURTASK expsc].type = NUMBER;
            exponent = FALSE;
            build_loop = FALSE;
            break;

         case 'E':   /* exponential, single precision */
         case 'e':
            ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                            * character */
            CURTASK         exps[CURTASK expsc].type = NUMBER;
            exponent = TRUE;
            build_loop = FALSE;
            break;

         case 'D':   /* exponential, double precision */
         case 'd':
            ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                            * character */
            CURTASK         exps[CURTASK expsc].type = NUMBER;
            exponent = TRUE;
            build_loop = FALSE;
            break;

         default: /* anything else, terminate */
            build_loop = FALSE;
            break;
         }

      }

      /* assign the value to the mantissa variable */

      sscanf(CURTASK exps[CURTASK expsc].string, BasicNumberScanFormat,
             var_findnval(&mantissa, mantissa.array_pos));


      /* test if integer bounds have been exceeded */

      if (CURTASK exps[CURTASK expsc].type == NUMBER)
      {
         int             i;
         BasicNumberType d;

         i = (int) var_getnval(&mantissa);
         d = (BasicNumberType) i;
         if (d != var_getnval(&mantissa))
         {
            CURTASK         exps[CURTASK expsc].type = NUMBER;
         }
      }
      /* read the exponent if there is one */

      if (exponent == TRUE)
      {

         /* allow a plus or minus once at the beginning */

         need_pm = TRUE;

         /* initialize counters */

         CURTASK         exps[CURTASK expsc].string[0] = '\0';
         s_pos = 0;
         build_loop = TRUE;

         /* loop to build the string */

         while (build_loop == TRUE)
         {
            switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
            {
            case '-':   /* prefixed plus or minus */
            case '+':

               if (need_pm == TRUE) /* only allow once */
               {
                  CURTASK         exps[CURTASK expsc].string[s_pos] = expression[CURTASK exps[CURTASK expsc].pos_adv];
                  ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                                  * character */
                  ++s_pos;
                  CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
               }
               else
               {
                  build_loop = FALSE;
               }
               break;

            case '0':   /* or ordinary digit */
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':

               CURTASK exps[CURTASK expsc].string[s_pos] = expression[CURTASK exps[CURTASK expsc].pos_adv];
               ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                               * character */
               ++s_pos;
               CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
               need_pm = FALSE;
               break;

            default: /* anything else, terminate */
               build_loop = FALSE;
               break;
            }

         }  /* end of build loop for exponent */

         /* assign the value to the user variable */

         sscanf(CURTASK exps[CURTASK expsc].string, BasicNumberScanFormat,
                &(CURTASK exps[CURTASK expsc].nval));


      }     /* end of exponent search */
      if (CURTASK exps[CURTASK expsc].nval == 0)
      {
         CURTASK         exps[CURTASK expsc].nval = var_getnval(&mantissa);
      }
      else
      {
         CURTASK         exps[CURTASK expsc].nval = var_getnval(&mantissa)
         * pow(10.0, CURTASK exps[CURTASK expsc].nval);
      }

      break;

   case 8:     /* octal constant */

      /* initialize counters */

      CURTASK exps[CURTASK expsc].pos_adv = man_start;
      CURTASK         exps[CURTASK expsc].type = NUMBER;
      CURTASK         exps[CURTASK expsc].string[0] = '\0';
      s_pos = 0;
      exponent = OP_NULL;
      build_loop = TRUE;

      /* loop to build the string */

      while (build_loop == TRUE)
      {
         switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
         {
         case '0':   /* or ordinary digit */
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
            CURTASK exps[CURTASK expsc].string[s_pos] = expression[CURTASK exps[CURTASK expsc].pos_adv];
            ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                            * character */
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
            break;

         default: /* anything else, terminate */
            build_loop = FALSE;
            break;
         }

      }

      /* now scan the string to determine the number */

      sscanf(CURTASK exps[CURTASK expsc].string, "%o", &u);
      CURTASK         exps[CURTASK expsc].nval = u;

      break;

   case 16:    /* hexadecimal constant */

      /* initialize counters */

      CURTASK exps[CURTASK expsc].pos_adv = man_start;
      CURTASK         exps[CURTASK expsc].type = NUMBER;
      CURTASK         exps[CURTASK expsc].string[0] = '\0';
      s_pos = 0;
      exponent = OP_NULL;
      build_loop = TRUE;

      /* loop to build the string */

      while (build_loop == TRUE)
      {
         switch (expression[CURTASK exps[CURTASK expsc].pos_adv])
         {
         case '0':   /* or ordinary digit */
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
         case 'A':
         case 'a':
         case 'B':
         case 'b':
         case 'C':
         case 'c':
         case 'D':
         case 'd':
         case 'E':
         case 'e':
         case 'F':   /* Don't forget these! (JBV) */
         case 'f':
            CURTASK exps[CURTASK expsc].string[s_pos] = expression[CURTASK exps[CURTASK expsc].pos_adv];

            ++CURTASK exps[CURTASK expsc].pos_adv; /* advance to next
                            * character */
            ++s_pos;
            CURTASK         exps[CURTASK expsc].string[s_pos] = '\0';
            break;

         default: /* anything else, terminate */
            build_loop = FALSE;
            break;
         }

      }

      /* now scan the string to determine the number */

      sscanf(CURTASK exps[CURTASK expsc].string, "%x", &u);
      CURTASK         exps[CURTASK expsc].nval = u;
      break;
   }

   /* note that the operation at this level is now a determined NUMBER */

   CURTASK         exps[CURTASK expsc].operation = NUMBER;


   return TRUE;

}
Esempio n. 23
0
static int
op_exponent(int level, int precision)
{

   bwx_DEBUG(__FUNCTION__);


   switch (precision)
   {
   case STRING:

      /* both sides of the operation should be numbers for string
       * addition; if not, report an error */

      sprintf(bwb_ebuf, "Strings cannot be taken as exponents.");
      bwb_error(bwb_ebuf);
      return FALSE;

      break;

   case NUMBER:
      if (TRUE)
      {
         /* N = X ^ Y */
         BasicNumberType X;
         BasicNumberType Y;
         BasicNumberType N;

         X = exp_getnval(&(CURTASK exps[level - 1]));
         Y = exp_getnval(&(CURTASK exps[level + 1]));

         if (X < 0 && Y != (int) Y)
         {
            /*** FATAL ***/
            /* - Evaluation of the operation of
             * involution results in a nega- tive number
             * being raised to a non-integral power
             * (fatal). */
            N = 0;
            bwb_error("NEGATIVE QUANTITY RAISED TO A NON-INTEGRAL POWER");
            return FALSE;
         }
         else
         if (X == 0 && Y < 0)
         {
            /* - Evaluation of the operation of
             * involution results in a zero be- ing
             * raised to a negative value (nonfatal, the
             * recommended re- covery procedure is to
             * supply positive machine infinity and
             * continue). */

            N = (DBL_MAX);
            bwb_Warning_Overflow("*** Arithmetic Overflow ***");
         }
         else
         {
            N = pow(X, Y);
         }
         CURTASK         exps[level - 1].nval = N;
      }
      break;

   }

   /* set variable to requested precision */

   CURTASK         exps[level - 1].type = (char) precision;
   CURTASK         exps[level - 1].operation = NUMBER;

   /* decrement the stack twice */

   op_pulldown(2);

   return TRUE;

}