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

📄 bwb_cnd.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
            bwb_debug( bwb_ebuf );#endif            if ( c_level == 0 )               {               return current;               }            }         }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "SELECT without CASE" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }/***************************************************************        FUNCTION:       find_case()        DESCRIPTION:    This function searches for a line containing                        an END SELECT statement corresponding to a previous                        SELECT CASE statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_endselect( struct bwb_line *l )#elsestatic struct bwb_line *find_endselect( l )   struct bwb_line *l;#endif   {   struct bwb_line *current;   register int c_level;   int position;   c_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_select )            {            ++c_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_case(): found SELECT at line %d, level %d",               current->number, c_level );            bwb_debug( bwb_ebuf );#endif            }         else if ( is_endselect( current ) == TRUE )            {            --c_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_endif(): found END SELECT at line %d, level %d",               current->number, c_level );            bwb_debug( bwb_ebuf );#endif            if ( c_level == 0 )               {               return current;               }            }         }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "SELECT without END SELECT" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }/***************************************************************	FUNCTION:       is_endselect()	DESCRIPTION:    This C function attempts to determine if			a given line contains an END SELECT statement.***************************************************************/#if ANSI_Cstatic intis_endselect( struct bwb_line *l )#elsestatic intis_endselect( l )   struct bwb_line *l;#endif   {   int position;   char tbuf[ MAXVARNAMESIZE + 1];   if ( bwb_cmdtable[ l->cmdnum ].vector != bwb_xend )      {      return FALSE;      }   position = l->startpos;   adv_ws( l->buffer, &position );   adv_element( l->buffer, &position, tbuf );   bwb_strtoupper( tbuf );   if ( strcmp( tbuf, "SELECT" ) == 0 )      {      return TRUE;      }   return FALSE;   }/***************************************************************        FUNCTION:       bwb_endselect()        DESCRIPTION:    This function handles the BASIC END                        SELECT statement.	SYNTAX:		END SELECT***************************************************************/#if ANSI_Cstruct bwb_line *bwb_endselect( struct bwb_line *l )#elsestruct bwb_line *bwb_endselect( l )   struct bwb_line *l;#endif   {#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_endselect(): entered function" );   bwb_debug( bwb_ebuf );#endif   if (  ( CURTASK excs[ CURTASK exsc ].code != EXEC_SELTRUE  )      && ( CURTASK excs[ CURTASK exsc ].code != EXEC_SELFALSE ))      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_endselect(): END SELECT without SELECT" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      }   bwb_decexec();#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ));#endif   return bwb_zline( l );   }#endif				/* STRUCT_CMDS */#if COMMON_CMDS || STRUCT_CMDS/***    WHILE-WEND ***//***************************************************************        FUNCTION:       bwb_while()        DESCRIPTION:    This function handles the BASIC WHILE			statement and also the ANSI DO WHILE			statement.	SYNTAX:		WHILE expression			DO WHILE expression***************************************************************/#if ANSI_Cstruct bwb_line *bwb_while( struct bwb_line *l )#elsestruct bwb_line *bwb_while( l )   struct bwb_line *l;#endif   {   struct exp_ese *e;   struct bwb_line *r;   /* call bwb_exp() to interpret the expression */   e = bwb_exp( l->buffer, FALSE, &( l->position ) );   if ( (int) exp_getnval( e ) == TRUE )      {      /* if this is the first time at this WHILE statement, note it */      if ( CURTASK excs[ CURTASK exsc ].while_line != l )         {         bwb_incexec();         CURTASK excs[ CURTASK exsc ].while_line = l;         /* find the WEND statement (or LOOP statement) */#if STRUCT_CMDS	 if ( l->cmdnum == getcmdnum( CMD_DO ))            {	    CURTASK excs[ CURTASK exsc ].wend_line = find_loop( l );            }         else            {	    CURTASK excs[ CURTASK exsc ].wend_line = find_wend( l );	    }#else	 CURTASK excs[ CURTASK exsc ].wend_line = find_wend( l );#endif         if ( CURTASK excs[ CURTASK exsc ].wend_line == NULL )            {            return bwb_zline( l );            }#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_while(): initialize WHILE loop, line <%d>",            l->number );         bwb_debug( bwb_ebuf );#endif         }#if INTENSIVE_DEBUG      else         {         sprintf( bwb_ebuf, "in bwb_while(): return to WHILE loop, line <%d>",            l->number );         bwb_debug( bwb_ebuf );         }#endif      bwb_setexec( l, l->position, EXEC_WHILE );      return bwb_zline( l );      }   else      {      CURTASK excs[ CURTASK exsc ].while_line = NULL;      r = CURTASK excs[ CURTASK exsc ].wend_line;      bwb_setexec( r, 0, CURTASK excs[ CURTASK exsc - 1 ].code );      r->position = 0;      bwb_decexec();      return r;      }   }/***************************************************************        FUNCTION:       bwb_wend()        DESCRIPTION:    This function handles the BASIC WEND			statement and the LOOP statement ending			a DO WHILE loop.	SYNTAX:		WEND			LOOP***************************************************************/#if ANSI_Cstruct bwb_line *bwb_wend( struct bwb_line *l )#elsestruct bwb_line *bwb_wend( l )   struct bwb_line *l;#endif   {   /* check integrity of WHILE loop */   if ( CURTASK excs[ CURTASK exsc ].code != EXEC_WHILE )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_wend(): exec stack code != EXEC_WHILE" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      }   if ( CURTASK excs[ CURTASK exsc ].while_line == NULL )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_wend(): exec stack while_line == NULL" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      }   /* reset to the top of the current WHILE loop */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_wend() return to line <%d>",      CURTASK excs[ CURTASK exsc ].while_line->number );   bwb_debug( bwb_ebuf );#endif   CURTASK excs[ CURTASK exsc ].while_line->position = 0;   bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_WHILE );   return CURTASK excs[ CURTASK exsc ].while_line;   }/***************************************************************        FUNCTION:       find_wend()        DESCRIPTION:    This function searches for a line containing                        a WEND statement corresponding to a previous                        WHILE statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_wend( struct bwb_line *l )#elsestatic struct bwb_line *find_wend( 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_while )            {            ++w_level;#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in find_wend(): found WHILE at line %d, level %d",               current->number, w_level );            bwb_debug( bwb_ebuf );#endif            }         else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_wend )            {            --w_level;#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in find_wend(): found WEND at line %d, level %d",               current->number, w_level );            bwb_debug( bwb_ebuf );#endif            if ( w_level == 0 )               {               return current->next;               }            }         }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "in find_wend(): WHILE without WEND" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }#if STRUCT_CMDS/***************************************************************	FUNCTION:       find_loop()	DESCRIPTION:    This function searches for a line containing			a LOOP statement corresponding to a previous			DO statement.***************************************************************/#if ANSI_Cextern struct bwb_line *find_loop( struct bwb_line *l )#elseextern struct bwb_line *find_loop( 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_do )	    {	    ++w_level;#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in find_loop(): found DO at line %d, level %d",	       current->number, w_level );	    bwb_debug( bwb_ebuf );#endif	    }	 else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_loop )	    {	    --w_level;#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in fnd_loop(): found LOOP at line %d, level %d",	       current->number, w_level );	    bwb_debug( bwb_ebuf );#endif	    if ( w_level == 0 )	       {	       return current->next;	       }	    }	 }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "in find_loop(): DO without LOOP" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }#endif                          /* STRUCT_CMDS */#endif                          /* COMMON_CMDS || STRUCT_CMDS *//***    FOR-NEXT ***//***************************************************************        FUNCTION:       bwb_for()        DESCRIPTION:    This function handles the BASIC FOR                        statement.	SYNTAX:		FOR counter = start TO finish [STEP increment]***************************************************************/#if ANSI_Cstruct bwb_line *bwb_for( struct bwb_line *l )#elsestruct bwb_line *bwb_for( l )   struct bwb_line *l;#endif   {   register int n;   int e, loop;   int to, step, p;   int for_step, for_target;   struct exp_ese *exp;   struct bwb_variable *v;   char tbuf[ MAXSTRINGSIZE + 1 ];   /* get the variable name */   exp_getvfname( &( l->buffer[ l->position ] ), tbuf );   l->position += strlen( tbuf );   v = var_find( tbuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): variable name <%s>.", v->name );   bwb_debug( bwb_ebuf );#endif   /*--------------------------------------------------------------*/   /* 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                                                 */   /*--------------------------------------------------------------*/   if (v == CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec();   /* at this point one should find an equals sign ('=') */   adv_ws( l->buffer, &( l->position ) );   if ( l->buffer[ l->position ] != '=' )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_for(): failed to find equals sign, buf <%s>",         &( l->buffer[ l->position ] ) );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      return bwb_zline( l );      }   else      {      ++( l->position );      }   /* Find the TO and STEP statements */   cnd_tostep( l->buffer, l->position, &to, &step );   /* if there is no TO statement, then an error has ocurred */   if ( to < 1 )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "FOR statement without TO" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax  );#endif      return bwb_zline( l );      }   /* copy initial value to buffer and evaluate it */   tbuf[ 0 ] = '\0';   p = 0;   for ( n = l->position; n < to; ++n )      {      tbuf[ p ] = l->buffer[ n ];      ++p;      ++l->position;      tbuf[ p ] = '\0';      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_for(): initial value string <%s>",      tbuf );   bwb_debug( bwb_ebuf );#endif   p = 0;   exp = bwb_exp( tbuf, FALSE, &p );

⌨️ 快捷键说明

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