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

📄 bwb_cmd.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
#if COMMON_CMDS   strncpy( sbuf, varname, 6 );   bwb_strtoupper( sbuf );   if ( strcmp( sbuf, CMD_XERROR ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_on(): detected ON ERROR" );      bwb_debug( bwb_ebuf );#endif      return bwb_onerror( l );      }#endif	/* COMMON_CMDS */   /* evaluate the variable name or constant */   p = 0;   rvar = bwb_exp( varname, FALSE, &p );   v = (int) exp_getnval( rvar );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_on(): value is <%d>", v );   bwb_debug( bwb_ebuf );#endif   /* Get GOTO or GOSUB statements */   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   if ( strncmp( tbuf, CMD_GOTO, (size_t) strlen( CMD_GOTO ) ) == 0 )      {      command = getcmdnum( CMD_GOTO );      }   else if ( strncmp( tbuf, CMD_GOSUB, (size_t) strlen( CMD_GOSUB ) ) == 0 )      {      command = getcmdnum( CMD_GOSUB );      }   else      {      sprintf( bwb_ebuf, ERR_ONNOGOTO );      bwb_error( bwb_ebuf );      return bwb_zline( l );      }   num_lines = 0;   loop = TRUE;   while( loop == TRUE )      {      /* read a line number */      inp_adv( l->buffer, &( l->position ) );      adv_element( l->buffer, &( l->position ), tbuf );      lines[ num_lines ] = atoi( tbuf );      ++num_lines;      if ( num_lines >= MAX_GOLINES )         {         loop = FALSE;         }      /* check for end of line */      adv_ws( l->buffer, &( l->position ) );      switch( l->buffer[ l->position ] )         {         case '\0':         case '\n':         case '\r':         case ':':            loop = FALSE;            break;         }      }   /* advance to end of segment */#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ) );#endif   /* Be sure value is in range */   if ( ( v < 1 ) || ( v > num_lines ))      {      sprintf( bwb_ebuf, err_valoorange );      bwb_error( bwb_ebuf );      return bwb_zline( l );      }   if ( command == getcmdnum( CMD_GOTO ))      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_on(): executing ON...GOTO" );      bwb_debug( bwb_ebuf );#endif      oline = NULL;      for ( x = &CURTASK bwb_start; x != &CURTASK bwb_end; x = x->next )	 {	 if ( x->number == lines[ v - 1 ] )	    {	    /* found the requested number */#if INTENSIVE_DEBUG	    sprintf( bwb_ebuf, "in bwb_on(): returning line <%d>", x->number );	    bwb_debug( bwb_ebuf );#endif	    oline = x;	    }	 }      if ( oline == NULL )	 {	 bwb_error( err_lnnotfound );	 return bwb_zline( l );	 }      oline->position = 0;      bwb_setexec( oline, 0, CURTASK excs[ CURTASK exsc ].code );      return oline;      }   else if ( command == getcmdnum( CMD_GOSUB ))      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_on(): executing ON...GOSUB" );      bwb_debug( bwb_ebuf );#endif      /* save current stack level */      bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );      /* increment exec stack */      bwb_incexec();      /* get memory for line and buffer */      /* Revised to CALLOC pass-thru call by JBV */      if ( ( oline = CALLOC( 1, sizeof( struct bwb_line ), "bwb_on") ) == NULL )	 {#if PROG_ERRORS	 bwb_error( "in bwb_on(): failed to find memory for oline" );#else	 bwb_error( err_getmem );#endif	 }      /* Revised to CALLOC pass-thru call by JBV */      if ( ( oline->buffer = CALLOC( 1, MAXSTRINGSIZE + 1, "bwb_on") ) == NULL )	 {#if PROG_ERRORS	 bwb_error( "in bwb_on(): failed to find memory for oline buffer" );#else	 bwb_error( err_getmem );#endif	 }      CURTASK excs[ CURTASK exsc ].while_line = oline;      sprintf( oline->buffer, "%s %d", CMD_GOSUB, lines[ v - 1 ] );      oline->marked = FALSE;      oline->position = 0;      oline->next = l->next;      bwb_setexec( oline, 0, EXEC_ON );      return oline;      }   else      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_on(): invalid value for command." );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      return bwb_zline( l );      }   }/***************************************************************        FUNCTION:       bwb_stop()	DESCRIPTION:    This C function implements the BASIC			STOP command, interrupting program flow			at a specific point.   	SYNTAX:		STOP***************************************************************/#if ANSI_Cstruct bwb_line *bwb_stop( struct bwb_line *l )#elsestruct bwb_line *bwb_stop( l )   struct bwb_line *l;#endif   {#if HAVE_SIGNAL#if HAVE_RAISE   raise( SIGINT );#else   kill( getpid(), SIGINT );#endif#endif   return bwb_xend( l );   }/***************************************************************        FUNCTION:       bwb_xend()	DESCRIPTION:    This C function implements the BASIC			END command, checking for END SUB			or END FUNCTION, else stopping program			execution for a simple END command.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_xend( struct bwb_line *l )#elsestruct bwb_line *bwb_xend( l )   struct bwb_line *l;#endif   {#if STRUCT_CMDS   char tbuf[ MAXSTRINGSIZE + 1 ];#endif#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_xend(): entered funtion" );   bwb_debug( bwb_ebuf );#endif   /* Detect END SUB or END FUNCTION here */#if STRUCT_CMDS   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   if ( strcmp( tbuf, CMD_XSUB ) == 0 )      {      return bwb_endsub( l );      }   if ( strcmp( tbuf, CMD_XFUNCTION ) == 0 )      {      return bwb_endfnc( l );      }   if ( strcmp( tbuf, CMD_XIF ) == 0 )      {      return bwb_endif( l );      }   if ( strcmp( tbuf, CMD_XSELECT ) == 0 )      {      return bwb_endselect( l );      }#endif			/* STRUCT_CMDS */   /* else a simple END statement */   break_handler();   return &CURTASK bwb_end;   }/***************************************************************        FUNCTION:       bwb_do()	DESCRIPTION:    This C function implements the BASIC DO			command, also checking for the DO NUM			and DO UNNUM commands for interactive			programming environment.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_do( struct bwb_line *l )#elsestruct bwb_line *bwb_do( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   /* if there is no argument (with STRUCT_CMDS) then we have a      DO-LOOP structure: pass on to bwb_doloop() in bwb_stc.c */#if STRUCT_CMDS   if ( strlen( tbuf ) == 0 )      {      return bwb_doloop( l );      }   if ( strcmp( tbuf, CMD_WHILE ) == 0 )      {      return bwb_while( l );      }#endif#if INTERACTIVE   if ( strcmp( tbuf, CMD_XNUM ) == 0 )      {      return bwb_donum( l );      }   if ( strcmp( tbuf, CMD_XUNNUM ) == 0 )      {      return bwb_dounnum( l );      }#endif				/* INTERACTIVE */   /* if none of these occurred, then presume an error */   bwb_error( err_syntax );   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_run()        DESCRIPTION:	This C function implements the BASIC			RUN command.			Even though RUN is not a core statement,			the function bwb_run() is called from			core, so it must be present for a minimal			implementation.   	SYNTAX:		RUN [line]|[file-name]***************************************************************/#if ANSI_Cstruct bwb_line *bwb_run( struct bwb_line *l )#elsestruct bwb_line *bwb_run( l )   struct bwb_line *l;#endif   {   struct bwb_line *current, *x;   int go_lnumber;                /* line number to go to */   char tbuf[ MAXSTRINGSIZE + 1 ];   struct exp_ese *e;   FILE *input;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_run(): entered function. buffer <%s> pos <%d>",      l->buffer, l->position );   bwb_debug( bwb_ebuf );#endif   /* see if there is an element */   current = NULL;   adv_ws( l->buffer, &( l->position ) );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_run(): check buffer <%s> pos <%d> char <0x%x>",      l->buffer, l->position, l->buffer[ l->position ] );   bwb_debug( bwb_ebuf );#endif   switch ( l->buffer[ l->position ] )      {      case '\0':      case '\n':      case '\r':      case ':':#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_run(): no argument; begin at start.next" );         bwb_debug( bwb_ebuf );#endif         current = CURTASK bwb_start.next;         e = NULL;         break;      default:         e = bwb_exp( l->buffer, FALSE, &( l->position ) );         break;      }   /* check its type: if it is a string, open the file and execute it */   if (( e != NULL ) && ( e->type == STRING ))      {      bwb_new( l );				/* clear memory */      str_btoc( tbuf, exp_getsval( e ) );	/* get string in tbuf */      if ( ( input = fopen( tbuf, "r" )) == NULL )	/* open file */         {         sprintf( bwb_ebuf, err_openfile, tbuf );         bwb_error( bwb_ebuf );         }      bwb_fload( input );		/* load program */      /* Next line removed by JBV (unnecessary recursion asks for trouble) */      /* bwb_run( &CURTASK bwb_start ); */         /* and call bwb_run() recursively */      current = &CURTASK bwb_start; /* JBV */      }   /* else if it is a line number, execute the program in memory      at that line number */   /* Removed by JBV */   /* else      { */      /* Removed by JBV */      /* if ( current == NULL )         { */         /* Added expression type check and changed loop boundaries (JBV) */         if (( e != NULL ) && ( e->type != STRING ))         {            go_lnumber = (int) exp_getnval( e );#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_run(): element detected <%s>, lnumber <%d>",            tbuf, go_lnumber );         bwb_debug( bwb_ebuf );#endif         for ( x = CURTASK bwb_start.next; x != &CURTASK bwb_end; x = x->next )            {            if ( x->number == go_lnumber )               {               current = x;               }            }         }      /*    } */ /* Removed by JBV */      if ( current == NULL )         {         sprintf( bwb_ebuf, err_lnnotfound, go_lnumber );         bwb_error( bwb_ebuf );         return &CURTASK bwb_end;         }#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_run(): ready to run starting at line %d",         current->number );      bwb_debug( bwb_ebuf );#endif      if ( CURTASK rescan == TRUE )         {         bwb_scan();         }      current->position = 0;      CURTASK exsc = 0;      bwb_setexec( current, 0, EXEC_NORM );   /*    } */ /* Removed by JBV */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_run(): function complete." );   bwb_debug( bwb_ebuf );#endif   return current;   }/***************************************************************        FUNCTION:       bwb_new()        DESCRIPTION:	This C function implements the BASIC			NEW command.			Even though NEW is not a core statement,			the function bwb_run() is called from			core, so it must be present for a minimal			implementation.	SYNTAX:		NEW***************************************************************/#if ANSI_Cstruct bwb_line *bwb_new( struct bwb_line *l )#elsestruct bwb_line *bwb_new( l )   struct bwb_line *l;#endif   {   /* clear program in memory */   bwb_xnew( l );   /* clear all variables */   bwb_clear( l );   return bwb_zline( l );   }/* End of Core Functions Section */#if INTERACTIVE/***************************************************************        FUNCTION:       bwb_system()	DESCRIPTION:    This C function implements the BASIC			SYSTEM command, exiting to the operating			system (or calling program).  It is also			called by the QUIT command, a functional			equivalent for SYSTEM in Bywater BASIC.	SYNTAX:		SYSTEM			QUIT***************************************************************/#if ANSI_Cstruct bwb_line *bwb_system( struct bwb_line *l )#elsestruct bwb_line *bwb_system( l )   struct bwb_line *l;#endif   {   prn_xprintf( stdout, "\n" );#if INTENSIVE_DEBUG   bwb_debug( "in bwb_system(): ready to exit" );

⌨️ 快捷键说明

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