📄 bwb_cnd.c
字号:
var_setnval( v, exp_getnval( exp ) );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): initial value <%d> pos <%d>", exp_getnval( exp ), l->position ); bwb_debug( bwb_ebuf );#endif /* copy target value to small buffer and evaluate it */ tbuf[ 0 ] = '\0'; p = 0; l->position = to + 2; if ( step < 1 ) { e = strlen( l->buffer ); } else { e = step - 1; } loop = TRUE; n = l->position; while( loop == TRUE ) { tbuf[ p ] = l->buffer[ n ]; ++p; ++l->position; tbuf[ p ] = '\0'; if ( n >= e ) { loop = FALSE; } ++n; if ( l->buffer[ n ] == ':' ) { loop = FALSE; } }#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): target value string <%s>", tbuf ); bwb_debug( bwb_ebuf );#endif p = 0; exp = bwb_exp( tbuf, FALSE, &p ); for_target = (int) exp_getnval( exp );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): target value <%d> pos <%d>", exp_getnval( exp ), l->position ); bwb_debug( bwb_ebuf );#endif /* If there is a STEP statement, copy it to a buffer and evaluate it */ if ( step > 1 ) { tbuf[ 0 ] = '\0'; p = 0; l->position = step + 4; for ( n = l->position; n < (int) strlen( l->buffer ); ++n ) { tbuf[ p ] = l->buffer[ n ]; ++p; ++l->position; tbuf[ p ] = '\0'; }#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): step value string <%s>", tbuf ); bwb_debug( bwb_ebuf );#endif p = 0; exp = bwb_exp( tbuf, FALSE, &p ); for_step = (int) exp_getnval( exp ); } else { for_step = 1; }#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): step value <%d>", for_step ); bwb_debug( bwb_ebuf );#endif /* set position in current line and increment EXEC counter */ /* bwb_setexec( l, l->position, EXEC_NORM ); */ /* WRONG */ bwb_incexec(); CURTASK excs[ CURTASK exsc ].local_variable = v; CURTASK excs[ CURTASK exsc ].for_step = for_step; CURTASK excs[ CURTASK exsc ].for_target = for_target; /* set exit line to be used by EXIT FOR */#if STRUCT_CMDS CURTASK excs[ CURTASK exsc ].wend_line = find_next( l );#endif /* set top line and position to be used in multisegmented FOR-NEXT loop */#if MULTISEG_LINES CURTASK excs[ CURTASK exsc ].for_line = l; CURTASK excs[ CURTASK exsc ].for_position = l->position;#endif#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): setting code to EXEC_FOR", l->position ); bwb_debug( bwb_ebuf );#endif bwb_setexec( l, l->position, EXEC_FOR );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_for(): ready to exit, position <%d>", l->position ); bwb_debug( bwb_ebuf );#endif /* proceed with processing */ return bwb_zline( l ); }/*************************************************************** FUNCTION: bwb_next() DESCRIPTION: This function handles the BASIC NEXT statement. SYNTAX: NEXT counter***************************************************************/#if ANSI_Cstruct bwb_line *bwb_next( struct bwb_line *l )#elsestruct bwb_line *bwb_next( l ) struct bwb_line *l;#endif { char tbuf[ MAXSTRINGSIZE + 1 ]; struct bwb_variable *v; /* Relocated from INTENSIVE_DEBUG (JBV) */#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_next(): entered function, cmdnum <%d> exsc level <%d> code <%d>", l->cmdnum, CURTASK exsc, CURTASK excs[ CURTASK exsc ].code ); bwb_debug( bwb_ebuf );#endif /* Check the integrity of the FOR statement */ if ( CURTASK excs[ CURTASK exsc ].code != EXEC_FOR ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_next(): NEXT without FOR; code is <%d> instead of <%d>", CURTASK excs[ CURTASK exsc ].code, EXEC_FOR ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif } /* read the argument, if there is one */ /* Relocated from MULTISEG_LINES (JBV) */ exp_getvfname( &( l->buffer[ l->position ] ), tbuf ); if (strlen(tbuf) != 0) { /* Relocated from INTENSIVE_DEBUG (JBV) */ v = var_find( tbuf );#if MULTISEG_LINES /* not currently needed otherwise */ l->position += strlen( tbuf );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_next(): variable name detected <%s>.", v->name ); bwb_debug( bwb_ebuf );#endif#endif /* decrement or increment the value */ /*--------------------------------------------------------------*/ /* Make sure we are in the right FOR-NEXT level! */ /* If we aren't (which could happen for legit reasons), fix the */ /* exec stack. */ /* JBV, 9/20/95 */ /*--------------------------------------------------------------*/ while (v != CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec(); } var_setnval( CURTASK excs[ CURTASK exsc ].local_variable, var_getnval( CURTASK excs[ CURTASK exsc ].local_variable ) + (bnumber) CURTASK excs[ CURTASK exsc ].for_step ); /* check for completion of the loop */ if ( CURTASK excs[ CURTASK exsc ].for_step > 0 ) /* if step is positive */ { if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable ) > CURTASK excs[ CURTASK exsc ].for_target ) { bwb_decexec();#if MULTISEG_LINES bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );#else bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );#endif#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_next(): end of loop" ); bwb_debug( bwb_ebuf );#endif#ifdef OLD_WAY l->next->position = 0; return l->next;#else return bwb_zline( l );#endif } } else /* if step is negative */ { if ( (int) var_getnval( CURTASK excs[ CURTASK exsc ].local_variable ) < CURTASK excs[ CURTASK exsc ].for_target ) { bwb_decexec(); bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_next(): end of loop" ); bwb_debug( bwb_ebuf );#endif#ifdef OLD_WAY l->next->position = 0; return l->next;#else return bwb_zline( l );#endif } } /* Target not reached: return to the top of the FOR loop */#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_next(): resetting code to EXEC_FOR", l->position ); bwb_debug( bwb_ebuf );#endif#if MULTISEG_LINES CURTASK excs[ CURTASK exsc ].for_line->position = CURTASK excs[ CURTASK exsc ].for_position; bwb_setexec( CURTASK excs[ CURTASK exsc ].for_line, CURTASK excs[ CURTASK exsc ].for_position, EXEC_FOR ); return CURTASK excs[ CURTASK exsc ].for_line; /* Added (JBV) */#else bwb_setexec( CURTASK excs[ CURTASK exsc - 1 ].line, CURTASK excs[ CURTASK exsc - 1 ].position, EXEC_FOR ); return CURTASK excs[ CURTASK exsc - 1 ].line; /* Relocated (JBV) */#endif }#if STRUCT_CMDS/*************************************************************** FUNCTION: bwb_exitfor() DESCRIPTION: This function handles the BASIC EXIT FOR statement. This is a structured programming command compatible with ANSI BASIC. It is called from the bwb_exit() subroutine. SYNTAX: EXIT FOR ***************************************************************/#if ANSI_Cstruct bwb_line *bwb_exitfor( struct bwb_line *l )#elsestruct bwb_line *bwb_exitfor( l ) struct bwb_line *l;#endif { struct bwb_line *next_line; int found; register int level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_exitfor(): entered subroutine" ); bwb_debug( bwb_ebuf );#endif /* Check the integrity of the FOR statement */ found = FALSE; level = CURTASK exsc; do { if ( CURTASK excs[ level ].code == EXEC_FOR ) { next_line = CURTASK excs[ CURTASK level ].wend_line; found = TRUE; } else { --level; } } while ( ( level >= 0 ) && ( found == FALSE ) ); if ( found != TRUE ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_exitfor(): EXIT FOR without FOR" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return bwb_zline( l ); }#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_exitfor(): level found is <%d>, current <%d>", level, CURTASK exsc ); bwb_debug( bwb_ebuf );#endif /* decrement below the level of the NEXT statement */ while( CURTASK exsc >= level ) { bwb_decexec(); } /* set the next line in the exec stack */ next_line->position = 0; /* bwb_setexec( next_line, 0, EXEC_NORM ); */ /* WRONG (JBV) */ bwb_setexec( next_line, 0, CURTASK excs[ CURTASK exsc ].code ); /* JBV */ return next_line; }/*************************************************************** FUNCTION: find_next() DESCRIPTION: This function searches for a line containing a NEXT statement corresponding to a previous FOR statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_next( struct bwb_line *l )#elsestatic struct bwb_line *find_next( l ) struct bwb_line *l;#endif { struct bwb_line *current; register int w_level; int position; w_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_for ) { ++w_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_next(): found FOR at line %d, level %d", current->number, w_level ); bwb_debug( bwb_ebuf );#endif } else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_next ) { --w_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_next(): found NEXT at line %d, level %d", current->number, w_level ); bwb_debug( bwb_ebuf );#endif if ( w_level == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_next(): found returning line <%d>", current->next->number ); bwb_debug( bwb_ebuf );#endif return current->next; } } } }#if PROG_ERRORS sprintf( bwb_ebuf, "FOR without NEXT" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return NULL; }#endif /* STRUCT_CMDS for EXIT FOR *//*************************************************************** FUNCTION: cnd_tostep() DESCRIPTION: This function searches through the <buffer> beginning at point <position> and attempts to find positions of TO and STEP statements.***************************************************************/#if ANSI_Cstatic intcnd_tostep( char *buffer, int position, int *to, int *step )#elsestatic intcnd_tostep( buffer, position, to, step ) char *buffer; int position; int *to; int *step;#endif { int loop, t_pos, b_pos, p_word; char tbuf[ MAXSTRINGSIZE + 1 ]; /* set then and els to FALSE initially */ *to = *step = FALSE; /* loop to find words */ p_word = b_pos = position; t_pos = 0; tbuf[ 0 ] = '\0'; loop = TRUE; while ( loop == TRUE ) { switch( buffer[ b_pos ] ) { case '\0': /* end of string */ case ':': /* end of line segment */ return TRUE; case ' ': /* whitespace = end of word */ case '\t':#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in cnd_tostep(): word is <%s>", tbuf ); bwb_debug( bwb_ebuf );#endif if ( strncmp( tbuf, CMD_TO, (size_t) strlen( CMD_TO ) ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in cnd_tostep(): TO found at position <%d>.", p_word ); bwb_debug( bwb_ebuf );#endif *to = p_word; } else if ( strncmp( tbuf, CMD_STEP, (size_t) strlen( CMD_STEP ) ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in cnd_tostep(): STEP found at position <%d>.", p_word ); bwb_debug( bwb_ebuf );#endif *step = p_word; } ++b_pos; p_word = b_pos; t_pos = 0; tbuf[ 0 ] = '\0'; break; default: if ( islower( buffer[ b_pos ] ) != FALSE ) { tbuf[ t_pos ] = (char) toupper( buffer[ b_pos ] ); } else { tbuf[ t_pos ] = buffer[ b_pos ]; } ++b_pos; ++t_pos; tbuf[ t_pos ] = '\0'; break; } } return TRUE; }/*************************************************************** FUNCTION: var_setnval() DESCRIPTION: This function sets the value of numerical variable v to the value of i.***************************************************************/#if ANSI_Cextern intvar_setnval( struct bwb_variable *v, bnumber i )#elseintvar_setnval( v, i ) struct bwb_variable *v; bnumber i;#endif { switch( v->type ) { case NUMBER: * var_findnval( v, v->array_pos ) = i; break; default:#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in var_setnval(): variable <%s> is not a number", v->name ); bwb_error( bwb_ebuf );#else bwb_error( err_mismatch );#endif } /* successful assignment */ return TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -