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

📄 bwb_cmd.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************        bwb_cmd.c       Miscellaneous Commands                        for Bywater BASIC Interpreter                        Commands:       RUN                                        LET                                        LOAD                                        MERGE                                        CHAIN                                        NEW                                        RENUM                                        SAVE                                        LIST                                        GOTO                                        GOSUB                                        RETURN                                        ON                                        STOP                                        END                                        SYSTEM                                        TRON                                        TROFF                                        DELETE                                        RANDOMIZE					ENVIRON                                        CMDS            (*debugging)                        Copyright (c) 1993, Ted A. Campbell                        Bywater Software                        email: tcamp@delphi.com        Copyright and Permissions Information:        All U.S. and international rights are claimed by the author,        Ted A. Campbell.	This software is released under the terms of the GNU General	Public License (GPL), which is distributed with this software	in the file "COPYING".  The GPL specifies the terms under	which users may copy and use the software in this distribution.	A separate license is available for commercial distribution,	for information on which you should contact the author.***************************************************************//*---------------------------------------------------------------*//* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, *//* 11/1995 (eidetics@cerf.net).                                  *//*                                                               *//* Those additionally marked with "DD" were at the suggestion of *//* Dale DePriest (daled@cadence.com).                            *//*---------------------------------------------------------------*/#include <stdio.h>#include <math.h>#include <ctype.h>#include "bwbasic.h"#include "bwb_mes.h"#if HAVE_SIGNAL#include <signal.h>#endifchar err_gosubl[ MAXVARNAMESIZE + 1 ] = { '\0' }; /* line for error GOSUB */#if ANSI_Cextern struct bwb_line *bwb_xnew( struct bwb_line *l );extern struct bwb_line *bwb_onerror( struct bwb_line *l );struct bwb_line *bwb_donum( struct bwb_line *l );struct bwb_line *bwb_dounnum( struct bwb_line *l );static int xl_line( FILE *file, struct bwb_line *l );#elseextern struct bwb_line *bwb_xnew();extern struct bwb_line *bwb_onerror();struct bwb_line *bwb_donum();struct bwb_line *bwb_dounnum();static int xl_line();#endif/***************************************************************        FUNCTION:       bwb_null()	DESCRIPTION:    This is a null command function body, and			can be used as the basis for developing			new BASIC commands.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_null( struct bwb_line *l )#elsestruct bwb_line *bwb_null( l )   struct bwb_line *l;#endif   {#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_null(): NULL command" );   bwb_debug( bwb_ebuf );#endif#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ));#endif   return bwb_zline( l );   }/***************************************************************	FUNCTION:       bwb_rem()	DESCRIPTION:    This C function implements the BASIC rem			(REMark) command, ignoring the remainder			of the line.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_rem( struct bwb_line *l )#elsestruct bwb_line *bwb_rem( l )   struct bwb_line *l;#endif   {#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_rem(): REM command" );   bwb_debug( bwb_ebuf );#endif   /* do not use bwb_zline() here; blank out remainder of line */   l->next->position = 0;   return l->next;   }/***************************************************************        FUNCTION:       bwb_let()	DESCRIPTION:    This C function implements the BASIC			LET assignment command, even if LET			is implied and not explicit.	SYNTAX:		LET variable = expression***************************************************************/#if ANSI_Cstruct bwb_line *bwb_let( struct bwb_line *l )#elsestruct bwb_line *bwb_let( l )   struct bwb_line *l;#endif   {#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_let(): pos <%d> line <%s>",      l->position, l->buffer );   bwb_debug( bwb_ebuf );#endif   /* Call the expression interpreter to evaluate the assignment */   bwb_exp( l->buffer, TRUE, &( l->position ) );   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_go        DESCRIPTION:	This C function implements the BASIC			GO command, branching appropriately to			GOTO or GOSUB.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_go( struct bwb_line *l )#elsestruct bwb_line *bwb_go( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   if ( strcmp( tbuf, CMD_XSUB ) == 0 )      {      return bwb_gosub( l );      }   if ( strcmp( tbuf, CMD_XTO ) == 0 )      {      return bwb_goto( l );      }#if PROG_ERRORS   sprintf( bwb_ebuf, "in bwb_go(): Nonsense following GO" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax );#endif   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_goto        DESCRIPTION:	This C function implements the BASIC			GOTO command.   	SYNTAX:		GOTO line | label***************************************************************/#if ANSI_Cstruct bwb_line *bwb_goto( struct bwb_line *l )#elsestruct bwb_line *bwb_goto( l )   struct bwb_line *l;#endif   {   struct bwb_line *x;   char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_goto(): entered function" );   bwb_debug( bwb_ebuf );#endif   /* Check for argument */   adv_ws( l->buffer, &( l->position ) );   switch( l->buffer[ l->position ] )      {      case '\0':      case '\n':      case '\r':      case ':':         bwb_error( err_noln );         return bwb_zline( l );      default:         break;      }   adv_element( l->buffer, &( l->position ), tbuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_goto(): buffer has <%s>", tbuf );   bwb_debug( bwb_ebuf );#endif   /* check for target label */#if STRUCT_CMDS   if ( isalpha( tbuf[ 0 ] ))      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_goto(): found LABEL, <%s>", tbuf );      bwb_debug( bwb_ebuf );#endif      x = find_label( tbuf );      x->position = 0;      return x;      }   else      {      for ( x = &CURTASK bwb_start; x != &CURTASK bwb_end; x = x->next )         {         if ( x->number == atoi( tbuf ) )            {            /* found the requested number */#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in bwb_goto(): returning line <%d>", x->number );            bwb_debug( bwb_ebuf );#endif            x->position = 0;            return x;            }         }      }#else   for ( x = &CURTASK bwb_start; x != &CURTASK bwb_end; x = x->next )      {      if ( x->number == atoi( tbuf ) )         {         /* found the requested number */#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_goto(): returning line <%d>", x->number );         bwb_debug( bwb_ebuf );#endif         x->position = 0;         return x;         }      }#endif   sprintf( bwb_ebuf, err_lnnotfound, atoi( tbuf ) );   bwb_error( bwb_ebuf );   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_gosub()	DESCRIPTION:    This function implements the BASIC GOSUB			command.   	SYNTAX:		GOSUB line | label***************************************************************/#if ANSI_Cstruct bwb_line *bwb_gosub( struct bwb_line *l )#elsestruct bwb_line *bwb_gosub( l )   struct bwb_line *l;#endif   {   struct bwb_line *x;   char atbuf[ MAXSTRINGSIZE + 1 ];   /* Check for argument */   adv_ws( l->buffer, &( l->position ) );   switch( l->buffer[ l->position ] )      {      case '\0':      case '\n':      case '\r':      case ':':         sprintf( bwb_ebuf, err_noln );         bwb_error( bwb_ebuf );         return bwb_zline( l );      default:         break;      }   /* get the target line number in tbuf */   adv_element( l->buffer, &( l->position ), atbuf );#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ));#endif   /* check for a label rather than line number */#if STRUCT_CMDS   if ( isalpha( atbuf[ 0 ] ))      {      x = find_label( atbuf );#if MULTISEG_LINES      CURTASK excs[ CURTASK exsc ].position = l->position;#endif      bwb_incexec();      /* set the new position to x and return x */      x->cmdnum = -1;      x->marked = FALSE;      x->position = 0;      bwb_setexec( x, 0, EXEC_GOSUB );      return x;      }#endif   for ( x = &CURTASK bwb_start; x != &CURTASK bwb_end; x = x->next )      {      if ( x->number == atoi( atbuf ))         {         /* this is the line we are looking for */#if MULTISEG_LINES         CURTASK excs[ CURTASK exsc ].position = l->position;#endif         /* increment the EXEC stack */         bwb_incexec();         /* set the new position to x and return x */         x->cmdnum = -1;         x->marked = FALSE;         x->position = 0;         bwb_setexec( x, 0, EXEC_GOSUB );         return x;         }      }   /* the requested line was not found */   sprintf( bwb_ebuf, err_lnnotfound, atoi( atbuf ) );   bwb_error( bwb_ebuf );   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_return()	DESCRIPTION:    This function implements the BASIC RETURN			command.   	SYNTAX:		RETURN***************************************************************/#if ANSI_Cstruct bwb_line *bwb_return( struct bwb_line *l )#elsestruct bwb_line *bwb_return( l )   struct bwb_line *l;#endif   {#if  INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_return() at line <%d> cmdnum <%d>",      l->number, l->cmdnum );   bwb_debug( bwb_ebuf );#endif   /* see if old position was "GOSUB" */   if ( CURTASK excs[ CURTASK exsc ].code != EXEC_GOSUB )      {      bwb_error( err_retnogosub );      }   /* decrement the EXEC stack counter */   bwb_decexec();   /* restore position and return old line */#if MULTISEG_LINES   CURTASK excs[ CURTASK exsc ].line->position      = CURTASK excs[ CURTASK exsc ].position;   return CURTASK excs[ CURTASK exsc ].line;#else   CURTASK excs[ CURTASK exsc ].line->next->position = 0;   return CURTASK excs[ CURTASK exsc ].line->next;#endif   }/***************************************************************        FUNCTION:       bwb_on        DESCRIPTION:    This function implements the BASIC ON...                        GOTO or ON...GOSUB statements.			It will also detect the ON ERROR... statement			and pass execution to bwb_onerror().   	SYNTAX:		ON variable GOTO|GOSUB line[,line,line,...]	LIMITATION:     As implemented here, the ON...GOSUB|GOTO			command recognizes line numbers only			(not labels).***************************************************************/#if ANSI_Cstruct bwb_line *bwb_on( struct bwb_line *l )#elsestruct bwb_line *bwb_on( l )   struct bwb_line *l;#endif   {   struct bwb_line *oline, *x;   char varname[ MAXVARNAMESIZE + 1 ];   char tbuf[ MAXSTRINGSIZE + 1 ];   static int p;   struct exp_ese *rvar;   int v;   int loop;   int num_lines;   int command;   int lines[ MAX_GOLINES ];   char sbuf[ 7 ];   /* Check for argument */   adv_ws( l->buffer, &( l->position ) );   switch( l->buffer[ l->position ] )      {      case '\0':      case '\n':      case '\r':      case ':':         sprintf( bwb_ebuf, err_incomplete );         bwb_error( bwb_ebuf );         return bwb_zline( l );      default:         break;      }   /* get the variable name or numerical constant */   adv_element( l->buffer, &( l->position ), varname );   /* check for ON ERROR statement */

⌨️ 快捷键说明

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