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

📄 bwbasic.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************        bwbasic.c       Main Program File                        for Bywater BASIC Interpreter                        Copyright (c) 1993, Ted A. Campbell                        Bywater Software			"I was no programmer, neither was I a			programmer's son; but I was an herdman			and a gatherer of sycomore fruit."			     - Amos 7:14b AV, slightly adapted                        email: tcamp@delphi.com        Copyright and Permissions Information:        All U.S. and international rights are claimed by the author,        Ted A. Campbell.	This software is released under the terms of the GNU General	Public License (GPL), which is distributed with this software	in the file "COPYING".  The GPL specifies the terms under	which users may copy and use the software in this distribution.	A separate license is available for commercial distribution,	for information on which you should contact the author.***************************************************************//*---------------------------------------------------------------*//* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, *//* 11/1995 (eidetics@cerf.net).                                  *//*---------------------------------------------------------------*/#include <stdio.h>#include <ctype.h>#include <math.h>#include "bwbasic.h"#include "bwb_mes.h"#if HAVE_SIGNAL#include <signal.h>#endif#if HAVE_LONGJUMP#include <setjmp.h>#endifchar *bwb_ebuf;				/* error buffer */static char *read_line;int bwb_trace = FALSE;FILE *errfdevice = stderr;              /* output device for error messages */#if HAVE_LONGJUMPjmp_buf mark;#endifstatic int program_run = 0;		/* has the command-line program been run? */int bwb_curtask = 0;			/* current task */struct bwb_variable *ed;                /* BWB.EDITOR$ variable */struct bwb_variable *fi;                /* BWB.FILES$ variable */struct bwb_variable *pr;                /* BWB.PROMPT$ variable */struct bwb_variable *im;                /* BWB.IMPLEMENTATION$ variable */struct bwb_variable *co;                /* BWB.COLORS variable */#if PARACTstruct bwb_task *bwb_tasks[ TASKS ];	/* table of task pointers */#elsechar progfile[ MAXARGSIZE ];		/* program file */int rescan = TRUE;                      /* program needs to be rescanned */int number = 0;				/* current line number */struct bwb_line *bwb_l;			/* current line pointer */struct bwb_line bwb_start;		/* starting line marker */struct bwb_line bwb_end;		/* ending line marker */struct bwb_line *data_line;     	/* current line to read data */int data_pos = 0;                       /* position in data_line */struct bwb_variable var_start;		/* variable list start marker */struct bwb_variable var_end;		/* variable list end marker */struct bwb_function fnc_start;		/* function list start marker */struct bwb_function fnc_end;		/* function list end marker */struct fslte fslt_start;		/* function-sub-label lookup table start marker */struct fslte fslt_end;			/* function-sub-label lookup table end marker */int exsc = -1;				/* EXEC stack counter */int expsc = 0;				/* expression stack counter */int xtxtsc = 0;				/* eXecute TeXT stack counter */struct exse *excs;			/* EXEC stack */struct exp_ese *exps;			/* Expression stack */struct xtxtsl *xtxts;                   /* Execute Text stack */#endif/* Prototypes for functions visible only to this file */#if ANSI_Cextern int is_ln( char *buffer );#elseextern int is_ln();#endif/***************************************************************        FUNCTION:       bwb_init()        DESCRIPTION:    This function initializes bwBASIC.***************************************************************/void#if ANSI_Cbwb_init( int argc, char **argv )#elsebwb_init( argc, argv )   int argc;   char **argv;#endif   {   static FILE *input = NULL;   register int n;#if PROFILE   struct bwb_variable *v;#endif#if REDIRECT_STDERR   FILE *newerr;#endif#if PROFILE   FILE *profile;#endif#if PARACT#else   static char start_buf[] = "\0";   static char end_buf[] = "\0";#endif#if INTENSIVE_DEBUG   prn_xprintf( stderr, "Memory Allocation Statistics:\n" );   prn_xprintf( stderr, "----------------------------\n" );#if PARACT   sprintf( bwb_ebuf, "task structure:   %ld bytes\n",      (long) sizeof( struct bwb_task ) );   prn_xprintf( stderr, bwb_ebuf );   getchar();#endif#endif   /* set all task pointers to NULL */#if PARACT   for ( n = 0; n < TASKS; ++n )      {      bwb_tasks[ n ] = NULL;      }#else   /* Memory allocation */   /* eXecute TeXT stack */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( xtxts = CALLOC( XTXTSTACKSIZE, sizeof( struct xtxtsl ), "bwb_init") ) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_init(): failed to find memory for xtxts" );#else      bwb_error( err_getmem );#endif      }   /* expression stack */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( exps = CALLOC( ESTACKSIZE, sizeof( struct exp_ese ), "bwb_init") ) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_init(): failed to find memory for exps" );#else      bwb_error( err_getmem );#endif      }   /* EXEC stack */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( excs = CALLOC( EXECLEVELS, sizeof( struct exse ), "bwb_init") ) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_init(): failed to find memory for excs" );#else      bwb_error( err_getmem );#endif      }   /* initialize tables of variables, functions */   bwb_start.number = 0;   bwb_start.next = &bwb_end;   bwb_end.number = MAXLINENO + 1;   bwb_end.next = &bwb_end;   bwb_start.buffer = start_buf;   bwb_end.buffer = end_buf;   data_line = &bwb_start;   data_pos = 0;   exsc = -1;   expsc = 0;   xtxtsc = 0;   bwb_start.position = 0;   bwb_l = &bwb_start;    var_init( 0 );   fnc_init( 0 );   fslt_init( 0 );#endif   /* character buffers */   /* Revised to CALLOC pass-thru call by JBV */   if ( ( bwb_ebuf = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_init") ) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_init(): failed to find memory for bwb_ebuf" );#else      bwb_error( err_getmem );#endif      }   /* Revised to CALLOC pass-thru call by JBV */   if ( ( read_line = CALLOC( MAXREADLINESIZE + 1, sizeof(char), "bwb_init") ) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_init(): failed to find memory for read_line" );#else      bwb_error( err_getmem );#endif      }#if PARACT   /* request task 0 as current (base) task */   bwb_curtask = bwb_newtask( 0 );   if ( bwb_curtask == -1 )      {      return;				/* error message has already been called*/      }#endif#if TEST_BSTRING   for ( n = 0; n < ESTACKSIZE; ++n )      {      sprintf( CURTASK exps[ n ].sval.name, "<Exp stack bstring %d>", n );      }#endif   /* assign memory for the device table */#if COMMON_CMDS   /* Revised to CALLOC pass-thru call by JBV */   if ( ( dev_table = CALLOC( DEF_DEVICES, sizeof( struct dev_element ), "bwb_init") ) == NULL )      {#if PROG_ERRORS      bwb_error( "in bwb_init(): failed to find memory for dev_table" );#else      bwb_error( err_getmem );#endif      bwx_terminate();      }   /* initialize all devices to DEVMODE_AVAILABLE */   for ( n = 0; n < DEF_DEVICES; ++n )      {      dev_table[ n ].mode = DEVMODE_AVAILABLE;      dev_table[ n ].reclen = -1;      dev_table[ n ].cfp = NULL;      dev_table[ n ].buffer = NULL;      dev_table[ n ].width = DEF_WIDTH;      dev_table[ n ].col = 1;      }#endif			/* COMMON_CMDS */   /* initialize preset variables */   ed = var_find( DEFVNAME_EDITOR );   ed->preset = TRUE;   ed->common = TRUE;   str_ctob( var_findsval( ed, ed->array_pos ), DEF_EDITOR );   fi = var_find( DEFVNAME_FILES );   fi->preset = TRUE;   fi->common = TRUE;   str_ctob( var_findsval( fi, fi->array_pos ), DEF_FILES );   pr = var_find( DEFVNAME_PROMPT );   pr->preset = TRUE;   pr->common = TRUE;   str_ctob( var_findsval( pr, pr->array_pos ), PROMPT );   im = var_find( DEFVNAME_IMPL );   im->preset = TRUE;   im->common = TRUE;   str_ctob( var_findsval( im, im->array_pos ), IMP_IDSTRING );   co = var_find( DEFVNAME_COLORS );   co->preset = TRUE;   co->common = TRUE;   * var_findnval( co, co->array_pos ) = (bnumber) DEF_COLORS;   /* Signon message */   bwx_signon();   /* Redirect stderr if specified */#if REDIRECT_STDERR   newerr = freopen( ERRFILE, "w", stderr );   if ( newerr == NULL )      {      sprintf( bwb_ebuf, "Failed to redirect error messages to file <%s>\n",         ERRFILE );      errfdevice = stdout;      prn_xprintf( errfdevice, bwb_ebuf );      }   else      {      sprintf( bwb_ebuf, "NOTE: Error messages are redirected to file <%s>\n",         ERRFILE );      prn_xprintf( errfdevice, bwb_ebuf );      errfdevice = stderr;      }#else   errfdevice = stdout;#endif   /* if there is a profile.bas, execute it */#if PROFILE   if ( ( profile = fopen( PROFILENAME, "r" )) != NULL )      {      bwb_fload( profile );	/* load profile */      bwb_run( &CURTASK bwb_start );	/* run profile */      /* profile must be run immediately, not by scheduler */      while ( CURTASK exsc > -1 )           {           bwb_execline();           }      /* mark all profiled variables as preset */      for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in bwb_init(): marked variable <%s> preset TRUE",            v->name );         bwb_debug( bwb_ebuf );#endif         v->preset = TRUE;         }      bwb_new( &CURTASK bwb_start ); 	/* remove profile from memory */      }#endif#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in main(): Ready to save jump MARKER" );   bwb_debug( bwb_ebuf );#endif   /* set a buffer for jump: program execution returns to this point      in case of a jump (error, interrupt, or finish program) */#if INTERACTIVE#if HAVE_SIGNAL   signal( SIGINT, break_mes );#endif#if HAVE_LONGJUMP   setjmp( mark );#endif#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_init(): Return from jump MARKER, program run <%d>",      program_run + 1 );   bwb_debug( bwb_ebuf );   getchar();#endif   /* if INTERACTIVE is FALSE, then we must have a program file */#else   if ( argc < 2 )      {      bwb_error( err_noprogfile );      }#endif				/* INTERACTIVE */   /* check to see if there is a program file: but do this only the first      time around! */   ++program_run;   if (( argc > 1 ) && ( program_run == 1 ))      {      strcpy( CURTASK progfile, argv[ 1 ] ); /* JBV */      if ( ( input = fopen( CURTASK progfile, "r" )) == NULL ) /* JBV */         {         strcat( CURTASK progfile, ".bas" );         if ( ( input = fopen( CURTASK progfile, "r" )) == NULL )            {            CURTASK progfile[ 0 ] = 0;            sprintf( bwb_ebuf, err_openfile, argv[ 1 ] );            bwb_error( bwb_ebuf );            }         }      if ( input != NULL )         {         /* strcpy( CURTASK progfile, argv[ 1 ] ); */  /* Removed by JBV */#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in main(): progfile is <%s>.", CURTASK progfile );         bwb_debug( bwb_ebuf );#endif         bwb_fload( input );         bwb_run( &CURTASK bwb_start );         }      }   }/***************************************************************        FUNCTION:       bwb_interact()        DESCRIPTION: 	This function gets a line from the user			and processes it.***************************************************************/#if INTERACTIVEint#if ANSI_Cbwb_interact( void )#elsebwb_interact()#endif   {   char tbuf[ MAXSTRINGSIZE + 1 ]; /* JBV */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in bwb_interact(): ready to read from keyboard" );   bwb_debug( bwb_ebuf );#endif   /* take input from keyboard */   bwb_gets( read_line );   bwb_stripcr( read_line ); /* JBV */   /* If there is no line number, execute the line as received */   if ( is_ln( read_line ) == FALSE )      {      bwb_xtxtline( read_line );      }   /*-----------------------------------------------------------------*/   /* Another possibility: if read_line is a numeric constant, delete */   /* the indicated line number (JBV)                                 */   /*-----------------------------------------------------------------*/   else if ( is_numconst( read_line ) == TRUE )   {       strcpy(tbuf, read_line);       sprintf(read_line, "delete %s\0", tbuf);       bwb_xtxtline( read_line );   }   /* If there is a line number, add the line to the file in memory */   else      {      bwb_ladd( read_line, TRUE );#if INTENSIVE_DEBUG      bwb_debug( "Return from bwb_ladd()" );#endif      }   return TRUE;   }#endif				/* INTERACTIVE == TRUE *//***************************************************************        FUNCTION:       bwb_fload()        DESCRIPTION: 	This function loads a BASIC program			file into memory given a FILE pointer.***************************************************************/int#if ANSI_Cbwb_fload( FILE *file )#else

⌨️ 快捷键说明

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