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

📄 bwbasic.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 3 页
字号:
bwb_fload( file )   FILE *file;#endif   {   while ( feof( file ) == FALSE )      {      read_line[ 0 ] = '\0';      fgets( read_line, MAXREADLINESIZE, file );      if ( file == stdin )         {         * prn_getcol( stdout ) = 1;		/* reset column */         }      bwb_stripcr( read_line );      /* be sure that this is not EOF with a NULL line */      if (( feof( file ) == FALSE ) || ( strlen( read_line ) > 0 ))	 {	 bwb_ladd( read_line, FALSE );	 }      }   /* close file stream */   fclose( file );   return TRUE;   }/***************************************************************        FUNCTION:       bwb_ladd()        DESCRIPTION:    This function adds a new line (in the                        buffer) to the program in memory.***************************************************************/int#if ANSI_Cbwb_ladd( char *buffer, int replace )#elsebwb_ladd( buffer, replace )   char *buffer;   int replace;#endif   {   struct bwb_line *l, *previous, *p;   static char *s_buffer;   static int init = FALSE;   static int prev_num = 0;   char *newbuffer;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_ladd(): add line <%s>",      buffer );   bwb_debug( bwb_ebuf );#endif   /* get memory for temporary buffer if necessary */   if ( init == FALSE )      {      init = TRUE;      /* Revised to CALLOC pass-thru call by JBV */      if ( ( s_buffer = CALLOC( (size_t) MAXSTRINGSIZE + 1, sizeof( char ), "bwb_ladd" )) == NULL )	 {#if PROG_ERRORS	 bwb_error( "in bwb_ladd(): failed to find memory for s_buffer" );#else	 bwb_error( err_getmem );#endif	 return FALSE;         }      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_ladd(): s_buffer initialized " );   bwb_debug( bwb_ebuf );#endif   /* get memory for this line */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( l = (struct bwb_line *) CALLOC( (size_t) 1, sizeof( struct bwb_line ), "bwb_ladd")) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_ladd(): failed to find memory for new line" );#else      bwb_error( err_getmem );#endif      return FALSE;      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_ladd(): got memory." );   bwb_debug( bwb_ebuf );#endif   /* note that line is not yet marked and the program must be rescanned */   l->marked = FALSE;   CURTASK rescan = TRUE;		/* program needs to be scanned again */   l->xnum = FALSE;   /* get the first element and test for a line number */   adv_element( buffer, &( l->position ), s_buffer );   /* set line number in line structure */   if ( is_numconst( s_buffer ) == TRUE )      {      l->number = atoi( s_buffer );#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_ladd(): line is numbered, number is <%d>",	 l->number );      bwb_debug( bwb_ebuf );#endif      prev_num = l->number;      l->xnum = TRUE;      ++( l->position );      newbuffer = &( buffer[ l->position ] );      /* allocate memory and assign buffer to line buffer */      ln_asbuf( l, newbuffer );      }   /* There is not a line number */   else      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_ladd(): line is not numbered, using prev <%d>",         prev_num );      bwb_debug( bwb_ebuf );#endif      newbuffer = buffer;      /* allocate memory and assign buffer to line buffer */      ln_asbuf( l, newbuffer );      l->xnum = FALSE;      l->number = prev_num;      }   /* find the place of the current line */   for ( previous = &CURTASK bwb_start; previous != &CURTASK bwb_end; previous = previous->next )      {      /* replace a previously existing line */      if ( ( l->xnum == (char) TRUE ) /* Better recast this one (JBV) */         && ( previous->number == l->number )	 && ( replace == TRUE )	 )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_ladd(): writing to previous number <%d>",            l->number );         bwb_debug( bwb_ebuf );#endif         /* allocate memory and assign buffer to line buffer */	 ln_asbuf( previous, newbuffer );         /* free the current line */         /* Revised to FREE pass-thru calls by JBV */         /* if (l->buffer != NULL) FREE( l->buffer, "bwb_ladd" ); */         /* FREE( l, "bwb_ladd" ); */         bwb_freeline( l ); /* JBV */         /* and return */         return TRUE;         }      /* add after previously existing line: this is to allow unnumbered         lines that follow in sequence after a previously numbered line */      else if (( previous->number == l->number )	 && ( replace == FALSE )	 )         {#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_ladd(): adding doubled number <%d>",	    l->number );	 bwb_debug( bwb_ebuf);#endif         /* if there are multiple instances of this particular line number,            then it is incumbent upon us to find the very last one */         for ( p = previous; p->number == l->number; p = p->next )            {#if INTENSIVE_DEBUG	    bwb_debug( "in bwb_ladd(): advancing..." );#endif            previous = p;            }         l->next = previous->next;         previous->next = l;         return TRUE;         }      /* add a new line */      else if ( ( previous->number < l->number )         && ( previous->next->number > l->number ))         {         l->next = previous->next;         previous->next = l;#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_ladd(): added new line <%d> buffer <%s>",	    l->number, l->buffer );	 bwb_debug( bwb_ebuf );#endif         return TRUE;         }      }   /* attempt to link line number has failed; free memory */   /* Revised to FREE pass-thru calls by JBV */   /* if (l->buffer != NULL) FREE( l->buffer, "bwb_ladd" ); */   /* FREE( l, "bwb_ladd" ); */   bwb_freeline( l ); /* JBV */   sprintf( bwb_ebuf, ERR_LINENO );   bwb_error( bwb_ebuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_ladd(): attempt to add line has failed" );   bwb_debug( bwb_ebuf );#endif   return FALSE;   }/***************************************************************        FUNCTION:       bwb_xtxtline()        DESCRIPTION:    This function executes a text line, i.e.,                        places it in memory and then relinquishes                        control.***************************************************************/struct bwb_line *#if ANSI_Cbwb_xtxtline( char *buffer )#elsebwb_xtxtline( buffer )   char *buffer;#endif   {   struct bwb_line *c;   char *p;   int loop;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_xtxtline(): received <%s>", buffer );   bwb_debug( bwb_ebuf );#endif   /* increment xtxt stack counter */   if ( CURTASK xtxtsc >= XTXTSTACKSIZE )      {      sprintf( bwb_ebuf, "Exceeded maximum xtxt stack <%d>",         CURTASK xtxtsc );      return &CURTASK bwb_end;      }   ++CURTASK xtxtsc;   /* advance past whitespace */   p = buffer;   loop = TRUE;   while( loop == TRUE )      {      switch( *p )         {         case '\0':                     /* end of string */#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "Null command line received." );            bwb_debug( bwb_ebuf );#endif            --CURTASK xtxtsc;            return &CURTASK bwb_end;         case ' ':                      /* whitespace */         case '\t':            ++p;            break;         default:            loop = FALSE;            break;         }      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_xtxtline(): ready to get memory" );   bwb_debug( bwb_ebuf );#endif/* Removed by JBV (no longer needed, done by ln_asbuf) *//*   if ( CURTASK xtxts[ CURTASK xtxtsc ].l.buffer != NULL )      { *//* #if INTENSIVE_DEBUG *//*      sprintf( bwb_ebuf, "in bwb_xtxtline(): freeing buffer memory" );      bwb_debug( bwb_ebuf ); *//* #endif */        /* Revised to FREE pass-thru call by JBV *//*      FREE( CURTASK xtxts[ CURTASK xtxtsc ].l.buffer, "bwb_xtxtline" );      } */   /* copy the whole line to the line structure buffer */   ln_asbuf( &( CURTASK xtxts[ CURTASK xtxtsc ].l ), buffer );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_xtxtline(): copied to line buffer <%s>.",      CURTASK xtxts[ CURTASK xtxtsc ].l.buffer );   bwb_debug( bwb_ebuf );#endif   /* set line number in line structure */   CURTASK xtxts[ CURTASK xtxtsc ].l.number = 0;   CURTASK xtxts[ CURTASK xtxtsc ].l.marked = FALSE;   /* execute the line as BASIC command line */   CURTASK xtxts[ CURTASK xtxtsc ].l.next = &CURTASK bwb_end;   c = &( CURTASK xtxts[ CURTASK xtxtsc ].l );   c->position = 0;#if THEOLDWAY   do      {      c = bwb_xline( c );      }   while( c != &CURTASK bwb_end );#endif   bwb_incexec();		/* increment EXEC stack */   bwb_setexec( c, 0, EXEC_NORM );		/* and set current line in it */   /* decrement xtxt stack counter ??? */   --CURTASK xtxtsc;   return c;   }/***************************************************************        FUNCTION:       bwb_incexec()        DESCRIPTION:    This function increments the EXEC			stack counter.***************************************************************/#if ANSI_Cextern voidbwb_incexec( void )   {#elsevoidbwb_incexec()   {#endif   ++CURTASK exsc;   if ( CURTASK exsc >= EXECLEVELS )      {      --CURTASK exsc;#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_incexec(): incremented EXEC stack past max <%d>",         EXECLEVELS );      bwb_error( bwb_ebuf );#else      bwb_error( err_overflow );#endif      }   CURTASK excs[ CURTASK exsc ].while_line = NULL;   CURTASK excs[ CURTASK exsc ].wend_line  = NULL;   CURTASK excs[ CURTASK exsc ].n_cvs = 0;   CURTASK excs[ CURTASK exsc ].local_variable = NULL;   }/***************************************************************        FUNCTION:       bwb_decexec()        DESCRIPTION:    This function decrements the EXEC			stack counter.***************************************************************/#if ANSI_Cextern voidbwb_decexec( void )   {#elsevoidbwb_decexec()   {#endif   /* decrement the exec stack counter */   --CURTASK exsc;   if ( CURTASK exsc < -1 )      {      CURTASK exsc = -1;#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_decexec(): decremented EXEC stack past min <-1>" );      bwb_error( bwb_ebuf );#else      bwb_error( err_overflow );#endif      }   /* check for EXEC_ON and decrement recursively */   if ( CURTASK excs[ CURTASK exsc ].code == EXEC_ON )      {      /* Revised to FREE pass-thru calls by JBV */      /* FREE( CURTASK excs[ CURTASK exsc ].while_line->buffer, "bwb_decexec" ); */      /* FREE( CURTASK excs[ CURTASK exsc ].while_line, "bwb_decexec" ); */      bwb_freeline( CURTASK excs[ CURTASK exsc ].while_line ); /* JBV */      bwb_decexec();      }   }/***************************************************************        FUNCTION:       bwb_setexec()        DESCRIPTION:    This function sets the line and position			for the next call to bwb_execline();***************************************************************/#if ANSI_Cextern intbwb_setexec( struct bwb_line *l, int position, int code )   {#elseintbwb_setexec( l, position, code )   struct bwb_line *l;   int position;   int code;   {#endif   CURTASK excs[ CURTASK exsc ].line = l;   CURTASK excs[ CURTASK exsc ].position = position;   CURTASK excs[ CURTASK exsc ].code = code;   return TRUE;   }/***************************************************************        FUNCTION:       bwb_mainloop()        DESCRIPTION:    This C function performs one iteration                        of the interpreter. In a non-preemptive                        scheduler, this function should be called                        by the scheduler, not by bwBASIC code.***************************************************************/void#if ANSI_Cbwb_mainloop( void )

⌨️ 快捷键说明

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