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

📄 bwb_cnd.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
   var_setnval( v, exp_getnval( exp ) );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): initial value <%d> pos <%d>",      exp_getnval( exp ), l->position );   bwb_debug( bwb_ebuf );#endif   /* copy target value to small buffer and evaluate it */   tbuf[ 0 ] = '\0';   p = 0;   l->position = to + 2;   if ( step < 1 )      {      e = strlen( l->buffer );      }   else      {      e = step - 1;      }   loop = TRUE;   n = l->position;   while( loop == TRUE )      {      tbuf[ p ] = l->buffer[ n ];      ++p;      ++l->position;      tbuf[ p ] = '\0';      if ( n >= e )          {          loop = FALSE;          }      ++n;      if ( l->buffer[ n ] == ':' )         {         loop = FALSE;         }      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): target value string <%s>",      tbuf );   bwb_debug( bwb_ebuf );#endif   p = 0;   exp = bwb_exp( tbuf, FALSE, &p );   for_target = (int) exp_getnval( exp );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): target value <%d> pos <%d>",      exp_getnval( exp ), l->position );   bwb_debug( bwb_ebuf );#endif   /* If there is a STEP statement, copy it to a buffer      and evaluate it */   if ( step > 1 )      {      tbuf[ 0 ] = '\0';      p = 0;      l->position = step + 4;      for ( n = l->position; n < (int) strlen( l->buffer ); ++n )         {         tbuf[ p ] = l->buffer[ n ];         ++p;         ++l->position;         tbuf[ p ] = '\0';         }#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_for(): step value string <%s>",         tbuf );      bwb_debug( bwb_ebuf );#endif      p = 0;      exp = bwb_exp( tbuf, FALSE, &p );      for_step = (int) exp_getnval( exp );      }   else      {      for_step = 1;      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): step value <%d>",      for_step );   bwb_debug( bwb_ebuf );#endif   /* set position in current line and increment EXEC counter */   /* bwb_setexec( l, l->position, EXEC_NORM ); */  /* WRONG */   bwb_incexec();   CURTASK excs[ CURTASK exsc ].local_variable  = v;   CURTASK excs[ CURTASK exsc ].for_step   = for_step;   CURTASK excs[ CURTASK exsc ].for_target = for_target;   /* set exit line to be used by EXIT FOR */#if STRUCT_CMDS   CURTASK excs[ CURTASK exsc ].wend_line  = find_next( l );#endif   /* set top line and position to be used in multisegmented FOR-NEXT loop */#if MULTISEG_LINES   CURTASK excs[ CURTASK exsc ].for_line     = l;   CURTASK excs[ CURTASK exsc ].for_position = l->position;#endif#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): setting code to EXEC_FOR",      l->position );   bwb_debug( bwb_ebuf );#endif   bwb_setexec( l, l->position, EXEC_FOR );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): ready to exit, position <%d>",      l->position );   bwb_debug( bwb_ebuf );#endif   /* proceed with processing */   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_next()        DESCRIPTION:    This function handles the BASIC NEXT                        statement.	SYNTAX:		NEXT counter***************************************************************/#if ANSI_Cstruct bwb_line *bwb_next( struct bwb_line *l )#elsestruct bwb_line *bwb_next( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   struct bwb_variable *v; /* Relocated from INTENSIVE_DEBUG (JBV) */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_next(): entered function, cmdnum <%d> exsc level <%d> code <%d>",      l->cmdnum, CURTASK exsc, CURTASK excs[ CURTASK exsc ].code );   bwb_debug( bwb_ebuf );#endif   /* Check the integrity of the FOR statement */   if ( CURTASK excs[ CURTASK exsc ].code != EXEC_FOR )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_next(): NEXT without FOR; code is <%d> instead of <%d>",	 CURTASK excs[ CURTASK exsc ].code, EXEC_FOR );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      }   /* read the argument, if there is one */   /* Relocated from MULTISEG_LINES (JBV) */   exp_getvfname( &( l->buffer[ l->position ] ), tbuf );   if (strlen(tbuf) != 0)   {   /* Relocated from INTENSIVE_DEBUG (JBV) */   v = var_find( tbuf );#if MULTISEG_LINES                   /* not currently needed otherwise */   l->position += strlen( tbuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_next(): variable name detected <%s>.", v->name );   bwb_debug( bwb_ebuf );#endif#endif   /* decrement or increment the value */   /*--------------------------------------------------------------*/   /* Make sure we are in the right FOR-NEXT level!                */   /* If we aren't (which could happen for legit reasons), fix the */   /* exec stack.                                                  */   /* JBV, 9/20/95                                                 */   /*--------------------------------------------------------------*/   while (v != CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec();   }   var_setnval( CURTASK excs[ CURTASK exsc ].local_variable,      var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )      + (bnumber) CURTASK excs[ CURTASK exsc ].for_step );   /* check for completion of the loop */   if ( CURTASK excs[ CURTASK exsc ].for_step > 0 )            /* if step is positive */      {      if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )         > CURTASK excs[ CURTASK exsc ].for_target )         {         bwb_decexec();#if MULTISEG_LINES	 bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );#else	 bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );#endif#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_next(): end of loop" );	 bwb_debug( bwb_ebuf );#endif#ifdef OLD_WAY	 l->next->position = 0;	 return l->next;#else	 return bwb_zline( l );#endif         }      }   else                                         /* if step is negative */      {      if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable )         < CURTASK excs[ CURTASK exsc ].for_target )         {         bwb_decexec();	 bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_next(): end of loop" );	 bwb_debug( bwb_ebuf );#endif#ifdef OLD_WAY	 l->next->position = 0;	 return l->next;#else	 return bwb_zline( l );#endif         }      }   /* Target not reached: return to the top of the FOR loop */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_next(): resetting code to EXEC_FOR",      l->position );   bwb_debug( bwb_ebuf );#endif#if MULTISEG_LINES   CURTASK excs[ CURTASK exsc ].for_line->position      = CURTASK excs[ CURTASK exsc ].for_position;   bwb_setexec( CURTASK excs[ CURTASK exsc ].for_line,      CURTASK excs[ CURTASK exsc ].for_position, EXEC_FOR );   return CURTASK excs[ CURTASK exsc ].for_line; /* Added (JBV) */#else   bwb_setexec( CURTASK excs[ CURTASK exsc - 1 ].line,      CURTASK excs[ CURTASK exsc - 1 ].position, EXEC_FOR );   return CURTASK excs[ CURTASK exsc - 1 ].line; /* Relocated (JBV) */#endif   }#if STRUCT_CMDS/***************************************************************	FUNCTION:       bwb_exitfor()	DESCRIPTION:    This function handles the BASIC EXIT			FOR statement.  This is a structured			programming command compatible with ANSI			BASIC. It is called from the bwb_exit()			subroutine.	SYNTAX:		EXIT FOR			***************************************************************/#if ANSI_Cstruct bwb_line *bwb_exitfor( struct bwb_line *l )#elsestruct bwb_line *bwb_exitfor( l )   struct bwb_line *l;#endif   {   struct bwb_line *next_line;   int found;   register int level;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_exitfor(): entered subroutine" );   bwb_debug( bwb_ebuf );#endif   /* Check the integrity of the FOR statement */   found = FALSE;   level = CURTASK exsc;   do      {      if ( CURTASK excs[ level ].code == EXEC_FOR )	 {	 next_line = CURTASK excs[ CURTASK level ].wend_line;	 found = TRUE;	 }      else	 {	 --level;	 }      }   while ( ( level >= 0 ) && ( found == FALSE ) );   if ( found != TRUE )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_exitfor(): EXIT FOR without FOR" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      return bwb_zline( l );      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_exitfor(): level found is <%d>, current <%d>",      level, CURTASK exsc );   bwb_debug( bwb_ebuf );#endif   /* decrement below the level of the NEXT statement */   while( CURTASK exsc >= level )      {      bwb_decexec();      }   /* set the next line in the exec stack */   next_line->position = 0;   /* bwb_setexec( next_line, 0, EXEC_NORM ); */  /* WRONG (JBV) */   bwb_setexec( next_line, 0, CURTASK excs[ CURTASK exsc ].code ); /* JBV */   return next_line;   }/***************************************************************	FUNCTION:       find_next()	DESCRIPTION:    This function searches for a line containing			a NEXT statement corresponding to a previous			FOR statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_next( struct bwb_line *l )#elsestatic struct bwb_line *find_next( l )   struct bwb_line *l;#endif   {   struct bwb_line *current;   register int w_level;   int position;   w_level = 1;   for ( current = l->next; current != &CURTASK bwb_end; current = current->next )      {      position = 0;      if ( current->marked != TRUE )	 {	 line_start( current->buffer, &position, &( current->lnpos ),	    &( current->lnum ),	    &( current->cmdpos ),	    &( current->cmdnum ),	    &( current->startpos ) );	 }      current->position = current->startpos;      if ( current->cmdnum > -1 )	 {	 if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_for )	    {	    ++w_level;#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in find_next(): found FOR at line %d, level %d",	       current->number, w_level );	    bwb_debug( bwb_ebuf );#endif	    }	 else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_next )	    {	    --w_level;#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in find_next(): found NEXT at line %d, level %d",	       current->number, w_level );	    bwb_debug( bwb_ebuf );#endif	    if ( w_level == 0 )	       {#if INTENSIVE_DEBUG	       sprintf( bwb_ebuf, "in find_next(): found returning line <%d>",		  current->next->number );	       bwb_debug( bwb_ebuf );#endif	       return current->next;	       }	    }	 }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "FOR without NEXT" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }#endif				/* STRUCT_CMDS for EXIT FOR *//***************************************************************	FUNCTION:	cnd_tostep()	DESCRIPTION:	This function searches through the			<buffer> beginning at point <position>			and attempts to find positions of TO			and STEP statements.***************************************************************/#if ANSI_Cstatic intcnd_tostep( char *buffer, int position, int *to, int *step )#elsestatic intcnd_tostep( buffer, position, to, step )   char *buffer;   int position;   int *to;   int *step;#endif   {   int loop, t_pos, b_pos, p_word;   char tbuf[ MAXSTRINGSIZE + 1 ];   /* set then and els to FALSE initially */   *to = *step = FALSE;   /* loop to find words */   p_word = b_pos = position;   t_pos = 0;   tbuf[ 0 ] = '\0';   loop = TRUE;   while ( loop == TRUE )      {      switch( buffer[ b_pos ] )         {         case '\0':                     /* end of string */         case ':':			/* end of line segment */            return TRUE;         case ' ':                      /* whitespace = end of word */         case '\t':#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in cnd_tostep(): word is <%s>", tbuf );            bwb_debug( bwb_ebuf );#endif            if ( strncmp( tbuf, CMD_TO, (size_t) strlen( CMD_TO ) ) == 0 )               {#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in cnd_tostep(): TO found at position <%d>.",                  p_word );               bwb_debug( bwb_ebuf );#endif               *to = p_word;               }            else if ( strncmp( tbuf, CMD_STEP, (size_t) strlen( CMD_STEP ) ) == 0 )               {#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in cnd_tostep(): STEP found at position <%d>.",                  p_word );               bwb_debug( bwb_ebuf );#endif               *step = p_word;               }            ++b_pos;            p_word = b_pos;            t_pos = 0;            tbuf[ 0 ] = '\0';            break;         default:            if ( islower( buffer[ b_pos ] ) != FALSE )               {               tbuf[ t_pos ] = (char) toupper( buffer[ b_pos ] );               }            else               {               tbuf[ t_pos ] = buffer[ b_pos ];               }            ++b_pos;            ++t_pos;            tbuf[ t_pos ] = '\0';            break;         }      }   return TRUE;   }/***************************************************************	FUNCTION:       var_setnval()	DESCRIPTION:    This function sets the value of numerical			variable v to the value of i.***************************************************************/#if ANSI_Cextern intvar_setnval( struct bwb_variable *v, bnumber i )#elseintvar_setnval( v, i )   struct bwb_variable *v;   bnumber i;#endif   {   switch( v->type )      {      case NUMBER:         * var_findnval( v, v->array_pos ) = i;         break;      default:#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in var_setnval(): variable <%s> is not a number",            v->name );         bwb_error( bwb_ebuf );#else         bwb_error( err_mismatch );#endif      }   /* successful assignment */   return TRUE;   }

⌨️ 快捷键说明

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