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

📄 bwb_ops.c

📁 这是一个简易的basic语言解释器, 可供我们学习和改进.
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************        bwb_ops.c       Expression Parsing Operations                        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).                                  *//*---------------------------------------------------------------*/#include <stdio.h>#include <ctype.h>#include <math.h>#include "bwbasic.h"#include "bwb_mes.h"/* declarations for functions visible in this file only */#if ANSI_Cstatic int op_oplevel( int level );static int op_add( int level, int precision );static int op_subtract( int level, int precision );static int op_multiply( int level, int precision );static int op_divide( int level, int precision );static int op_assign( int level, int precision );static int op_equals( int level, int precision );static int op_lessthan( int level, int precision );static int op_greaterthan( int level, int precision );static int op_lteq( int level, int precision );static int op_gteq( int level, int precision );static int op_notequal( int level, int precision );static int op_modulus( int level, int precision );static int op_exponent( int level, int precision );static int op_intdiv( int level, int precision );static int op_or( int level, int precision );static int op_and( int level, int precision );static int op_not( int level, int precision );static int op_xor( int level, int precision );static int op_negation( int level, int precision ); /* JBV */static int op_islevelstr( int level );static int op_getprecision( int level );static int op_isoperator( int operation );static int op_pulldown( int how_far );#elsestatic int op_oplevel();static int op_add();static int op_subtract();static int op_multiply();static int op_divide();static int op_assign();static int op_equals();static int op_lessthan();static int op_greaterthan();static int op_lteq();static int op_gteq();static int op_notequal();static int op_modulus();static int op_exponent();static int op_intdiv();static int op_or();static int op_and();static int op_not();static int op_xor();static int op_negation(); /* JBV */static int op_islevelstr();static int op_getprecision();static int op_isoperator();static int op_pulldown();#endif				/* ANSI_C for prototypes */static int op_level;/***************************************************************	FUNCTION:       exp_operation()	DESCRIPTION:    This function performs whatever operations			are necessary at the end of function bwb_exp()			(i.e., the end of the parsing of an expression;			see file bwb_exp.c).***************************************************************/#if ANSI_Cintexp_operation( int entry_level )#elseintexp_operation( entry_level )   int entry_level;#endif   {   register int precedence;   int operator;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in exp_operation(): entered function." );   bwb_debug( bwb_ebuf );#endif   /* cycle through all levels of precedence and perform required      operations */   for ( precedence = 0; precedence <= MAX_PRECEDENCE; ++precedence )      {      /* Operation loop: cycle through every level above entry level         and perform required operations as needed */      op_level = entry_level + 1;      while( ( op_level < CURTASK expsc )         && ( op_isoperator( CURTASK exps[ op_level ].operation ) == FALSE ))         {         ++op_level;         }      while ( ( op_level > entry_level ) && ( op_level < CURTASK expsc ) )         {         /* see if the operation at this level is an operator with the            appropriate precedence level by running through the table            of operators */         for ( operator = 0; operator < N_OPERATORS; ++operator )            {            if ( exp_ops[ operator ].operation == CURTASK exps[ op_level ].operation )               {               /* check for appropriate level of precedence */               if ( exp_ops[ operator ].precedence == precedence )                  {#if INTENSIVE_DEBUG                  sprintf( bwb_ebuf, "in exp_operation(): level <%d> operation <%d>",                     op_level, CURTASK exps[ op_level ].operation );                  bwb_debug( bwb_ebuf );#endif                  op_oplevel( op_level );     /* perform the operation */                  }               }            }         /* advance level if appropriate; one must check, however, since            the op_oplevel() function may have decremented CURTASK expsc */         if ( op_level < CURTASK expsc )            {            ++op_level;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in exp_operation() first increment op_level to <%d>",               op_level );            bwb_debug( bwb_ebuf );#endif            while ( ( op_isoperator( CURTASK exps [ op_level ].operation ) == FALSE )               && ( op_level < CURTASK expsc ) )               {               ++op_level;#if INTENSIVE_DEBUG               sprintf( bwb_ebuf, "in exp_operation() further increment op_level to <%d>",                  op_level );               bwb_debug( bwb_ebuf );#endif               }            }                           /* end of increment of op_level */         }                              /* end of for loop for stack levels */      }                                 /* end of for loop for precedence levels */   return TRUE;   }                                    /* end of function exp_operation() *//***************************************************************	FUNCTION:       op_oplevel()	DESCRIPTION:    This function performs a specific operation			at a specific level as the expression parser			resolves its arguments.***************************************************************/#if ANSI_Cstatic intop_oplevel( int level )#elsestatic intop_oplevel( level )   int level;#endif   {   int precision;   /* set the precision */   if ( ( precision = op_getprecision( level ) ) == OP_ERROR )      {#if PROG_ERRORS      sprintf( bwb_ebuf, "exp_operation(): failed to set precision." );      bwb_error( bwb_ebuf );#else      bwb_error( err_mismatch );			/*** ??? ***/#endif      op_pulldown( 2 );      }   /* precision is set correctly */   else      {#if INTENSIVE_DEBUG      sprintf( bwb_ebuf, "in op_oplevel(): level <%d>, precision <%c>",         level, precision );      bwb_debug( bwb_ebuf );#endif      switch ( CURTASK exps[ level ].operation )         {         case OP_ADD:            op_add( level, precision );            break;         case OP_SUBTRACT:            op_subtract( level, precision );            break;         case OP_MULTIPLY:            op_multiply( level, precision );            break;         case OP_DIVIDE:            op_divide( level, precision );            break;         case OP_ASSIGN:            op_assign( level, precision );            break;         case OP_EQUALS:            op_equals( level, precision );            break;         case OP_LESSTHAN:            op_lessthan( level, precision );            break;         case OP_GREATERTHAN:            op_greaterthan( level, precision );            break;         case OP_LTEQ:            op_lteq( level, precision );            break;         case OP_GTEQ:            op_gteq( level, precision );            break;         case OP_NOTEQUAL:            op_notequal( level, precision );            break;         case OP_MODULUS:            op_modulus( level, precision );            break;         case OP_INTDIVISION:            op_intdiv( level, precision );            break;         case OP_OR:            op_or( level, precision );            break;         case OP_AND:            op_and( level, precision );            break;         case OP_NOT:            op_not( level, precision );            break;         case OP_XOR:            op_xor( level, precision );            break;         case OP_EXPONENT:            op_exponent( level, precision );            break;         case OP_NEGATION: /* JBV */            op_negation( level, precision );            break;         default:#if PROG_ERRORS            sprintf( bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported.", CURTASK exps[ level ].operation );            op_pulldown( 2 );            bwb_error( bwb_ebuf );#else            bwb_error( err_syntax );#endif            break;         }                              /* end of case statement for operators */      }                                 /* end of else statement, precision set */   return TRUE;   }                                    /* end of function op_oplevel() *//***************************************************************	FUNCTION:       op_isoperator()	DESCRIPTION:    This function detects whether its argument			is an operator.***************************************************************/#if ANSI_Cstatic intop_isoperator( int operation )#elsestatic intop_isoperator( operation )   int operation;#endif   {   register int c;   for( c = 0; c < N_OPERATORS; ++c )      {      if ( operation == exp_ops[ c ].operation )         {#if INTENSIVE_DEBUG         sprintf( bwb_ebuf, "in op_isoperator(): found match <%s>",            exp_ops[ c ].symbol );         bwb_debug( bwb_ebuf );#endif         return TRUE;         }      }   /* test failed; return FALSE */#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in op_isoperator(): no match found for operation <%d>",      operation );   bwb_debug( bwb_ebuf );#endif   return FALSE;   }/***************************************************************        FUNCTION:   	op_add()        DESCRIPTION:  	This function adds two numbers or        		concatenates two strings.***************************************************************/#if ANSI_Cstatic intop_add( int level, int precision )#elsestatic intop_add( level, precision )   int level;   int precision;#endif   {   int error_condition;   static bstring b; /* JBV */   error_condition = FALSE;   b.rab = FALSE; /* JBV */   switch( precision )      {      case STRING:         /* both sides of the operation should be strings for            string addition; if not, report an error */         if (  ( op_islevelstr( level - 1 ) != TRUE )            || ( op_islevelstr( level + 1 ) != TRUE ) )            {#if PROG_ERRORS            sprintf( bwb_ebuf, "in op_add(): Type mismatch in string addition." );            bwb_error( bwb_ebuf );#else            bwb_error( err_mismatch );#endif            error_condition = TRUE;            }         /* concatenate the two strings */         if ( error_condition == FALSE )            {#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",               level - 1, CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );            bwb_debug( bwb_ebuf );            exp_getsval( &( CURTASK exps[ level - 1 ] ));            sprintf( bwb_ebuf, "in op_add(): try exp_getsval(), level <%d> op <%d> type <%c>:",               level + 1, CURTASK exps[ level + 1 ].operation, CURTASK exps[ level + 1 ].type );            bwb_debug( bwb_ebuf );            exp_getsval( &( CURTASK exps[ level + 1 ] ));            sprintf( bwb_ebuf, "in op_add(): string addition, exp_getsval()s completed" );            bwb_debug( bwb_ebuf );#endif            /* Removed by JBV (incomplete, modifies wrong string variable!) */            /* str_cat( exp_getsval( &( CURTASK exps[ level - 1 ] ) ),                exp_getsval( &( CURTASK exps[ level + 1 ] ) ) ); */            /* Added by JBV */            str_btob( &b, exp_getsval( &( CURTASK exps[ level - 1 ] ) ) );            str_cat( &b, exp_getsval( &( CURTASK exps[ level + 1 ] ) ) );            str_btob( &( CURTASK exps[ level - 1 ].sval ), &b );            CURTASK exps[ level - 1 ].operation = CONST_STRING;#if INTENSIVE_DEBUG            sprintf( bwb_ebuf, "in op_add(): str_cat() returns <%d>-byte string to level <%d>",               exp_getsval( &( CURTASK exps[ level - 1 ] ) )->length, level - 1 );            bwb_debug( bwb_ebuf );#endif            }         break;      case NUMBER:         CURTASK exps[ level - 1 ].nval            = exp_getnval( &( CURTASK exps[ level - 1 ] ))            + exp_getnval( &( CURTASK exps[ level + 1 ] ));         CURTASK exps[ level - 1 ].operation = NUMBER;         break;      }   /* set variable to requested precision */   CURTASK exps[ level - 1 ].type = (char) precision;#if INTENSIVE_DEBUG   sprintf( bwb_ebuf, "in op_add() returns with operation <%d> type <%c>",      CURTASK exps[ level - 1 ].operation, CURTASK exps[ level - 1 ].type );   bwb_debug( bwb_ebuf );#endif   /* decrement the stack twice */   op_pulldown( 2 );   return TRUE;   }/***************************************************************	FUNCTION:       op_subtract()	DESCRIPTION:    This function subtracts the number on			the left from the number on the right.***************************************************************/#if ANSI_Cstatic intop_subtract( int level, int precision )#else

⌨️ 快捷键说明

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