📄 bwb_exp.c
字号:
***************************************************************/#if ANSI_Cintexp_findop( char *expression )#elseintexp_findop( expression ) char *expression;#endif { register int c; /* character counter */ int carry_on; /* boolean: control while loop */ int rval; /* return value */ char cbuf[ MAXSTRINGSIZE + 1 ]; /* capitalized expression */ char nbuf[ MAXSTRINGSIZE + 1 ]; /* non-capitalized expression */ int position; /* position in the expression */ int adv_loop; /* control loop to build expression */#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_findop(): received <%s>", expression ); bwb_debug( bwb_ebuf );#endif /* set return value to OP_NULL initially */ rval = OP_NULL; /* assign local pointer to expression to begin reading */ position = 0; /* advance to the first significant character */ adv_ws( expression, &position );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_findop(): expression after advance <%s>", &( expression[ position ] ) ); bwb_debug( bwb_ebuf );#endif /* we now have the first significant character and can begin parsing */ /* check the first character for an indication of a parenthetical expression, a string constant, or a numerical constant that begins with a digit (numerical constants beginning with a plus or minus sign or hex/octal/binary constants will have to be detected by exp_isnc() */ carry_on = TRUE; switch ( expression[ position ] ) { case '\"': /* this should indicate a string constant */ rval = CONST_STRING; break; case '(': /* this will indicate a simple parenthetical expression */ rval = PARENTHESIS; break;#if MULTISEG_LINES case ':': /* terminate processing */#endif case ')': /* end of argument list? */ rval = OP_TERMINATE; break; case '0': /* these will indicate a numerical constant */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '&': /* designator for hex or octal constant */ rval = CONST_NUMERICAL; break; }#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_findop(): rval pos 1 is <%d>", rval ); bwb_debug( bwb_ebuf );#endif /* String constants, numerical constants, open parentheses, and the plus and minus operators have been checked at this point; but if the return value is still OP_NULL, other possibilities must be checked, namely, other operators, function names, and variable names. The function adv_element cannot be used here because it will stop, e.g., with certain operators and not include them in the returned element. */ /* get a character string to be interpreted */ adv_loop = TRUE; cbuf[ 0 ] = '\0'; nbuf[ 0 ] = '\0'; c = 0; while ( adv_loop == TRUE ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_findop() loop position <%d> char 0x%x", c, expression[ position ] ); bwb_debug( bwb_ebuf );#endif switch( expression[ position ] ) { case ' ': /* whitespace */ case '\t': case '\r': /* end of line */ case '\n': case '\0': /* end of string */ case '(': /* parenthesis terminating function name */ adv_loop = FALSE; break; default: nbuf[ c ] = cbuf[ c ] = expression[ position ]; ++c; nbuf[ c ] = cbuf[ c ] = '\0'; ++position; break; } if ( c >= MAXSTRINGSIZE ) { adv_loop = FALSE; } } bwb_strtoupper( cbuf );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_findop(): cbuf element is <%s>", cbuf ); bwb_debug( bwb_ebuf );#endif /* check for numerical constant */ if ( rval == OP_NULL ) { rval = exp_isnc( cbuf ); } /* check for other operators */ if ( rval == OP_NULL ) { rval = exp_isop( cbuf ); } /* check for user-defined function */ if ( rval == OP_NULL ) { rval = exp_isufn( nbuf ); } /* check for function name */ if ( rval == OP_NULL ) { rval = exp_isfn( nbuf ); } /* check for a BASIC command, esp. to catch THEN or ELSE */ if ( rval == OP_NULL ) { rval = exp_iscmd( cbuf ); } /* last: check for variable name, and assign it if there is not already one */ if ( rval == OP_NULL ) { rval = exp_isvn( nbuf ); } /* return the value assigned (or OP_ERROR if none assigned) */ if ( rval == OP_NULL ) { return OP_ERROR; } else { return rval; } }/*************************************************************** FUNCTION: exp_isnc() DESCRIPTION: This function reads the expression to find if a numerical constant is present at this point.***************************************************************/#if ANSI_Cintexp_isnc( char *expression )#elseintexp_isnc( expression ) char *expression;#endif { char tbuf[ MAXVARNAMESIZE + 1 ]; /* JBV */ switch( expression[ 0 ] ) { case '0': /* these will indicate a numerical constant */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': /* indicator for hex or octal constant */ return CONST_NUMERICAL; case '+': case '-': /* if the previous stack level was a numerical value or a string, then this is certainly not one; return OP_NULL here and let the next function call to exp_isop() determine the (plus or minus) operator */ if ( ( CURTASK exps[ CURTASK expsc - 1 ].operation == NUMBER ) || ( CURTASK exps[ CURTASK expsc - 1 ].operation == VARIABLE ) || ( CURTASK exps[ CURTASK expsc - 1 ].operation == CONST_STRING ) ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_isnc(): previous function is a number or string" ); bwb_debug( bwb_ebuf );#endif return OP_NULL; } /* similarly, if the previous stack level was a variable with a numerical value (not a string), then this level must be an operator, not a numerical constant */ if ( ( CURTASK exps[ CURTASK expsc - 1 ].operation == VARIABLE ) && ( CURTASK exps[ CURTASK expsc - 1 ].type != STRING )) { return OP_NULL; } /*--------------------------------------------------------*/ /* Check for unary minus sign added by JBV. */ /* Could be prefixing a parenthetical expression or a */ /* variable name. */ /* But parentheses won't show up in expression (cbuf), so */ /* just check for expression and variable name lengths. */ /*--------------------------------------------------------*/ if (expression[0] == '-') { if (strlen(expression) == 1) return OP_NEGATION; exp_getvfname(&expression[1], tbuf); if (strlen(tbuf) != 0) return OP_NEGATION; } /* failing these tests, the argument must be a numerical constant preceded by a plus or minus sign */ return CONST_NUMERICAL; default: return OP_NULL; } }/*************************************************************** FUNCTION: exp_isop() DESCRIPTION: This function reads the expression to find if a logical or mathematical operation is required at this point. This function presupposes that a numerical constant with affixed plus or minus sign has been ruled out.***************************************************************/#if ANSI_Cintexp_isop( char *expression )#elseintexp_isop( expression ) char *expression;#endif { register int c; /* counter */#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_isop(): expression is <%s>", expression ); bwb_debug( bwb_ebuf );#endif /* compare the initial characters of the string with the table of operators */ for ( c = 0; c < N_OPERATORS; ++c ) { if ( strncmp( expression, exp_ops[ c ].symbol, (size_t) strlen( exp_ops[ c ].symbol ) ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_isop(): match <%s>, number <%d>.", exp_ops[ c ].symbol, c ); bwb_debug( bwb_ebuf );#endif return exp_ops[ c ].operation; } } /* search failed; return OP_NULL */ return OP_NULL; }/*************************************************************** FUNCTION: exp_iscmd() DESCRIPTION: This function reads the expression to find if a BASIC command name is present; if so, it returns OP_TERMINATE to terminate expression parsing. This is critical, for example, in parsing a conditional following IF where THEN, ELSE, and other BASIC commands may follow.***************************************************************/#if ANSI_Cintexp_iscmd( char *expression )#elseintexp_iscmd( expression ) char *expression;#endif { register int n;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_iscmd(): expression received <%s>", expression ); bwb_debug( bwb_ebuf );#endif /* first check for THEN or ELSE statements */ if ( strcmp( expression, CMD_THEN ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>", expression ); bwb_debug( bwb_ebuf );#endif return OP_TERMINATE; }#if STRUCT_CMDS if ( strcmp( expression, CMD_TO ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>", expression ); bwb_debug( bwb_ebuf );#endif return OP_TERMINATE; }#endif if ( strcmp( expression, CMD_ELSE ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>", expression ); bwb_debug( bwb_ebuf );#endif return OP_TERMINATE; } /* run through the command table and search for a match */ for ( n = 0; n < COMMANDS; ++n ) { if ( strcmp( expression, bwb_cmdtable[ n ].name ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_iscmd(): match found, <%s>", expression ); bwb_debug( bwb_ebuf );#endif return OP_TERMINATE; }#if INTENSIVE_DEBUG else { sprintf( bwb_ebuf, "in exp_iscmd(): No match, <%s> and <%s>; returns %d", expression, bwb_cmdtable[ n ].name, strcmp( expression, bwb_cmdtable[ n ].name ) ); bwb_debug( bwb_ebuf ); }#endif } /* search failed, return NULL */ return OP_NULL; }/*************************************************************** FUNCTION: exp_isufn() DESCRIPTION: This function reads the expression to find if a user-defined function name is present at this point.***************************************************************/#if ANSI_Cintexp_isufn( char *expression )#elseintexp_isufn( expression ) char *expression;#endif { struct fslte *f; char tbuf[ MAXVARNAMESIZE + 1 ]; exp_getvfname( expression, tbuf ); for ( f = CURTASK fslt_start.next; f != &CURTASK fslt_end; f = f->next ) { if ( strcmp( f->name, tbuf ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_isufn(): found user function <%s>", tbuf ); bwb_debug( bwb_ebuf );#endif /* a user function name was found: but is it the local variable name for the user function? If so, return OP_NULL and the name will be read as a variable */ if ( var_islocal( tbuf ) != NULL ) { return OP_NULL; } else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in exp_isufn(): found function <%s> not a local variable, EXEC level <%d>", tbuf, CURTASK exsc ); bwb_debug( bwb_ebuf ); getchar();#endif return OP_USERFNC; } } } return OP_NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -