⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bwb_var.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
      v->name, v->type, v->dimensions );   bwb_debug( bwb_ebuf );   getchar();#endif   return v;   }/***************************************************************        FUNCTION:       var_new()	DESCRIPTION:    This function assigns memory for a new variable.***************************************************************/#if ANSI_Cstruct bwb_variable *var_new( char *name )#elsestruct bwb_variable *var_new( name )   char *name;#endif   {   struct bwb_variable *v;   /* get memory for new variable */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( v = (struct bwb_variable *) CALLOC( 1, sizeof( struct bwb_variable ), "var_new" ))      == NULL )      {      bwb_error( err_getmem );      return NULL;      }   /* copy the name into the appropriate structure */   strcpy( v->name, name );   /* set memory in the new variable */   var_make( v, (int) v->name[ strlen( v->name ) - 1 ] );   /* and return */   return v;   }/***************************************************************        FUNCTION:       bwb_isvar()	DESCRIPTION:    This function determines if the string			in 'buffer' is the name of a previously-			existing variable.***************************************************************/#if ANSI_Cintbwb_isvar( char *buffer )#elseintbwb_isvar( buffer )   char *buffer;#endif   {   struct bwb_variable *v;   /* run through the variable list and try to find a match */   for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )      {      if ( strcmp( v->name, buffer ) == 0 )         {         return TRUE;         }      }   /* search failed */   return FALSE;   }/***************************************************************	FUNCTION:       var_getnval()	DESCRIPTION:    This function returns the current value of			the variable argument as a number.***************************************************************/#if ANSI_Cbnumbervar_getnval( struct bwb_variable *nvar )#elsebnumbervar_getnval( nvar )   struct bwb_variable *nvar;#endif   {   switch( nvar->type )      {      case NUMBER:         return *( var_findnval( nvar, nvar->array_pos ) );      }#if PROG_ERRORS   sprintf( bwb_ebuf, "in var_getnval(): type is <%d>=<%c>.",      nvar->type, nvar->type );   bwb_error( bwb_ebuf );#else   bwb_error( err_mismatch );#endif   return (bnumber) 0.0;   }/***************************************************************	FUNCTION:       var_getsval()	DESCRIPTION:    This function returns the current value of			the variable argument as a pointer to a BASIC			string structure.***************************************************************/#if ANSI_Cbstring *var_getsval( struct bwb_variable *nvar )#elsebstring *var_getsval( nvar )   struct bwb_variable *nvar;#endif   {   static bstring b;   b.rab = FALSE;   switch( nvar->type )      {      case STRING:	 return var_findsval( nvar, nvar->array_pos );      case NUMBER:	 sprintf( bwb_ebuf, "%*f ", prn_precision( nvar ),	    *( var_findnval( nvar, nvar->array_pos ) ) );	 str_ctob( &b, bwb_ebuf );	 return &b;      default:#if PROG_ERRORS	 sprintf( bwb_ebuf, "in var_getsval(): type is <%d>=<%c>.",	    nvar->type, nvar->type );	 bwb_error( bwb_ebuf );#else	 bwb_error( err_mismatch );#endif	 return NULL;      }   }/***************************************************************	FUNCTION:	bwb_dim()	DESCRIPTION:	This function implements the BASIC DIM			statement, allocating memory for a			dimensioned array of variables.	SYNTAX:		DIM variable(elements...)[variable(elements...)]...***************************************************************/#if ANSI_Cstruct bwb_line *bwb_dim( struct bwb_line *l )#elsestruct bwb_line *bwb_dim( l )   struct bwb_line *l;#endif   {   register int n;   static int n_params;                         /* number of parameters */   static int *pp;                              /* pointer to parameter values */   struct bwb_variable *newvar;   bnumber *np;   int loop;   int old_name, old_dimensions;   char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_dim(): entered function." );   bwb_debug( bwb_ebuf );#endif   loop = TRUE;   while ( loop == TRUE )      {      old_name = FALSE;      /* Get variable name */      adv_ws( l->buffer, &( l->position ) );      bwb_getvarname( l->buffer, tbuf, &( l->position ) );      /* check for previously used variable name */      if ( bwb_isvar( tbuf ) == TRUE )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_dim(): variable name is already used.",            l->number );         bwb_debug( bwb_ebuf );#endif         old_name = TRUE;         }      /* get the new variable */      newvar = var_find( tbuf );#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_dim(): new variable name is <%s>.",         newvar->name );      bwb_debug( bwb_ebuf );#endif      /* note that DIM has been called */      dimmed = TRUE;      /* read parameters */      old_dimensions = newvar->dimensions;      dim_getparams( l->buffer, &( l->position ), &n_params, &pp );      newvar->dimensions = n_params;      /* Check parameters for an old variable name */      if ( old_name == TRUE )         {         /* check to be sure the number of dimensions is the same */         if ( newvar->dimensions != old_dimensions )            {#if PROG_ERRORS            sprintf( bwb_ebuf, "in bwb_dim(): variable <%s> cannot be re-dimensioned",               newvar->name );            bwb_error( bwb_ebuf );#else            bwb_error( err_redim );#endif            }         /* check to be sure sizes for the old variable are the same */         for ( n = 0; n < newvar->dimensions; ++n )            {#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in bwb_dim(): old var <%s> parameter <%d> size <%d>.",               newvar->name, n, pp[ n ] );            bwb_debug( bwb_ebuf );#endif            if ( ( pp[ n ] + ( 1 - dim_base )) != newvar->array_sizes[ n ] )               {#if PROG_ERRORS               sprintf( bwb_ebuf, "in bwb_dim(): variable <%s> parameter <%d> cannot be resized",                  newvar->name, n );               bwb_error( bwb_ebuf );#else               bwb_error( err_redim );#endif               }            }         }         /* end of conditional for old variable */      /* a new variable */      else         {         /* assign memory for parameters */         /* Revised to CALLOC pass-thru call by JBV */         if ( ( newvar->array_sizes = (int *) CALLOC( n_params, sizeof( int ), "bwb_dim"  )) == NULL )            {#if PROG_ERRORS            sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_sizes for <%s>",               l->number, newvar->name );            bwb_error( bwb_ebuf );#else            bwb_error( err_getmem );#endif            return bwb_zline( l );            }         for ( n = 0; n < newvar->dimensions; ++n )            {            newvar->array_sizes[ n ] = pp[ n ] + ( 1 - dim_base );#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in bwb_dim(): array_sizes dim <%d> value <%d>",               n, newvar->array_sizes[ n ] );            bwb_debug( bwb_ebuf );#endif            }         /* assign memory for current position */         /* Revised to CALLOC pass-thru call by JBV */         if ( ( newvar->array_pos = (int *) CALLOC( n_params, sizeof( int ), "bwb_dim" )) == NULL )            {#if PROG_ERRORS            sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_pos for <%s>",               l->number, newvar->name );            bwb_error( bwb_ebuf );#else            bwb_error( err_getmem );#endif            return bwb_zline( l );            }         for ( n = 0; n < newvar->dimensions; ++n )            {            newvar->array_pos[ n ] = dim_base;            }         /* calculate the array size */	 newvar->array_units = (size_t) MAXINTSIZE;	/* avoid error in dim_unit() */	 newvar->array_units = dim_unit( newvar, pp ) + 1;#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_dim(): array memory requires <%ld> units",            (long) newvar->array_units );         bwb_debug( bwb_ebuf );#endif         /* assign array memory */         switch( newvar->type )            {            case STRING:#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in bwb_dim(): 1 STRING requires <%ld> bytes",                  (long) sizeof( bstring ));               bwb_debug( bwb_ebuf );               sprintf( bwb_ebuf, "in bwb_dim(): STRING array memory requires <%ld> bytes",        	  (long) ( newvar->array_units + 1 ) * sizeof( bstring ));               bwb_debug( bwb_ebuf );#endif               /*------------------------------------------------------*/               /* memnum, not memstr, was used here -- incorrect (JBV) */               /* Revised to CALLOC pass-thru call by JBV              */               /*------------------------------------------------------*/               if ( ( newvar->memstr = (bstring *)                  CALLOC( newvar->array_units, sizeof( bstring), "bwb_dim" )) == NULL )               {#if PROG_ERRORS                  sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>",                     l->number, newvar->name );                  bwb_error( bwb_ebuf );#else                  bwb_error( err_getmem );#endif                  return bwb_zline( l );                  }               break;            case NUMBER:#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in bwb_dim(): 1 DOUBLE requires <%ld> bytes",                  (long) sizeof( double ));               bwb_debug( bwb_ebuf );               sprintf( bwb_ebuf, "in bwb_dim(): DOUBLE array memory requires <%ld> bytes",        	  (long) ( newvar->array_units + 1 ) * sizeof( double ));               bwb_debug( bwb_ebuf );#endif               /* Revised to CALLOC pass-thru call by JBV */               if ( ( np = (bnumber *)                  CALLOC( newvar->array_units, sizeof( bnumber ), "bwb_dim" )) == NULL )                  {#if PROG_ERRORS                  sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>",                  l->number, newvar->name );                  bwb_error( bwb_ebuf );#else                  bwb_error( err_getmem );#endif                  return bwb_zline( l );                  }	       newvar->memnum = np;	       break;	    default:#if PROG_ERRORS               sprintf( bwb_ebuf, "in line %d: New variable has unrecognized type.",                  l->number );               bwb_error( bwb_ebuf );#else               bwb_error( err_syntax );#endif               return bwb_zline( l );            }         }			/* end of conditional for new variable */      /* now check for end of string */      if ( l->buffer[ l->position ] == ')' )         {         ++( l->position );         }      adv_ws( l->buffer, &( l->position ));      switch( l->buffer[ l->position ] )         {         case '\n':			/* end of line */         case '\r':         case ':':			/* end of line segment */         case '\0':			/* end of string */            loop = FALSE;            break;         case ',':            ++( l->position );            adv_ws( l->buffer, &( l->position ) );            loop = TRUE;            break;         default:#if PROG_ERRORS            sprintf( bwb_ebuf, "in bwb_dim(): unexpected end of string, buf <%s>",               &( l->buffer[ l->position ] ) );            bwb_error( bwb_ebuf );#else            bwb_error( err_syntax );#endif            loop = FALSE;            break;         }      }				/* end of loop through variables */   /* return */   return bwb_zline( l );   }/***************************************************************        FUNCTION:       dim_unit()        DESCRIPTION:    This function calculates the unit        		position for an array.***************************************************************/#if ANSI_Cstatic size_tdim_unit( struct bwb_variable *v, int *pp )#elsestatic size_tdim_unit( v, pp )   struct bwb_variable *v;   int *pp;#endif   {   size_t r;   size_t b;   register int n;   /* Calculate and return the address of the dimensioned array */   b = 1;   r = 0;   for ( n = 0; n < v->dimensions; ++n )      {      r += b * ( pp[ n ] - dim_base );      b *= v->array_sizes[ n ];      }#if INTENSIVE_DEBUG   for ( n = 0; n < v->dimensions; ++n )      {      sprintf( bwb_ebuf,         "in dim_unit(): variable <%s> pos <%d> val <%d>.",         v->name, n, pp[ n ] );      bwb_debug( bwb_ebuf );      }   sprintf( bwb_ebuf, "in dim_unit(): return unit: <%ld>", (long) r );   bwb_debug( bwb_ebuf );#endif   if ( r > v->array_units )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in dim_unit(): unit value <%ld> exceeds array units <%ld>",         r, v->array_units );      bwb_error( bwb_ebuf );#else      bwb_error( err_valoorange );#endif      return 0;      }   return r;   }/***************************************************************        FUNCTION:       dim_getparams()	DESCRIPTION:    This function reads a string in <buffer>                        beginning at position <pos> and finds a                        list of parameters surrounded by paren-                        theses, returning in <n_params> the number                        of parameters found, and returning in                        <pp> an array of n_params integers giving                        the sizes for each dimension of the array.***************************************************************/#if ANSI_Cintdim_getparams( char *buffer, int *pos, int *n_params, int **pp )#elseintdim_getparams( buffer, pos, n_params, pp )   char *buffer;   int *pos;   int *n_params;   int **pp;#endif   {   int loop;   static int params[ MAX_DIMS ];   int x_pos, s_pos;   struct exp_ese *e;   char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG   register int n;#endif   /* set initial values */   *n_params = 0;#if OLDSTUFF   paren_found = FALSE;#endif   /* advance and check for undimensioned variable */   adv_ws( buffer, pos );   if ( buffer[ *pos ] != '(' )      {      *n_params = 1;      params[ 0 ] = dim_base;      *pp = params;      return TRUE;      }   else      {      ++(*pos);      }   /* Variable has DIMensions: Find each parameter */   s_pos = 0;   tbuf[ 0 ] = '\0';   loop = TRUE;   while( loop == TRUE )      {      switch( buffer[ *pos ] )         {         case ')':                      /* end of parameter list */            x_pos = 0;            if ( tbuf[ 0 ] == '\0' )               {               params[ *n_params ] = DEF_SUBSCRIPT;               }            else               {#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in dim_getparams(): call bwb_exp() for last element" );               bwb_debug( bwb_ebuf );#endif               e = bwb_exp( tbuf, FALSE, &x_pos );#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in dim_getparams(): return from bwb_exp() for last element" );               bwb_debug( bwb_ebuf );#endif               params[ *n_params ] = (int) exp_getnval( e );               }            ++(*n_params);            loop = FALSE;            ++( *pos );            break;         case ',':                      /* end of a parameter */            x_pos = 0;            if ( tbuf[ 0 ] == '\0' )               {               params[ *n_params ] = DEF_SUBSCRIPT;               }            else               {#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in dim_getparams(): call bwb_exp() for element (not last)" );               bwb_debug( bwb_ebuf );#endif               e = bwb_exp( tbuf, FALSE, &x_pos );               params[ *n_params ] = (int) exp_getnval( e );               }            ++(*n_params);            tbuf[ 0 ] = '\0';            ++(*pos);            s_pos = 0;            break;         case ' ':                      /* whitespace -- skip */         case '\t':            ++(*pos);            break;         default:            tbuf[ s_pos ] = buffer[ *pos ];            ++(*pos);            ++s_pos;            tbuf[ s_pos ] = '\0';            break;         }      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -