📄 bwb_cmd.c
字号:
/*************************************************************** 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 + -