📄 bwb_stc.c
字号:
/* if a MAIN function was not found at level 0, then skip the subroutine */ else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_sub(): found non-MAIN function at level 0" ); bwb_debug( bwb_ebuf );#endif rline = find_endsub( l ); bwb_setexec( rline->next, 0, EXEC_CALLSUB ); rline->next->position = 0; return rline->next; } } /* check for integrity of CALL-SUB sequence if above level 0 */ else if ( CURTASK excs[ CURTASK exsc ].code != EXEC_CALLSUB ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_sub(): SUB without CALL" ); bwb_error( bwb_ebuf );#else bwb_error( err_retnogosub );#endif } /* advance position */#if MULTISEG_LINES adv_ws( l->buffer, &( l->position )); adv_element( l->buffer, &( l->position ), tbuf ); f = fslt_findf( tbuf ); l->position = f->startpos; return bwb_zline( l );#else return bwb_zline( l );#endif }/*************************************************************** FUNCTION: find_endsub() DESCRIPTION: This function searches for a line containing an END SUB statement corresponding to a previous SUB statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_endsub( struct bwb_line *l )#elsestatic struct bwb_line *find_endsub( l ) struct bwb_line *l;#endif { struct bwb_line *current; register int s_level; int position; s_level = 1; for ( current = l->next; current != &CURTASK bwb_end; current = current->next ) { position = 0; if ( current->marked != TRUE ) { line_start( current->buffer, &position, &( current->lnpos ), &( current->lnum ), &( current->cmdpos ), &( current->cmdnum ), &( current->startpos ) ); } current->position = current->startpos; if ( current->cmdnum > -1 ) { if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_sub ) { ++s_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_endsub(): found SUB at line %d, level %d", current->number, s_level ); bwb_debug( bwb_ebuf );#endif } else if ( is_endsub( current ) == TRUE ) { --s_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_endsub(): found END SUB at line %d, level %d", current->number, s_level ); bwb_debug( bwb_ebuf );#endif if ( s_level == 0 ) { return current; } } } }#if PROG_ERRORS sprintf( bwb_ebuf, "SUB without END SUB" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return NULL; }/*************************************************************** FUNCTION: is_endsub() DESCRIPTION: This function determines whether the line buffer for line 'l' is positioned at an END SUB statement.***************************************************************/#if ANSI_Cstatic intis_endsub( struct bwb_line *l )#elsestatic intis_endsub( l ) struct bwb_line *l;#endif { int position; char tbuf[ MAXVARNAMESIZE + 1]; if ( bwb_cmdtable[ l->cmdnum ].vector != bwb_xend ) { return FALSE; } position = l->startpos; adv_ws( l->buffer, &position ); adv_element( l->buffer, &position, tbuf ); bwb_strtoupper( tbuf ); if ( strcmp( tbuf, "SUB" ) == 0 ) { return TRUE; } return FALSE; }/*************************************************************** FUNCTION: bwb_endsub() DESCRIPTION: This C function implements the BASIC END SUB command, ending a subroutine definition. Because the command END can have multiple meanings, this function should be called from the bwb_xend() function, which should be able to identify an END SUB command. SYNTAX: END SUB***************************************************************/#if ANSI_Cstruct bwb_line *bwb_endsub( struct bwb_line *line )#elsestruct bwb_line *bwb_endsub( line ) struct bwb_line *line;#endif { struct bwb_variable *l; register int c; /* assign local variable values to calling variables */ l = CURTASK excs[ CURTASK exsc ].local_variable; for ( c = 0; c < CURTASK excs[ CURTASK exsc ].n_cvs; ++c ) { bwb_vtov( CURTASK excs[ CURTASK exsc ].calling_variable[ c ], l ); l = l->next; } /* decrement the EXEC stack counter */ bwb_decexec(); /* if the previous level was EXEC_MAIN, then execution continues from this point */ if ( CURTASK excs[ CURTASK exsc + 1 ].code == EXEC_MAIN ) { return bwb_zline( line ); } /* else return next from old line */ CURTASK excs[ CURTASK exsc ].line->next->position = 0; return CURTASK excs[ CURTASK exsc ].line->next; }/*************************************************************** FUNCTION: find_label() DESCRIPTION: This C function finds a program line that begins with the label included in <buffer>.***************************************************************/#if ANSI_Cextern struct bwb_line *find_label( char *buffer )#elseextern struct bwb_line *find_label( buffer ) char *buffer;#endif { struct fslte *f; for ( f = CURTASK fslt_start.next; f != & ( CURTASK fslt_end ); f = f->next ) { if ( strcmp( buffer, f->name ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_label(): found label <%s>", buffer ); bwb_debug( bwb_ebuf );#endif return f->line; } }#if PROG_ERRORS sprintf( bwb_ebuf, "in find_label(): failed to find label <%s>", buffer ); bwb_error( bwb_ebuf );#else bwb_error( err_lnnotfound );#endif return NULL; }/*************************************************************** FUNCTION: bwb_doloop() DESCRIPTION: This C function implements the ANSI BASIC DO statement, when DO is not followed by an argument. It is called by bwb_do() in bwb_cmd.c. SYNTAX: DO***************************************************************/#if ANSI_Cstruct bwb_line *bwb_doloop( struct bwb_line *l )#elsestruct bwb_line *bwb_doloop( l ) struct bwb_line *l;#endif { /* if this is the first time at this DO statement, note it */ if ( CURTASK excs[ CURTASK exsc ].while_line != l ) { bwb_incexec(); CURTASK excs[ CURTASK exsc ].while_line = l; /* find the LOOP statement */ CURTASK excs[ CURTASK exsc ].wend_line = find_loop( l ); if ( CURTASK excs[ CURTASK exsc ].wend_line == NULL ) { return bwb_zline( l ); }#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_doloop(): initialize DO loop, line <%d>", l->number ); bwb_debug( bwb_ebuf );#endif }#if INTENSIVE_DEBUG else { sprintf( bwb_ebuf, "in bwb_doloop(): return to DO loop, line <%d>", l->number ); bwb_debug( bwb_ebuf ); }#endif bwb_setexec( l, l->position, EXEC_DO ); return bwb_zline( l ); }/*************************************************************** FUNCTION: bwb_loop() DESCRIPTION: This C function implements the ANSI BASIC LOOP statement. SYNTAX: LOOP [UNTIL expression] ***************************************************************/#if ANSI_Cstruct bwb_line *bwb_loop( struct bwb_line *l )#elsestruct bwb_line *bwb_loop( l ) struct bwb_line *l;#endif { char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_loop(): entered subroutine" ); bwb_debug( bwb_ebuf );#endif /* If the current exec stack is set for EXEC_WHILE, then we presume that this is a LOOP statement ending a DO WHILE loop */ if ( CURTASK excs[ CURTASK exsc ].code == EXEC_WHILE ) { return bwb_wend( l ); } /* check integrity of DO loop */ if ( CURTASK excs[ CURTASK exsc ].code != EXEC_DO ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_loop(): exec stack code != EXEC_DO" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif } if ( CURTASK excs[ CURTASK exsc ].while_line == NULL ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_loop(): exec stack while_line == NULL" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif } /* advance to find the first argument */ adv_element( l->buffer, &( l->position ), tbuf ); bwb_strtoupper( tbuf ); /* detect a LOOP UNTIL structure */ if ( strcmp( tbuf, CMD_XUNTIL ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_loop(): detected LOOP UNTIL" ); bwb_debug( bwb_ebuf );#endif return bwb_loopuntil( l ); } /* LOOP does not have UNTIL */ else { /* reset to the top of the current DO loop */#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_loop() return to line <%d>", CURTASK excs[ CURTASK exsc ].while_line->number ); bwb_debug( bwb_ebuf );#endif CURTASK excs[ CURTASK exsc ].while_line->position = 0; bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_DO ); return CURTASK excs[ CURTASK exsc ].while_line; } }/*************************************************************** FUNCTION: bwb_loopuntil() DESCRIPTION: This C function implements the ANSI BASIC LOOP UNTIL statement and is called by bwb_loop().***************************************************************/#if ANSI_Cstatic struct bwb_line *bwb_loopuntil( struct bwb_line *l )#elsestatic struct bwb_line *bwb_loopuntil( l ) struct bwb_line *l;#endif { struct exp_ese *e; struct bwb_line *r;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_loopuntil(): entered subroutine" ); bwb_debug( bwb_ebuf );#endif /* call bwb_exp() to interpret the expression */ e = bwb_exp( l->buffer, FALSE, &( l->position ) ); if ( (int) exp_getnval( e ) == TRUE ) { CURTASK excs[ CURTASK exsc ].while_line = NULL; r = CURTASK excs[ CURTASK exsc ].wend_line; bwb_setexec( r, 0, CURTASK excs[ CURTASK exsc - 1 ].code ); r->position = 0; bwb_decexec(); return r; } /* condition is false: loop around to DO again */ else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_loopuntil() return to line <%d>", CURTASK excs[ CURTASK exsc ].while_line->number ); bwb_debug( bwb_ebuf );#endif CURTASK excs[ CURTASK exsc ].while_line->position = 0; bwb_setexec( CURTASK excs[ CURTASK exsc ].while_line, 0, EXEC_DO ); return CURTASK excs[ CURTASK exsc ].while_line; } }/*************************************************************** FUNCTION: bwb_exit() DESCRIPTION: This C function implements the BASIC EXIT statement, calling subroutines for either EXIT FOR or EXIT DO. SYNTAX: EXIT FOR|DO***************************************************************/#if ANSI_Cstruct bwb_line *bwb_exit( struct bwb_line *l )#elsestruct bwb_line *bwb_exit( l ) struct bwb_line *l;#endif { char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_exit(): entered subroutine" ); bwb_debug( bwb_ebuf );#endif adv_element( l->buffer, &( l->position ), tbuf ); bwb_strtoupper( tbuf ); if ( strcmp( tbuf, CMD_XFOR ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_exit(): detected EXIT FOR" ); bwb_debug( bwb_ebuf );#endif return bwb_exitfor( l ); } if ( strcmp( tbuf, CMD_XDO ) == 0 ) { return bwb_exitdo( l ); }#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_exit(): Nonsense or nothing following EXIT" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return bwb_zline( l ); }/*************************************************************** FUNCTION: bwb_exitdo() DESCRIPTION: This function handles the BASIC EXIT DO statement. This is a structured programming command compatible with ANSI BASIC. It is called from the bwb_exit() subroutine.***************************************************************/#if ANSI_Cstruct bwb_line *bwb_exitdo( struct bwb_line *l )#elsestruct bwb_line *bwb_exitdo( l ) struct bwb_line *l;#endif { struct bwb_line *next_line; int found; register int level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_exitdo(): entered subroutine" ); bwb_debug( bwb_ebuf );#endif /* Check the integrity of the DO statement */ found = FALSE; level = CURTASK exsc; do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -