Exemplo n.º 1
0
void
main( int argc, char **argv )
   {
#if MS_CMDS
   struct videoconfig vc;
   short videomode;

   /* Save original foreground, background, and text position. */

   _getvideoconfig( &vc );
   oldfgd = _gettextcolor();
   oldbgd = _getbkcolor();

   if ( vc.mode != _TEXTC80 )
      {
      if ( _setvideomode( _TEXTC80 ) == 0 )
         {
	 _getvideoconfig( &vc );
	 prn_xprintf( stderr, "Failed to set color video mode\n" );
         }
      else
	 {
	 reset_mode = FALSE;
	 }
      }
   else
      {
      reset_mode = FALSE;
      }

#endif       /* MS_CMDS */

   bwb_init( argc, argv );

#if INTERACTIVE
   setjmp( mark );
#endif

   /* now set the number of colors available */

   * var_findnval( co, co->array_pos ) = (bnumber) vc.numcolors;

   /* main program loop */

   while( !feof( stdin ) )		/* condition !feof( stdin ) added in v1.11 */
      {
      bwb_mainloop();
      }

   }
Exemplo n.º 2
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;

}
Exemplo n.º 3
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;
      }
   }
Exemplo n.º 4
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;

}