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

📄 bwbasic.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 3 页
字号:
#elsebwb_mainloop()#endif   {   if ( CURTASK exsc > -1 )      {      bwb_execline();			/* execute one line of program */      }#if INTERACTIVE   else      {      bwb_interact();			/* get user interaction */      }#endif   }/***************************************************************        FUNCTION:       bwb_execline()        DESCRIPTION:    This function executes a single line of                        a program in memory. This function is			called by bwb_mainloop().***************************************************************/void#if ANSI_Cbwb_execline( void )#elsebwb_execline()#endif   {   struct bwb_line *r, *l;   l = CURTASK excs[ CURTASK exsc ].line;   /* if the line is &CURTASK bwb_end, then break out of EXEC loops */   if ( l == &CURTASK bwb_end )      {      CURTASK exsc = -1;      return;      }   /* Check for wacko line numbers  */#if INTENSIVE_DEBUG   if ( l->number < -1 )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_execline(): received line number <%d> < -1",         l->number );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      return;      }   if ( l->number > MAXLINENO )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_execline(): received line number <%d> > MAX <%d>",         l->number, MAXLINENO );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      return;      }#endif#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_execline(): buffer <%s>",      &( l->buffer[ l->position ] ) );   bwb_debug( bwb_ebuf );#endif   /* Print line number if trace is on */   if ( bwb_trace == TRUE )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "[ %d ]", l->number );      prn_xprintf( errfdevice, bwb_ebuf );#else      if ( l->number > 0 )         {         sprintf( bwb_ebuf, "[ %d ]", l->number );	 prn_xprintf( errfdevice, bwb_ebuf );         }#endif      }   /* Set current line for error/break handling */   CURTASK number = l->number;   CURTASK bwb_l = l;   /* advance beyond whitespace */   adv_ws( l->buffer, &( l->position ) );   /*  advance past segment delimiter and warn */#if MULTISEG_LINES   if ( l->buffer[ l->position ] == ':' )      {      ++( l->position );      adv_ws( l->buffer, &( l->position ) );      }   l->marked = FALSE;#else#if PROG_ERRORS   if ( l->buffer[ l->position ] == ':' )      {      ++( l->position );      adv_ws( l->buffer, &( l->position ) );      sprintf( bwb_ebuf, "Enable MULTISEG_LINES for multi-segmented lines",         VERSION );      bwb_error( bwb_ebuf );      }#endif#endif   /* set positions in buffer */#if MULTISEG_LINES   if ( ( l->marked != TRUE ) || ( l->position > l->startpos ))      {      line_start( l->buffer, &( l->position ), &( l->lnpos ), &( l->lnum ),         &( l->cmdpos ), &( l->cmdnum ), &( l->startpos ) );      l->marked = TRUE;      }   else      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_execline(): line <%d> is already marked",          l->number );      bwb_debug( bwb_ebuf );#endif      }   l->position = l->startpos;#else				/* not MULTISEG_LINES */   line_start( l->buffer, &( l->position ), &( l->lnpos ), &( l->lnum ),      &( l->cmdpos ), &( l->cmdnum ), &( l->startpos ) );   if ( l->position < l->startpos )      {      l->position = l->startpos;      }#endif   /* if there is a BASIC command in the line, execute it here */   if ( l->cmdnum > -1 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_execline(): executing <%s>", l->buffer );      bwb_debug( bwb_ebuf );#endif      /* execute the command vector */      r = bwb_cmdtable[ l->cmdnum ].vector ( l );      }   /* No BASIC command; try to execute it as a shell command */#if COMMAND_SHELL   else      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "Breaking out to shell, line num <%d> buf <%s> cmd <%d> pos <%d>",         l->number, &( l->buffer[ l->position ] ), l->cmdnum, l->position );      bwb_debug( bwb_ebuf );      getchar();#endif      bwx_shell( l );      bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );      return;      }#else				/* COMMAND_SHELL == FALSE */   else     {     bwb_error( err_uc );     }#endif   /* check for end of line: if so, advance to next line and return */   adv_ws( r->buffer, &( r->position ) );   switch( r->buffer[ r->position ] )      {      case '\n':      case '\r':      case '\0':#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_execline(): detected end of line" );	 bwb_debug( bwb_ebuf );#endif	 r->next->position = 0;         bwb_setexec( r->next, 0, CURTASK excs[ CURTASK exsc ].code );         return;			/* and return */      }   /* else reset with the value in r */   bwb_setexec( r, r->position, CURTASK excs[ CURTASK exsc ].code );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_execline(): exit setting line number <%d>",      r->number );   bwb_debug( bwb_ebuf );#endif   }/***************************************************************        FUNCTION:       ln_asbuf()        DESCRIPTION:    This function allocates memory and copies			a null-terminated string to a line buffer.***************************************************************/int#if ANSI_Cln_asbuf( struct bwb_line *l, char *s )#elseln_asbuf( l, s )   struct bwb_line *l;   char *s;#endif   {/* Reinstated by JBV *//* #if DONTDOTHIS */		/* but why not? */   if ( l->buffer != NULL )      {      /* Revised to FREE pass-thru call by JBV */      FREE( l->buffer, "ln_asbuf" );      l->buffer = NULL; /* JBV */      }/* #endif */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( l->buffer = CALLOC( strlen( s ) + 2, sizeof( char ), "ln_asbuf") )      == NULL )      {#if PROG_ERRORS      bwb_error( "in ln_asbuf(): failed to find memory for new line" );#else      bwb_error( err_getmem );#endif      return FALSE;      }   /* copy the whole line to the line structure buffer */   strcpy( l->buffer, s );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in ln_asbuf(): allocated buffer <%s>", l->buffer );   bwb_debug( bwb_ebuf );#endif   /* strip CR from the buffer */   bwb_stripcr( l->buffer );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in ln_asbuf(): stripped CRs" );   bwb_debug( bwb_ebuf );#endif   return TRUE;   }/***************************************************************        FUNCTION:       bwb_gets()        DESCRIPTION:    This function reads a single line from                        the specified buffer.***************************************************************/int#if ANSI_Cbwb_gets( char *buffer )#elsebwb_gets( buffer )   char *buffer;#endif   {   struct bwb_variable *v;   char tbuf[ MAXSTRINGSIZE + 1 ];#if PARACT   char ubuf[ MAXSTRINGSIZE + 1 ];#endif   CURTASK number = 0;   v = var_find( DEFVNAME_PROMPT );   str_btoc( tbuf, var_getsval( v ) );#if PARACT   sprintf( ubuf, "TASK %d %s", bwb_curtask, tbuf );   strcpy( tbuf, ubuf );#endif   bwx_input( tbuf, buffer );   return TRUE;   }/***************************************************************        FUNCTION:       break_mes()        DESCRIPTION:    This function is called (a) by a SIGINT			signal or (b) by error-handling routines.			It prints an error message then calls			break_handler() to handle the program			interruption.***************************************************************/void#if ANSI_Cbreak_mes( int x )#elsebreak_mes( x )   int x;#endif   {   static char *tmp_buffer;   static int init = FALSE;   /* get memory for temporary buffer if necessary */   if ( init == FALSE )      {      init = TRUE;      /* Revised to CALLOC pass-thru call by JBV */      if ( ( tmp_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "break_mes")) == NULL )         {#if PROG_ERRORS	 bwb_error( "in break_mes(): failed to find memory for tmp_buffer" );#else	 bwb_error( err_getmem );#endif	 }      }   CURTASK expsc = 0;   sprintf( tmp_buffer, "\r%s %d\n", MES_BREAK, CURTASK number );   prn_xprintf( errfdevice, tmp_buffer );   break_handler();   }/***************************************************************	FUNCTION:       break_handler()	DESCRIPTION:    This function is called by break_mes()			and handles program interruption by break			(or by the STOP command).***************************************************************/void#if ANSI_Cbreak_handler( void )#elsebreak_handler()#endif   {#if INTERACTIVE		/* INTERACTIVE: reset counters and jump back to mark */   /* reset all stack counters */   CURTASK exsc = -1;   CURTASK expsc = 0;   CURTASK xtxtsc = 0;   err_gosubl[ 0 ] = '\0';   /* reset the break handler */#if HAVE_SIGNAL   signal( SIGINT, break_mes );#endif#if HAVE_LONGJUMP   longjmp( mark, -1 );#else		/* HAVE_LONGJUMP = FALSE; no jump available; terminate */      bwx_terminate();#endif   #else		/* nonINTERACTIVE:  terminate immediately */   bwx_terminate();#endif   }/***************************************************************	FUNCTION:       is_ln()	DESCRIPTION:    This function determines whether a program			line (in buffer) begins with a line number.***************************************************************/int#if ANSI_Cis_ln( char *buffer )#elseis_ln( buffer )   char *buffer;#endif   {   static int position;   position = 0;   adv_ws( buffer, &position );   switch( buffer[ position ] )      {      case '0':      case '1':      case '2':      case '3':      case '4':      case '5':      case '6':      case '7':      case '8':      case '9':         return TRUE;      default:         return FALSE;      }   }/***************************************************************	FUNCTION:       CALLOC()	DESCRIPTION:    Pass-thru function to calloc() for debugging			purposes.  Added by JBV 10/95***************************************************************/void *#if ANSI_CCALLOC( size_t nelem, size_t elsize, char *str )#elseCALLOC( nelem, elsize, str )   size_t nelem;   size_t elsize;   char *str;#endif{    void *ptr;    ptr = calloc(nelem, elsize);    /* printf("%x %x\n", ptr, mallocblksize(ptr)); */    return ptr;}/***************************************************************	FUNCTION:       FREE()	DESCRIPTION:    Pass-thru function to free() for debugging			purposes.  Added by JBV 10/95***************************************************************/void#if ANSI_CFREE( void *ptr, char *str )#elseFREE( ptr, str )   void *ptr;   char *str;#endif{    /* printf("%x\n", ptr); */    free(ptr);}

⌨️ 快捷键说明

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