⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bwb_cnd.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
struct bwb_line *bwb_endif( l )   struct bwb_line *l;#endif   {#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_endif(): entered function" );   bwb_debug( bwb_ebuf );#endif   if (( CURTASK excs[ CURTASK exsc ].code != EXEC_IFTRUE )      && ( CURTASK excs[ CURTASK exsc ].code != EXEC_IFFALSE ))      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_endif(): END IF without IF" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      }   bwb_decexec();#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ));#endif   return bwb_zline( l );   }/***************************************************************        FUNCTION:       find_endif()        DESCRIPTION:    This C function attempts to find an			END IF statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_endif( struct bwb_line *l, struct bwb_line **else_line )#elsestatic struct bwb_line *find_endif( l, else_line )   struct bwb_line *l;   struct bwb_line **else_line;#endif   {   struct bwb_line *current;   register int i_level;   int position;   *else_line = NULL;   i_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_if )            {            ++i_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_endif(): found IF at line %d, level %d",               current->number, i_level );            bwb_debug( bwb_ebuf );#endif            }         else if ( is_endif( current ) == TRUE )            {            --i_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_endif(): found END IF at line %d, level %d",               current->number, i_level );            bwb_debug( bwb_ebuf );#endif            if ( i_level == 0 )               {               return current;               }            }         else if ( ( bwb_cmdtable[ current->cmdnum ].vector == bwb_else )            || ( bwb_cmdtable[ current->cmdnum ].vector == bwb_elseif ))            {            /* we must only report the first ELSE or ELSE IF we encounter               at level 1 */            if ( ( i_level == 1 ) && ( *else_line == NULL ))               {               *else_line = current;               }            }         }      }#if PROG_ERRORS   sprintf( bwb_ebuf, "Multiline IF without END IF" );   bwb_error( bwb_ebuf );#else   bwb_error( err_syntax  );#endif   return NULL;   }/***************************************************************	FUNCTION:       is_endif()	DESCRIPTION:    This C function attempts to determine if			a given line contains an END IF statement.***************************************************************/#if ANSI_Cstatic intis_endif( struct bwb_line *l )#elsestatic intis_endif( 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, "IF" ) == 0 )      {      return TRUE;      }   return FALSE;   }/***************************************************************        FUNCTION:       bwb_select()        DESCRIPTION:    This C function handles the BASIC SELECT                        statement.	SYNTAX:		SELECT CASE expression***************************************************************/#if ANSI_Cstruct bwb_line *bwb_select( struct bwb_line *l )#elsestruct bwb_line *bwb_select( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   struct exp_ese *e;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_select(): entered function" );   bwb_debug( bwb_ebuf );#endif   /* first element should be "CASE" */   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   if ( strcmp( tbuf, "CASE" ) != 0 )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "SELECT without CASE" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );      return bwb_zline( l );#endif      }   /* increment the level and set to EXEC_SELFALSE */   bwb_incexec();   CURTASK excs[ CURTASK exsc ].code = EXEC_SELFALSE;   /* evaluate the expression at this level */   e = bwb_exp( l->buffer, FALSE, &( l->position ) );#if OLDWAY   memcpy( &( CURTASK excs[ CURTASK exsc ].expression ), e,      sizeof( struct exp_ese ) );#endif   if ( e->type == STRING )      {      CURTASK excs[ CURTASK exsc ].expression.type = STRING;      str_btob( &( CURTASK excs[ CURTASK exsc ].expression.sval ),	 &( e->sval ) );      }   else      {      CURTASK excs[ CURTASK exsc ].expression.type = NUMBER;      CURTASK excs[ CURTASK exsc ].expression.nval	 = exp_getnval( e );      }   /* return */#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ));#endif   return bwb_zline( l );   }/***************************************************************        FUNCTION:       bwb_case()        DESCRIPTION:    This C function handles the BASIC CASE                        statement.	SYNTAX:		CASE constant | IF partial-expression | ELSE***************************************************************/#if ANSI_Cstruct bwb_line *bwb_case( struct bwb_line *l )#elsestruct bwb_line *bwb_case( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   int oldpos;   struct exp_ese minvalue;   struct exp_ese *maxval, *minval;   struct bwb_line *retline;   char cbuf1[ MAXSTRINGSIZE + 1 ];   char cbuf2[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_case(): entered function" );   bwb_debug( bwb_ebuf );#endif   /* if code is EXEC_SELTRUE, then we should jump to the end */   if ( CURTASK excs[ CURTASK exsc ].code == EXEC_SELTRUE )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_case(): exit EXEC_SELTRUE" );      bwb_debug( bwb_ebuf );#endif      retline = find_endselect( l );      retline->position = 0;      return retline;      }   /* read first element */   oldpos = l->position;   adv_element( l->buffer, &( l->position ), tbuf );   bwb_strtoupper( tbuf );   /* check for CASE IF */   if ( strcmp( tbuf, CMD_IF ) == 0 )      {      return bwb_caseif( l );      }   /* check for CASE ELSE: if true, simply proceed to the next line,      because other options should have been detected by now */   else if ( strcmp( tbuf, CMD_ELSE ) == 0 )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_case(): execute CASE ELSE" );      bwb_debug( bwb_ebuf );#endif      return bwb_zline( l );      }   /* neither CASE ELSE nor CASE IF; presume constant here for min value */   l->position = oldpos;   minval = bwb_exp( l->buffer, FALSE, &( l->position ));   memcpy( &minvalue, minval, sizeof( struct exp_ese ) );   maxval = minval = &minvalue;   /* check for string value */   if ( minvalue.type == STRING )      {      str_btoc( cbuf1, &( CURTASK excs[ CURTASK exsc ].expression.sval ) );      str_btoc( cbuf2, &( minvalue.sval ) );#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_case(): compare strings <%s> and <%s>",	 cbuf1, cbuf2 );      bwb_debug( bwb_ebuf );#endif      if ( strncmp( cbuf1, cbuf2, MAXSTRINGSIZE ) == 0 )	 {#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_case(): string comparison returns TRUE" );	 bwb_debug( bwb_ebuf );#endif	 CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;#if MULTISEG_LINES         adv_eos( l->buffer, &( l->position ));#endif	 return bwb_zline( l );	 }      else	 {#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in bwb_case(): string comparison returns FALSE" );	 bwb_debug( bwb_ebuf );#endif	 retline = find_case( l );	 retline->position = 0;	 return retline;	 }      }   /* not a string; advance */   adv_ws( l->buffer, &( l->position ));   /* check for TO */   if ( is_eol( l->buffer, &( l->position )) != TRUE )      {      /* find the TO statement */      adv_element( l->buffer, &( l->position ), tbuf );      bwb_strtoupper( tbuf );      if ( strcmp( tbuf, CMD_TO ) != 0 )         {#if PROG_ERRORS         sprintf( bwb_ebuf, "CASE has inexplicable code following expression" );         bwb_error( bwb_ebuf );#else         bwb_error( err_syntax );#if MULTISEG_LINES         adv_eos( l->buffer, &( l->position ));#endif         return bwb_zline( l );#endif         }      /* now evaluate the MAX expression */      maxval = bwb_exp( l->buffer, FALSE, &( l->position ));      }   /* evaluate the expression */   if ( case_eval( &( CURTASK excs[ CURTASK exsc ].expression ),      minval, maxval ) == TRUE )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_case(): evaluation returns TRUE" );      bwb_debug( bwb_ebuf );#endif      CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;#if MULTISEG_LINES      adv_eos( l->buffer, &( l->position ));#endif      return bwb_zline( l );      }   /* evaluation returns a FALSE value; find next CASE or END SELECT statement */   else      {#if INTENSIVE_DEBUGb      sprintf( bwb_ebuf, "in bwb_case(): evaluation returns FALSE" );      bwb_debug( bwb_ebuf );#endif      retline = find_case( l );      retline->position = 0;      return retline;      }   }/***************************************************************        FUNCTION:       bwb_caseif()        DESCRIPTION:    This C function handles the BASIC CASE IF                        statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *bwb_caseif( struct bwb_line *l )#elsestatic struct bwb_line *bwb_caseif( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   int position;   struct exp_ese *r;   struct bwb_line *retline;   if ( CURTASK excs[ CURTASK exsc ].expression.type == NUMBER )      {      sprintf( tbuf, "%f %s",         (float) CURTASK excs[ CURTASK exsc ].expression.nval,         &( l->buffer[ l->position ] ) );      }   else      {      bwb_error( err_mismatch );#if MULTISEG_LINES      adv_eos( l->buffer, &( l->position ));#endif      return bwb_zline( l );      }   position = 0;   r = bwb_exp( tbuf, FALSE, &position );   if ( r->nval == (bnumber) TRUE )      {      CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;#if MULTISEG_LINES      adv_eos( l->buffer, &( l->position ));#endif      return bwb_zline( l );      }   else      {      retline = find_case( l );      retline->position = 0;      return retline;      }   }/***************************************************************        FUNCTION:       case_eval()        DESCRIPTION:    This function evaluates a case statement			by comparing minimum and maximum values			with a set expression. It returns either			TRUE or FALSE***************************************************************/#if ANSI_Cstatic intcase_eval( struct exp_ese *expression, struct exp_ese *minval,   struct exp_ese *maxval )#elsestatic intcase_eval( expression, minval, maxval )   struct exp_ese *expression;   struct exp_ese *minval;   struct exp_ese *maxval;#endif   {   /* string value */   if ( expression->type == STRING )      {      bwb_error( err_mismatch );      return FALSE;      }   /* numerical value */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in case_eval(): n <%f> min <%f> max <%f>",      (float) expression->nval,      (float) minval->nval,      (float) maxval->nval );   bwb_debug( bwb_ebuf );#endif   if (  ( expression->nval >= minval->nval )      && ( expression->nval <= maxval->nval ))      {      return TRUE;      }   return FALSE;   }/***************************************************************        FUNCTION:       find_case()        DESCRIPTION:    This function searches for a line containing                        a CASE statement corresponding to a previous                        SELECT CASE statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_case( struct bwb_line *l )#elsestatic struct bwb_line *find_case( l )   struct bwb_line *l;#endif   {   struct bwb_line *current;   register int c_level;   int position;   c_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_select )            {            ++c_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_case(): found SELECT at line %d, level %d",               current->number, c_level );            bwb_debug( bwb_ebuf );#endif            }         else if ( is_endselect( current ) == TRUE )            {            --c_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_endif(): found END SELECT at line %d, level %d",               current->number, c_level );            bwb_debug( bwb_ebuf );#endif            if ( c_level == 0 )               {               return current;               }            }         else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_case )            {            --c_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in find_case(): found CASE at line %d, level %d",               current->number, c_level );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -