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