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

📄 bwb_stc.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
      {      if ( CURTASK excs[ level ].code == EXEC_DO )	 {	 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 DO without DO" );      bwb_error( bwb_ebuf );#else      bwb_error( err_syntax );#endif      return bwb_zline( l );      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_exitdo(): 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 );   return next_line;   }#endif					/* STRUCT_CMDS *//***************************************************************	FUNCTION:       bwb_vtov()	DESCRIPTION:    This function assigns the value of one			bwBASIC variable (src) to the value of another			bwBASIC variable (dst).***************************************************************/#if ANSI_Cstruct bwb_variable *bwb_vtov( struct bwb_variable *dst,   struct bwb_variable *src )#elsestruct bwb_variable *bwb_vtov( dst, src )   struct bwb_variable *dst;   struct bwb_variable *src;#endif   {   if ( dst == src )      {      return dst;      }   if ( src->type != dst->type )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_vtov(): mismatch src <%s> type <%d> dst <%s> type <%d>",	 src->name, src->type, dst->name, dst->type );      bwb_error( bwb_ebuf );#else      bwb_error( err_mismatch );#endif      return NULL;      }   if ( dst->type == NUMBER )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in bwb_vtov(): assigning var <%s> val <%lf> to var <%s>",	 src->name, var_getnval( src ), dst->name );      bwb_debug( bwb_ebuf );#endif      * var_findnval( dst, dst->array_pos ) = var_getnval( src );      }   else      {      str_btob( var_getsval( dst ), var_getsval( src ) );      }   return dst;   }/***************************************************************	FUNCTION:       bwb_etov()	DESCRIPTION:    This function assigns the value of a			bwBASIC expression stack element (src)			to the value of a bwBASIC variable (dst).***************************************************************/#if ANSI_Cstruct bwb_variable *bwb_etov( struct bwb_variable *dst, struct exp_ese *src )#elsestruct bwb_variable *bwb_etov( dst, src )   struct bwb_variable *dst;   struct exp_ese *src;#endif   {   if ( (int) src->type != dst->type )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in bwb_etov(): mismatch src <%d> dst <%d>",         src->type, dst->type );      bwb_error( bwb_ebuf );#else      bwb_error( err_mismatch );#endif      return NULL;      }   if ( dst->type == NUMBER )      {      * var_findnval( dst, dst->array_pos ) = exp_getnval( src );      }   else      {      str_btob( var_getsval( dst ), exp_getsval( src ) );      }   return dst;   }/***************************************************************	FUNCTION:       var_pos()	DESCRIPTION:    This function returns the name of a			local variable at a specified position			in the local variable list.***************************************************************/#if ANSI_Cstruct bwb_variable *var_pos( struct bwb_variable *firstvar, int p )#elsestruct bwb_variable *var_pos( firstvar, p )   struct bwb_variable *firstvar;   int p;#endif   {   register int c;   struct bwb_variable *v;   v = firstvar;   for ( c = 0; c != p; ++c )      {      v = v->next;      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in var_pos(): returning pos <%d> variable <%s>",      p, v->name );   bwb_debug( bwb_ebuf );#endif   return v;   }/***************************************************************	FUNCTION:       fslt_addcallvar()	DESCRIPTION:    This function adds a calling variable			to the FUNCTION-SUB lookup table at			a specific level.***************************************************************/#if ANSI_Cintfslt_addcallvar( struct bwb_variable *v )#elseintfslt_addcallvar( v )   struct bwb_variable *v;#endif   {   if ( CURTASK excs[ CURTASK exsc ].n_cvs >= MAX_FARGS )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "in fslt_addcallvar(): Maximum number of Function Args Exceeded" );      bwb_error( bwb_ebuf );#else      bwb_error( err_overflow );#endif      }   CURTASK excs[ CURTASK exsc ].calling_variable[ CURTASK excs[ CURTASK exsc ].n_cvs ] = v;   ++CURTASK excs[ CURTASK exsc ].n_cvs;   return TRUE;   }/***************************************************************	FUNCTION:       exp_ufnc()        DESCRIPTION:	This C function interprets a user-defined			function, returning its value at the current			level of the expression stack.***************************************************************/#if ANSI_Cintexp_ufnc( char *expression )#elseintexp_ufnc( expression )   char *expression;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   struct bwb_line *call_line;   struct fslte *f, *c;   struct bwb_variable *v, *r;   struct exp_ese *e;   int save_elevel;   int position, epos;#if INTENSIVE_DEBUG   register int i;#endif   position = 0;   /* get the function name in tbuf */   exp_getvfname( expression, tbuf );   /* find the function name in the function-subroutine lookup table */   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_ufnc(): found user function <%s>",	    tbuf );	 bwb_debug( bwb_ebuf );#endif	 c = f; 		/* current function-subroutine lookup table element */	 call_line = f->line;	/* line to call for function */	 }      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_ufnc(): call to function <%s>", tbuf );   bwb_debug( bwb_ebuf );#endif   position += strlen( tbuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_ufnc(): found line <%s>",      call_line->buffer );   bwb_debug( bwb_ebuf );#endif   /* save the old position on the EXEC stack */   bwb_setexec( CURTASK excs[ CURTASK exsc ].line,      position, CURTASK excs[ CURTASK exsc ].code );   save_elevel = CURTASK exsc;   /* increment and set new EXEC stack */   bwb_incexec();   call_line->position = 0;   bwb_setexec( call_line, 0, EXEC_FUNCTION );   /* attach local variables */   CURTASK excs[ CURTASK exsc ].local_variable = c->local_variable;#if INTENSIVE_DEBUG   i = 0;   sprintf( bwb_ebuf, "in exp_ufnc(): <%s> attached local variables EXEC level <%d>",      tbuf, CURTASK exsc );   bwb_debug( bwb_ebuf );   for ( v = CURTASK excs[ CURTASK exsc ].local_variable; v != NULL; v = v->next )      {      sprintf( bwb_ebuf, "in exp_ufnc():   <%s> level <%d> variable <%d> name <%s>",	 tbuf, CURTASK exsc, i, v->name );      bwb_debug( bwb_ebuf );      ++i;      }   getchar();#endif   /* read calling variables for this call */   call_readargs( c, expression, &position );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_ufnc(): current buffer <%s>",      &( call_line->buffer[ c->startpos ] ) );   bwb_debug( bwb_ebuf );#endif   /* determine if single-line function */   epos = c->startpos;   adv_ws( call_line->buffer, &epos );   if ( call_line->buffer[ epos ] == '=' )      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_ufnc(): found SINGLE-LINE function" );      bwb_debug( bwb_ebuf );#endif      ++epos;      call_line->position = epos;      bwb_setexec( call_line, epos, EXEC_FUNCTION );#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_ufnc(): single line: parse <%s>",	 &( call_line->buffer[ epos ] ) );      bwb_debug( bwb_ebuf );#endif      e = bwb_exp( call_line->buffer, FALSE, &epos );      v = var_find( tbuf );#if INTENSIVE_DEBUG      if ( e->type == STRING )	 {	 sprintf( bwb_ebuf, "in exp_ufnc(): expression returns <%d>-byte string",	    exp_getsval( e )->length );	 bwb_debug( bwb_ebuf );	 }      else	 {	 sprintf( bwb_ebuf, "in exp_ufnc(): expression returns number <%lf>",	    (double) exp_getnval( e ) );	 bwb_debug( bwb_ebuf );	 }#endif#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_ufnc(): single line after parsing, <%s>",	 &( call_line->buffer[ epos ] ) );      bwb_debug( bwb_ebuf );#endif      bwb_etov( v, e );      bwb_decexec();      }   /* multi-line function must be executed now */   else      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in exp_ufnc(): found MULTI-LINE function" );      bwb_debug( bwb_ebuf );#endif      /* now execute until function is resolved */      bwb_execline();      while( CURTASK exsc > save_elevel )	 {	 bwb_execline();	 }      /* find the return value */      for ( r = c->local_variable; r != NULL; r = r->next )	 {	 if ( strcmp( r->name, c->name ) == 0 )	    {	    v = r;	    }	 }      }   /* now place value in expression stack */   CURTASK exps[ CURTASK expsc ].type = (char) v->type;   CURTASK exps[ CURTASK expsc ].pos_adv = position;   switch( v->type )      {      case STRING:	 CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;#if INTENSIVE_DEBUG	 sprintf( bwb_ebuf, "in exp_ufnc(): ready to assign <%d>-byte STRING",	    var_getsval( v )->length );	 bwb_debug( bwb_ebuf );#endif	 str_btob( exp_getsval( &( CURTASK exps[ CURTASK expsc ] )),	    var_getsval( v ) );#if INTENSIVE_DEBUG	 str_btoc( tbuf, var_getsval( v ) );	 sprintf( bwb_ebuf, "in exp_ufnc(): string assigned <%s>", tbuf );	 bwb_debug( bwb_ebuf );#endif	 break;      default:	 CURTASK exps[ CURTASK expsc ].operation = NUMBER;	 CURTASK exps[ CURTASK expsc ].nval = var_getnval( v );	 break;      }   return TRUE;   }/***************************************************************	FUNCTION:       fslt_addlocalvar()	DESCRIPTION:    This function adds a local variable			to the FUNCTION-SUB lookup table at			a specific level.***************************************************************/#if ANSI_Cintfslt_addlocalvar( struct fslte *f, struct bwb_variable *v )#elseintfslt_addlocalvar( f, v )   struct fslte *f;   struct bwb_variable *v;#endif   {   struct bwb_variable *c, *p;#if INTENSIVE_DEBUG   register int i;#endif   /* find end of local chain */   if ( f->local_variable == NULL )      {#if INTENSIVE_DEBUG      i = 0;#endif      f->local_variable = v;      }   else      {#if INTENSIVE_DEBUG      i = 1;#endif      p = f->local_variable;      for ( c = f->local_variable->next; c != NULL; c = c->next )         {         p = c;#if INTENSIVE_DEBUG         ++i;#endif         }      p->next = v;      }   v->next = NULL;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in fslt_addlocalvar(): added local variable variable <%s> arg number <%d>",      v->name, i );   bwb_debug( bwb_ebuf );   getchar();#endif   return TRUE;   }/***************************************************************	FUNCTION:       fslt_init()	DESCRIPTION:    This function initializes the FUNCTION-SUB			lookup table.***************************************************************/#if ANSI_Cintfslt_init( int task )#elseintfslt_init( task )   int task;#endif   {   LOCALTASK fslt_start.next = &(LOCALTASK fslt_end);   return TRUE;   }/***************************************************************	FUNCTION:       is_label()	DESCRIPTION:    This function determines whether the string			pointed to by 'buffer' is a label (i.e.,			ends with colon).***************************************************************/#if ANSI_Cextern intis_label( char *buffer )#elseintis_label( buffer )   char *buffer;#endif   {#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in is_label(): check element <%s>", buffer );   bwb_debug( bwb_ebuf );#endif   if ( buffer[ strlen( buffer ) - 1 ] == ':' )      {      return TRUE;      }   else      {      return FALSE;      }   }

⌨️ 快捷键说明

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