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

📄 bwb_elx.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************        bwb_elx.c       Parse Elements of Expressions                        for Bywater BASIC Interpreter                        Copyright (c) 1993, Ted A. Campbell                        Bywater Software                        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).                                  *//*                                                               *//* Those additionally marked with "DD" were at the suggestion of *//* Dale DePriest (daled@cadence.com).                            *//*---------------------------------------------------------------*/#include <stdio.h>#include <ctype.h>#include <math.h>#include "bwbasic.h"#include "bwb_mes.h"/***************************************************************	FUNCTION:       exp_paren()	DESCRIPTION:    This function interprets a parenthetical			expression, calling bwb_exp() (recursively)			to resolve the internal expression.***************************************************************/#if ANSI_Cintexp_paren( char *expression )#elseintexp_paren( expression )   char *expression;#endif   {   struct exp_ese *e;   int s_pos;                           /* position in build buffer */   int loop;   int paren_level;   /* find a string enclosed by parentheses */   CURTASK exps[ CURTASK expsc ].pos_adv = 1;       /* start beyond open paren */   s_pos = 0;   loop = TRUE;   paren_level = 1;   CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';   while( loop == TRUE )      {      /* check the current character */      switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )         {         case '\r':				/* these tests added v1.11 */         case '\n':         case '\0':            bwb_error( err_incomplete );            loop = FALSE;            break;         case '(':            ++paren_level;            CURTASK exps[ CURTASK expsc ].string[ s_pos ]               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];            ++s_pos;            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';            break;         case ')':            --paren_level;            if ( paren_level == 0 )               {               loop = FALSE;               }            else               {               CURTASK exps[ CURTASK expsc ].string[ s_pos ]                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];               ++s_pos;               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';               }            break;         case '\"':                             /* embedded string constant */            ++CURTASK exps[ CURTASK expsc ].pos_adv;            while ( ( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] != '\"' )               && ( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] != '\0' ) )               {               CURTASK exps[ CURTASK expsc ].string[ s_pos ]                  = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];               ++s_pos;               CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';               ++CURTASK exps[ CURTASK expsc ].pos_adv;               }            break;         default:            CURTASK exps[ CURTASK expsc ].string[ s_pos ]               = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];            ++s_pos;            CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';            break;         }      /* advance the counter */      ++CURTASK exps[ CURTASK expsc ].pos_adv;      }#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_paren() found internal string <%s>",      CURTASK exps[ CURTASK expsc ].string );   bwb_debug( bwb_ebuf );#endif   /* call bwb_exp() recursively to interpret this expression */   CURTASK exps[ CURTASK expsc ].rec_pos = 0;   e = bwb_exp( CURTASK exps[ CURTASK expsc ].string, FALSE,          &( CURTASK exps[ CURTASK expsc ].rec_pos ) );   /* assign operation and value at this level */   CURTASK exps[ CURTASK expsc ].type = e->type;   switch ( e->type )      {      case STRING:         CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;         str_btob( exp_getsval( &( CURTASK exps[ CURTASK expsc ] )), exp_getsval( e ) );         break;      default:         CURTASK exps[ CURTASK expsc ].operation = NUMBER;         CURTASK exps[ CURTASK expsc ].nval = exp_getnval( e );         break;      }   return TRUE;   }/***************************************************************        FUNCTION:   	exp_strconst()        DESCRIPTION:	This function interprets a string			constant.***************************************************************/#if ANSI_Cintexp_strconst( char *expression )#elseintexp_strconst( expression )   char *expression;#endif   {   int e_pos, s_pos;   /* assign values to structure */   CURTASK exps[ CURTASK expsc ].type = STRING;   CURTASK exps[ CURTASK expsc ].operation = CONST_STRING;   /* set counters */   s_pos = 0;   CURTASK exps[ CURTASK expsc ].pos_adv = e_pos = 1;   CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';   /* read the string up until the next double quotation mark */   /* While yer at it, check for a null terminator too (JBV, found by DD) */   while(( expression[ e_pos ] != '\"') && ( expression[ e_pos ] != '\0' ))      {      CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ e_pos ];      ++e_pos;      ++s_pos;      ++CURTASK exps[ CURTASK expsc ].pos_adv;      CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';      if ( s_pos >= ( MAXSTRINGSIZE - 1 ) )         {#if PROG_ERRORS         sprintf( bwb_ebuf, "string <%s> exceeds maximum size (%d) for string constant.",            expression, MAXSTRINGSIZE );         bwb_error( bwb_ebuf );#else         bwb_error( err_overflow );#endif         return OP_NULL;         }      }   /* now write string over to bstring */   str_ctob( &( CURTASK exps[ CURTASK expsc ].sval ), CURTASK exps[ CURTASK expsc ].string );   /* advance past last double quotation mark */   /*-------------------------------------------------------------*/   /* Of course, it doesn't hurt to make sure it's really a quote */   /* (JBV, found by DD)                                          */   /*-------------------------------------------------------------*/   if ( expression[ e_pos ] == '\"' ) ++CURTASK exps[ CURTASK expsc ].pos_adv;   /* return */   return TRUE;   }/***************************************************************        FUNCTION:	exp_numconst()        DESCRIPTION:	This function interprets a numerical			constant.***************************************************************/#if ANSI_Cintexp_numconst( char *expression )#elseintexp_numconst( expression )   char *expression;#endif   {   int base;                            /* numerical base for the constant */   static struct bwb_variable mantissa; /* mantissa of floating-point number */   static int init = FALSE;		/* is mantissa variable initialized? */   int exponent;                        /* exponent for floating point number */   int man_start;                       /* starting point of mantissa */   int s_pos;                           /* position in build string */   int build_loop;   int need_pm;   int i;   bnumber d;#if CHECK_RECURSION   static int in_use = FALSE;                   /* boolean: is function in use? */   /* check recursion status */   if ( in_use == TRUE )      {      sprintf( bwb_ebuf, "Recursion error in bwb_exp.c:exp_findop(): recursion violation." );      bwb_error( bwb_ebuf );      }   /* reset recursion status indicator */   else      {      in_use = TRUE;      }#endif   /* initialize the variable if necessary */#if INTENSIVE_DEBUG   strcpy( mantissa.name, "(mantissa)" );#endif   if ( init == FALSE )      {      init = TRUE;      var_make( &mantissa, NUMBER );      }   /* be sure that the array_pos[ 0 ] for mantissa is set to dim_base;      this is necessary because mantissa might be used before dim_base      is set */   mantissa.array_pos[ 0 ] = dim_base;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_numconst(): received <%s>, eval <%c>",      expression, expression[ 0 ] );   bwb_debug( bwb_ebuf );#endif   need_pm = FALSE;   CURTASK exps[ CURTASK expsc ].nval = (bnumber) 0;   /* check the first character(s) to determine numerical base      and starting point of the mantissa */   switch( expression[ 0 ] )      {      case '-':      case '+':      case '0':      case '1':      case '2':      case '3':      case '4':      case '5':      case '6':      case '7':      case '8':      case '9':      case '.':         base = 10;                     /* decimal constant */	 man_start = 0;                 /* starts at position 0 */	 need_pm = FALSE;         break;      case '&':                         /* hex or octal constant */         if ( ( expression[ 1 ] == 'H' ) || ( expression[ 1 ] == 'h' ))            {            base = 16;                  /* hexadecimal constant */            man_start = 2;              /* starts at position 2 */            }         else            {            base = 8;                   /* octal constant */            if ( ( expression[ 1 ] == 'O' ) || ( expression[ 1 ] == 'o' ))               {               man_start = 2;           /* starts at position 2 */               }            else               {               man_start = 1;           /* starts at position 1 */               }            }         break;      default:#if PROG_ERRORS         sprintf( bwb_ebuf, "expression <%s> is not a numerical constant.",            expression );         bwb_error( bwb_ebuf );#else         bwb_error( err_syntax );#endif         return OP_NULL;      }   /* now build the mantissa according to the numerical base */   switch( base )      {      case 10:                          /* decimal constant */         /* initialize counters */         CURTASK exps[ CURTASK expsc ].pos_adv = man_start;         CURTASK exps[ CURTASK expsc ].type = NUMBER;         CURTASK exps[ CURTASK expsc ].string[ 0 ] = '\0';         s_pos = 0;         exponent = OP_NULL;         build_loop = TRUE;         /* loop to build the string */         while ( build_loop == TRUE )            {            switch( expression[ CURTASK exps[ CURTASK expsc ].pos_adv ] )               {               case '-':                        /* prefixed plus or minus */               case '+':                  /* in the first position, a plus or minus sign can                     be added to the beginning of the string to be                     scanned */                  if ( CURTASK exps[ CURTASK expsc ].pos_adv == man_start )                     {                     CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ];                     ++CURTASK exps[ CURTASK expsc ].pos_adv;  /* advance to next character */                     ++s_pos;                     CURTASK exps[ CURTASK expsc ].string[ s_pos ] = '\0';                     }                  /* but in any other position, the plus or minus sign                     must be taken as an operator and thus as terminating                     the string to be scanned */

⌨️ 快捷键说明

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