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

📄 bwb_stc.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
         {         case '\n':		/* premature end of line */         case '\r':         case '\0':            control_loop = FALSE;            f->startpos = *position;            bwb_error( err_syntax );            return FALSE;         case ')':		/* end of argument list */            ++( *position );            control_loop = FALSE;            f->startpos = *position;            return TRUE;         default:		/* presume beginning of argument == variable name */            exp_getvfname( &( line->buffer[ *position ] ), tbuf );            *position += strlen( tbuf );#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in scan_readargs(): read argument <%s>",               tbuf );            bwb_debug( bwb_ebuf );#endif            /* initialize the variable and add it to local chain */            v = var_new( tbuf );            fslt_addlocalvar( f, v );            /* advance past the comma */            if ( line->buffer[ *position ] == ',' )               {               ++( *position );               }            break;         }      adv_ws( line->buffer, position );      }   return TRUE;   }/***************************************************************        FUNCTION:       call_readargs()        DESCRIPTION:	This C function reads arguments (variable        		names for a subroutine CALL or function			call.***************************************************************/#if ANSI_Cstatic intcall_readargs( struct fslte *f, char *expression, int *position )#elsestatic intcall_readargs( f, expression, position )   struct fslte *f;   char *expression;   int *position;#endif   {   int control_loop;   struct bwb_variable *v, *c;   char tbuf[ MAXSTRINGSIZE + 1 ];   int argument_counter;   int local_pos, single_var;   struct exp_ese *e;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in call_readargs(): reading arguments, buffer <%s>",      &( expression[ *position ] ) );   bwb_debug( bwb_ebuf );#endif   /* if we are at begin paren, advance */   if ( expression[ *position ] == '(' )      {      ++( *position );      }   /* loop through looking for arguments */   control_loop = TRUE;   argument_counter = 0;   while ( control_loop == TRUE )      {      adv_ws( expression, position );#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in call_readargs(): in loop, buffer <%s>",         &( expression[ *position ] ) );      bwb_debug( bwb_ebuf );#endif      switch( expression[ *position ] )         {         case '\n':		/* end of line */         case '\r':	 case '\0':#if MULTISEG_LINES	 case ':':              /* end of segment */#endif            control_loop = FALSE;            return FALSE;         case ')':		/* end of argument list */            ++( *position );            control_loop = FALSE;            return TRUE;         default:		/* presume beginning of argument */            /* read the first word to see if it is a single variable name */            single_var = FALSE;            exp_getvfname( &( expression[ *position ] ), tbuf );            local_pos = *position + strlen( tbuf );            adv_ws( expression, &local_pos );#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in call_readargs(): in loop, tbuf <%s>",               tbuf );            bwb_debug( bwb_ebuf );#endif            /* check now for the single variable name */            if ( strlen( tbuf ) == 0 )               {               single_var = FALSE;               }            else               {               switch ( expression[ local_pos ] )                  {                  case ')':		/* end of argument list */#if INTENSIVE_DEBUG		     sprintf( bwb_ebuf, "in call_readargs(): detected end of argument list" );		     bwb_debug( bwb_ebuf );#endif		     ++local_pos;       /* and fall through */                  case '\n':		/* end of line */                  case '\r':		  case '\0':#if MULTISEG_LINES		  case ':':             /* end of segment */#endif		     control_loop = FALSE;      /* and fall through */						/* added 1993-06-16 */		  case ',':             /* end of argument */		     single_var = TRUE;		     /* look for variable from previous (calling) level */		     -- CURTASK exsc;		     v = var_find( tbuf );      /* find variable there */		     ++ CURTASK exsc;		     c = var_pos( CURTASK excs[ CURTASK exsc ].local_variable,                        argument_counter );	/* find local equivalent */                     bwb_vtov( c, v );		/* assign calling value to local variable */#if INTENSIVE_DEBUG		     sprintf( bwb_ebuf, "in call_readargs(): variable name is <%s>, local name <%s>",			v->name, c->name );		     bwb_debug( bwb_ebuf );#endif		     *position = local_pos;                     break;                  default:                     single_var = FALSE;                     break;                  }               }            if ( single_var == FALSE )               {#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in call_readargs(): in loop, parse expression <%s>",                  &( expression[ *position ] ) );               bwb_debug( bwb_ebuf );#endif               e = bwb_exp( expression, FALSE, position );	/* parse */#if INTENSIVE_DEBUG	       sprintf( bwb_ebuf, "in call_readargs(): in loop, parsed expression, buffer <%s>",		  &( expression[ *position ] ) );               bwb_debug( bwb_ebuf );#endif               v = var_pos( CURTASK excs[ CURTASK exsc ].local_variable,                  argument_counter );		/* assign to variable */               bwb_etov( v, e );		/* assign value */               }            /* add the variable to the calling variable chain */            fslt_addcallvar( v );#if INTENSIVE_DEBUG            str_btoc( tbuf, var_getsval( v ));            if ( single_var == TRUE )               {               sprintf( bwb_ebuf, "in call_readargs(): added arg <%d> (single) name <%s> value <%s>",                  argument_counter, v->name, tbuf );               }            else               {               sprintf( bwb_ebuf, "in call_readargs(): added arg <%d> (expression) name <%s> value <%s>",                  argument_counter, v->name, tbuf );               }            bwb_debug( bwb_ebuf );            getchar();#endif            /* advance past comma if present */            adv_ws( expression, position );            if ( expression[ *position ] == ',' )               {               ++( *position );               }            break;         }      ++argument_counter;      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in call_readargs(): exiting function" );   bwb_debug( bwb_ebuf );#endif   return TRUE;   }/***************************************************************        FUNCTION:       fslt_findl()        DESCRIPTION:	This C function finds a line corresponding        		to a name in the FUNCTION-SUB lookup			table.***************************************************************/#if ANSI_Cstatic struct bwb_line *fslt_findl( char *buffer )#elsestatic struct bwb_line *fslt_findl( buffer )   char *buffer;#endif   {   struct fslte *r;   r = fslt_findf( buffer );   return r->line;   }/***************************************************************        FUNCTION:       fslt_findf()        DESCRIPTION:	This C function finds an fslte structure			corresponding to a name in the FUNCTION-			SUB lookup table.***************************************************************/#if ANSI_Cstatic struct fslte *fslt_findf( char *buffer )#elsestatic struct fslte *fslt_findf( buffer )   char *buffer;#endif   {   struct fslte *f;   register int c;   /* remove open-paren from string */   for ( c = 0; buffer[ c ] != '\0'; ++c )      {      if ( buffer[ c ] == '(' )         {         buffer[ c ] = '\0';         }      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in fslt_findf(): search for name <%s>", buffer );   bwb_debug( bwb_ebuf );#endif   /* run through the table */   for ( f = CURTASK fslt_start.next; f != &CURTASK fslt_end; f = f->next )      {      if ( strcmp( f->name, buffer ) == 0 )         {         return f;         }      }   /* search has failed */#if PROG_ERRORS   sprintf( bwb_ebuf, "in fslt_findf(): failed to find Function/Subroutine <%s>",      buffer );   bwb_error( bwb_ebuf );#else   bwb_error( err_lnnotfound );#endif   return NULL;   }/***************************************************************        FUNCTION:       bwb_def()        DESCRIPTION:    This C function implements the BASIC                        DEF statement. Since DEF and FUNCTION			are equivalent, it simply passes execution			to bwb_function().	SYNTAX:		DEF FNname(arg...)] = expression	NOTE:		It is not a strict requirement that the			function name should begin with "FN".***************************************************************/#if ANSI_Cstruct bwb_line *bwb_def( struct bwb_line *l )#elsestruct bwb_line *bwb_def( l )   struct bwb_line *l;#endif   {#if MULTISEG_LINES   adv_eos( l->buffer, &( l->position ));#endif   return bwb_zline( l );   }#if STRUCT_CMDS/***************************************************************        FUNCTION:       bwb_function()        DESCRIPTION:	This C function implements the BASIC			FUNCTION and DEF commands.	SYNTAX:		FUNCTION function-definition***************************************************************/#if ANSI_Cstruct bwb_line *bwb_function( struct bwb_line *l )#elsestruct bwb_line *bwb_function( l )   struct bwb_line *l;#endif   {   return bwb_def( l );   }/***************************************************************        FUNCTION:       bwb_endfnc()        DESCRIPTION:	This C function implements the BASIC			END FUNCTION 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 FUNCTION command.	SYNTAX:		END FUNCTION***************************************************************/#if ANSI_Cstruct bwb_line *bwb_endfnc( struct bwb_line *l )#elsestruct bwb_line *bwb_endfnc( l )   struct bwb_line *l;#endif   {   struct bwb_variable *local;   register int c;   /* assign local variable values to calling variables */   local = 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 ], local );      local = local->next;      }   /* decrement the EXEC stack counter */   bwb_decexec();   /* and return next from old line */   CURTASK excs[ CURTASK exsc ].line->next->position = 0;   return CURTASK excs[ CURTASK exsc ].line->next;   }/***************************************************************        FUNCTION:       bwb_call()        DESCRIPTION:	This C function implements the BASIC        		CALL subroutine command.	SYNTAX:		CALL subroutine-name***************************************************************/#if ANSI_Cstruct bwb_line *bwb_call( struct bwb_line *l )#elsestruct bwb_line *bwb_call( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   struct bwb_line *call_line;   struct fslte *f;   adv_element( l->buffer, &( l->position ), tbuf );#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_call(): call to subroutine <%s>", tbuf );   bwb_debug( bwb_ebuf );#endif   /* find the line to call */   call_line = fslt_findl( tbuf );   f = fslt_findf( tbuf );   if ( call_line == NULL )      {      return bwb_zline( l );      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_call(): found line <%s>",      call_line->buffer );   bwb_debug( bwb_ebuf );#endif   /* save the old position on the EXEC stack */   bwb_setexec( l, l->position, CURTASK excs[ CURTASK exsc ].code );   /* increment and set new EXEC stack */   bwb_incexec();   call_line->position = 0;   bwb_setexec( call_line, 0, EXEC_CALLSUB );   /* attach local variables */   CURTASK excs[ CURTASK exsc ].local_variable = f->local_variable;   /* read calling variables for this call */   call_readargs( f, l->buffer, &( l->position ) );   return call_line;   }/***************************************************************        FUNCTION:       bwb_sub()	DESCRIPTION:    This function implements the BASIC			SUB command, introducing a named			subroutine.	SYNTAX:		SUB subroutine-name			(followed by subroutine definition ending			with END SUB).***************************************************************/#if ANSI_Cstruct bwb_line *bwb_sub( struct bwb_line *l )#elsestruct bwb_line *bwb_sub( l )   struct bwb_line *l;#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ];   struct bwb_line *rline;#if MULTISEG_LINES   struct fslte *f;#endif#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_sub(): entered function at exec level <%d>",      CURTASK exsc );   bwb_debug( bwb_ebuf );#endif   /* check current exec level: if 1 then only MAIN should be executed */   if ( CURTASK exsc == 0 )      {      adv_element( l->buffer, &( l->position ), tbuf );      bwb_strtoupper( tbuf );      if ( strcmp( tbuf, "MAIN" ) == 0 )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_sub(): found MAIN function at level 0" );         bwb_debug( bwb_ebuf );#endif         bwb_incexec();         bwb_setexec( l->next, 0, EXEC_MAIN );         return bwb_zline( l );         }

⌨️ 快捷键说明

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