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

📄 bwb_stc.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
      /* if a MAIN function was not found at level 0, then skip the subroutine */      else         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_sub(): found non-MAIN function at level 0" );         bwb_debug( bwb_ebuf );#endif         rline = find_endsub( l );         bwb_setexec( rline->next, 0, EXEC_CALLSUB );         rline->next->position = 0;         return rline->next;         }      }   /* check for integrity of CALL-SUB sequence if above level 0 */   else if ( CURTASK excs[ CURTASK exsc ].code != EXEC_CALLSUB )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_sub(): SUB without CALL" );      bwb_error( bwb_ebuf );#else      bwb_error( err_retnogosub );#endif      }   /* advance position */#if MULTISEG_LINES   adv_ws( l->buffer, &( l->position ));   adv_element( l->buffer, &( l->position ), tbuf );   f = fslt_findf( tbuf );   l->position = f->startpos;   return bwb_zline( l );#else   return bwb_zline( l );#endif   }/***************************************************************        FUNCTION:       find_endsub()        DESCRIPTION:    This function searches for a line containing                        an END SUB statement corresponding to a previous                        SUB statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_endsub( struct bwb_line *l )#elsestatic struct bwb_line *find_endsub( l )   struct bwb_line *l;#endif   {   struct bwb_line *current;   register int s_level;   int position;   s_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_sub )            {            ++s_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_endsub(): found SUB at line %d, level %d",               current->number, s_level );            bwb_debug( bwb_ebuf );#endif            }         else if ( is_endsub( current ) == TRUE )            {            --s_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_endsub(): found END SUB at line %d, level %d",               current->number, s_level );            bwb_debug( bwb_ebuf );#endif            if ( s_level == 0 )               {               return current;               }            }         }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "SUB without END SUB" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }/***************************************************************	FUNCTION:       is_endsub()	DESCRIPTION:    This function determines whether the			line buffer for line 'l' is positioned			at an END SUB statement.***************************************************************/#if ANSI_Cstatic intis_endsub( struct bwb_line *l )#elsestatic intis_endsub( 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, "SUB" ) == 0 )      {      return TRUE;      }   return FALSE;   }/***************************************************************        FUNCTION:       bwb_endsub()        DESCRIPTION:	This C function implements the BASIC			END SUB command, ending a subroutine			definition.  Because the command END			can have multiple meanings, this function			should be called from the bwb_xend()			function, which should be able to identify			an END SUB command.	SYNTAX:		END SUB***************************************************************/#if ANSI_Cstruct bwb_line *bwb_endsub( struct bwb_line *line )#elsestruct bwb_line *bwb_endsub( line )   struct bwb_line *line;#endif   {   struct bwb_variable *l;   register int c;   /* assign local variable values to calling variables */   l = CURTASK excs[ CURTASK exsc ].local_variable;   for ( c = 0; c < CURTASK excs[ CURTASK exsc ].n_cvs; ++c )      {      bwb_vtov( CURTASK excs[ CURTASK exsc ].calling_variable[ c ], l );      l = l->next;      }   /* decrement the EXEC stack counter */   bwb_decexec();   /* if the previous level was EXEC_MAIN,      then execution continues from this point */   if ( CURTASK excs[ CURTASK exsc + 1 ].code == EXEC_MAIN )      {      return bwb_zline( line );      }   /* else return next from old line */   CURTASK excs[ CURTASK exsc ].line->next->position = 0;   return CURTASK excs[ CURTASK exsc ].line->next;   }/***************************************************************	FUNCTION:	find_label()	DESCRIPTION:	This C function finds a program line that			begins with the label included in <buffer>.***************************************************************/#if ANSI_Cextern struct bwb_line *find_label( char *buffer )#elseextern struct bwb_line *find_label( buffer )   char *buffer;#endif   {   struct fslte *f;   for ( f = CURTASK fslt_start.next; f != & ( CURTASK fslt_end ); f = f->next )      {      if ( strcmp( buffer, f->name ) == 0 )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in find_label(): found label <%s>", buffer );         bwb_debug( bwb_ebuf );#endif         return f->line;         }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "in find_label(): failed to find label <%s>", buffer );   bwb_error( bwb_ebuf );#else   bwb_error( err_lnnotfound );#endif   return NULL;   }/***************************************************************	FUNCTION:       bwb_doloop()	DESCRIPTION:    This C function implements the ANSI BASIC			DO statement, when DO is not followed by			an argument.  It is called by bwb_do() in			bwb_cmd.c.	SYNTAX:		DO***************************************************************/#if ANSI_Cstruct bwb_line *bwb_doloop( struct bwb_line *l )#elsestruct bwb_line *bwb_doloop( l )   struct bwb_line *l;#endif   {   /* if this is the first time at this DO statement, note it */   if ( CURTASK excs[ CURTASK exsc ].while_line != l )      {      bwb_incexec();      CURTASK excs[ CURTASK exsc ].while_line = l;      /* find the LOOP statement */      CURTASK excs[ CURTASK exsc ].wend_line = find_loop( l );      if ( CURTASK excs[ CURTASK exsc ].wend_line == NULL )	 {	 return bwb_zline( l );	 }#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_doloop(): initialize DO loop, line <%d>",	 l->number );      bwb_debug( bwb_ebuf );#endif      }#if INTENSIVE_DEBUG   else      {      sprintf( bwb_ebuf, "in bwb_doloop(): return to DO loop, line <%d>",	 l->number );      bwb_debug( bwb_ebuf );      }#endif   bwb_setexec( l, l->position, EXEC_DO );   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_loop()	DESCRIPTION:    This C function implements the ANSI BASIC			LOOP statement.	SYNTAX:		LOOP [UNTIL expression]			***************************************************************/#if ANSI_Cstruct bwb_line *bwb_loop( struct bwb_line *l )#elsestruct bwb_line *bwb_loop( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_loop(): entered subroutine" );   bwb_debug( bwb_ebuf );#endif   /* If the current exec stack is set for EXEC_WHILE, then we      presume that this is a LOOP statement ending a DO WHILE      loop */   if ( CURTASK excs[ CURTASK exsc ].code == EXEC_WHILE )      {      return bwb_wend( l );      }   /* check integrity of DO loop */   if ( CURTASK excs[ CURTASK exsc ].code != EXEC_DO )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_loop(): exec stack code != EXEC_DO" );      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_loop(): exec stack while_line == NULL" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      }   /* advance to find the first argument */   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   /* detect a LOOP UNTIL structure */   if ( strcmp( tbuf, CMD_XUNTIL ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_loop(): detected LOOP UNTIL" );      bwb_debug( bwb_ebuf );#endif      return bwb_loopuntil( l );      }   /* LOOP does not have UNTIL */   else      {      /* reset to the top of the current DO loop */#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_loop() 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_DO );      return CURTASK excs[ CURTASK exsc ].while_line;      }   }/***************************************************************	FUNCTION:       bwb_loopuntil()	DESCRIPTION:    This C function implements the ANSI BASIC			LOOP UNTIL statement and is called by			bwb_loop().***************************************************************/#if ANSI_Cstatic struct bwb_line *bwb_loopuntil( struct bwb_line *l )#elsestatic struct bwb_line *bwb_loopuntil( l )   struct bwb_line *l;#endif   {   struct exp_ese *e;   struct bwb_line *r;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_loopuntil(): entered subroutine" );   bwb_debug( bwb_ebuf );#endif   /* call bwb_exp() to interpret the expression */   e = bwb_exp( l->buffer, FALSE, &( l->position ) );   if ( (int) exp_getnval( e ) == TRUE )      {      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;      }   /* condition is false: loop around to DO again */   else      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_loopuntil() 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_DO );      return CURTASK excs[ CURTASK exsc ].while_line;      }   }/***************************************************************        FUNCTION:       bwb_exit()	DESCRIPTION:    This C function implements the BASIC EXIT			statement, calling subroutines for either			EXIT FOR or EXIT DO.	SYNTAX:		EXIT FOR|DO***************************************************************/#if ANSI_Cstruct bwb_line *bwb_exit( struct bwb_line *l )#elsestruct bwb_line *bwb_exit( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_exit(): entered subroutine" );   bwb_debug( bwb_ebuf );#endif   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   if ( strcmp( tbuf, CMD_XFOR ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_exit(): detected EXIT FOR" );      bwb_debug( bwb_ebuf );#endif      return bwb_exitfor( l );      }   if ( strcmp( tbuf, CMD_XDO ) == 0 )      {      return bwb_exitdo( l );      }#if PROG_ERRORS   sprintf( bwb_ebuf, "in bwb_exit(): Nonsense or nothing following EXIT" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax );#endif   return bwb_zline( l );   }/***************************************************************	FUNCTION:       bwb_exitdo()	DESCRIPTION:    This function handles the BASIC EXIT			DO statement.  This is a structured			programming command compatible with ANSI			BASIC. It is called from the bwb_exit()			subroutine.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_exitdo( struct bwb_line *l )#elsestruct bwb_line *bwb_exitdo( l )   struct bwb_line *l;#endif   {   struct bwb_line *next_line;   int found;   register int level;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_exitdo(): entered subroutine" );   bwb_debug( bwb_ebuf );#endif   /* Check the integrity of the DO statement */   found = FALSE;   level = CURTASK exsc;   do

⌨️ 快捷键说明

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