|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035 |
- /****************************************************************
-
- 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_C
- static 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 );
- #else
- static 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_C
- int
- exp_operation( int entry_level )
- #else
- int
- exp_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_C
- static int
- op_oplevel( int level )
- #else
- static int
- op_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_C
- static int
- op_isoperator( int operation )
- #else
- static int
- op_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_C
- static int
- op_add( int level, int precision )
- #else
- static int
- op_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_C
- static int
- op_subtract( int level, int precision )
- #else
- static int
- op_subtract( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- string addition; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be subtracted." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- CURTASK exps[ level - 1 ].nval
- = exp_getnval( &( CURTASK exps[ level - 1 ] ))
- - exp_getnval( &( CURTASK exps[ level + 1 ] ));
- break;
-
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = (char) precision;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_multiply()
-
- DESCRIPTION: This function multiplies the number on
- the left by the number on the right.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_multiply( int level, int precision )
- #else
- static int
- op_multiply( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- string addition; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be multiplied." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- CURTASK exps[ level - 1 ].nval
- = exp_getnval( &( CURTASK exps[ level - 1 ] ))
- * exp_getnval( &( CURTASK exps[ level + 1 ] ));
- break;
-
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = (char) precision;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_divide()
-
- DESCRIPTION: This function divides the number on
- the left by the number on the right.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_divide( int level, int precision )
- #else
- static int
- op_divide( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- division; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be divided." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
- == (bnumber) 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) -1.0;
- op_pulldown( 2 );
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Divide by 0." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dbz );
- #endif
- return FALSE;
- }
- CURTASK exps[ level - 1 ].nval
- = exp_getnval( &( CURTASK exps[ level - 1 ] ))
- / exp_getnval( &( CURTASK exps[ level + 1 ] ));
- break;
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = (char) precision;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_assign()
-
- DESCRIPTION: This function assigns the value in the
- right hand side to the variable in the
- left hand side.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_assign( int level, int precision )
- #else
- static int
- op_assign( level, precision )
- int level;
- int precision;
- #endif
- {
-
- /* Make sure the position one level below is a variable */
-
- if ( CURTASK exps[ level - 1 ].operation != VARIABLE )
- {
- op_pulldown( 2 );
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "in op_assign(): Assignment must be to variable: level -1 <%d> op <%d>",
- level - 1, CURTASK exps[ level - 1 ].operation );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_syntax );
- #endif
- return FALSE;
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_assign(): entered function level <%d>",
- level );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* if the assignment is numerical, then the precision should be set
- to that of the variable on the left-hand side of the assignment */
-
- if ( precision != STRING )
- {
- precision = (int) CURTASK exps[ level - 1 ].type;
- }
-
- switch( precision )
- {
- case STRING:
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_assign(): 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_assign(): 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_assign(): string addition, exp_getsval()s completed" );
- bwb_debug( bwb_ebuf );
- #endif
-
- str_btob( exp_getsval( &( CURTASK exps[ level - 1 ] )),
- exp_getsval( &( CURTASK exps[ level + 1 ] )) );
- break;
-
- case NUMBER:
- * var_findnval( CURTASK exps[ level - 1 ].xvar,
- CURTASK exps[ level - 1 ].array_pos ) =
- CURTASK exps[ level - 1 ].nval =
- exp_getnval( &( CURTASK exps[ level + 1 ] ) );
- break;
-
- default:
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "in op_assign(): Variable before assignment operator has unidentified type." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- return FALSE;
-
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = (char) precision;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_equals()
-
- DESCRIPTION: This function compares two values and
- returns an integer value: TRUE if they are
- the same and FALSE if they are not.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_equals( int level, int precision )
- #else
- static int
- op_equals( level, precision )
- int level;
- int precision;
- #endif
- {
- int error_condition;
- static bstring b;
- bstring *bp;
-
- error_condition = FALSE;
- b.rab = FALSE;
-
- 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_equals(): Type mismatch in string comparison." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- error_condition = TRUE;
- }
-
- /* compare the two strings */
-
- if ( error_condition == FALSE )
- {
- bp = exp_getsval( &( CURTASK exps[ level - 1 ] ));
- #if OLDWAY
- b.length = bp->length;
- b.sbuffer = bp->sbuffer;
- #endif
- str_btob( &b, bp );
-
- if ( str_cmp( &b,
- exp_getsval( &( CURTASK exps[ level + 1 ] )) ) == 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- }
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
- == exp_getnval( &( CURTASK exps[ level + 1 ] )) )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- break;
-
- }
-
- /* set variable to integer and operation to NUMBER:
- this must be done at the end, since at the beginning it
- might cause op_islevelstr() to return a false error */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_lessthan()
-
- DESCRIPTION: This function compares two values and
- returns an integer value: TRUE if the
- left hand value is less than the right,
- and FALSE if it is not.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_lessthan( int level, int precision )
- #else
- static int
- op_lessthan( level, precision )
- int level;
- int precision;
- #endif
- {
- int error_condition;
-
- error_condition = FALSE;
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers 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, "Type mismatch in string comparison." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- error_condition = TRUE;
- }
-
- /* compare the two strings */
-
- if ( error_condition == FALSE )
- {
- if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
- exp_getsval( &( CURTASK exps[ level + 1 ] )) ) < 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- }
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
- < exp_getnval( &( CURTASK exps[ level + 1 ] )) )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- break;
-
- }
-
- /* set variable to integer and operation to NUMBER:
- this must be done at the end, since at the beginning it
- might cause op_islevelstr() to return a false error */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_greaterthan()
-
- DESCRIPTION: This function compares two values and
- returns an integer value: TRUE if the
- left hand value is greater than the right,
- and FALSE if it is not.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_greaterthan( int level, int precision )
- #else
- static int
- op_greaterthan( level, precision )
- int level;
- int precision;
- #endif
- {
- int error_condition;
-
- error_condition = FALSE;
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers 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, "Type mismatch in string comparison." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- error_condition = TRUE;
- }
-
- /* compare the two strings */
-
- if ( error_condition == FALSE )
- {
- if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
- exp_getsval( &( CURTASK exps[ level + 1 ] )) ) > 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- }
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
- > exp_getnval( &( CURTASK exps[ level + 1 ] )) )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- break;
-
- }
-
- /* set variable to integer and operation to NUMBER:
- this must be done at the end, since at the beginning it
- might cause op_islevelstr() to return a false error */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_lteq()
-
- DESCRIPTION: This function compares two values and
- returns an integer value: TRUE if the
- left hand value is less than or equal
- to the right, and FALSE if it is not.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_lteq( int level, int precision )
- #else
- static int
- op_lteq( level, precision )
- int level;
- int precision;
- #endif
- {
- int error_condition;
-
- error_condition = FALSE;
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers 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, "Type mismatch in string comparison." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- error_condition = TRUE;
- }
-
- /* compare the two strings */
-
- if ( error_condition == FALSE )
- {
- if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
- exp_getsval( &( CURTASK exps[ level + 1 ] )) ) <= 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- }
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
- <= exp_getnval( &( CURTASK exps[ level + 1 ] )) )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- break;
-
- }
-
- /* set variable to integer and operation to NUMBER:
- this must be done at the end, since at the beginning it
- might cause op_islevelstr() to return a false error */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_gteq()
-
- DESCRIPTION: This function compares two values and
- returns an integer value: TRUE if the
- left hand value is greater than or equal
- to the right, and FALSE if it is not.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_gteq( int level, int precision )
- #else
- static int
- op_gteq( level, precision )
- int level;
- int precision;
- #endif
- {
- int error_condition;
-
- error_condition = FALSE;
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers 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, "Type mismatch in string comparison." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- error_condition = TRUE;
- }
-
- /* compare the two strings */
-
- if ( error_condition == FALSE )
- {
- if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
- exp_getsval( &( CURTASK exps[ level + 1 ] )) ) >= 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- }
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
- >= exp_getnval( &( CURTASK exps[ level + 1 ] )) )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- break;
-
- }
-
- /* set variable to integer and operation to NUMBER:
- this must be done at the end, since at the beginning it
- might cause op_islevelstr() to return a false error */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_notequal()
-
- DESCRIPTION: This function compares two values and
- returns an integer value: TRUE if they
- are not the same and FALSE if they are.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_notequal( int level, int precision )
- #else
- static int
- op_notequal( level, precision )
- int level;
- int precision;
- #endif
- {
- int error_condition;
-
- error_condition = FALSE;
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers 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, "Type mismatch in string comparison." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
- error_condition = TRUE;
- }
-
- /* compare the two strings */
-
- if ( error_condition == FALSE )
-
- {
- if ( str_cmp( exp_getsval( &( CURTASK exps[ level - 1 ] )),
- exp_getsval( &( CURTASK exps[ level + 1 ] )) ) != 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- }
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level - 1 ] ))
- != exp_getnval( &( CURTASK exps[ level + 1 ] )) )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) TRUE;
- }
- else
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) FALSE;
- }
- break;
-
- }
-
- /* set variable to integer and operation to NUMBER:
- this must be done at the end, since at the beginning it
- might cause op_islevelstr() to return a false error */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_modulus()
-
- DESCRIPTION: This function divides the number on
- the left by the number on the right
- and returns the remainder.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_modulus( int level, int precision )
- #else
- static int
- op_modulus( level, precision )
- int level;
- int precision;
- #endif
- {
- static double iportion;
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- string addition; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be divided." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_syntax );
- #endif
-
- break;
-
- case NUMBER:
- if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
- == (bnumber) 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) -1;
- op_pulldown( 2 );
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Divide by 0." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dbz );
- #endif
- return FALSE;
- }
- CURTASK exps[ level ].nval
- = exp_getnval( &( CURTASK exps[ level - 1 ] ))
- / exp_getnval( &( CURTASK exps[ level + 1 ] ));
- modf( (double) CURTASK exps[ level ].nval, &iportion );
- CURTASK exps[ level - 1 ].nval
- = exp_getnval( &( CURTASK exps[ level - 1 ] ))
- - ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
- * iportion );
- break;
-
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = (char) precision;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_exponent()
-
- DESCRIPTION: This function finds the exponential value
- of a number (on the left) to the power
- indicated on the right-hand side.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_exponent( int level, int precision )
- #else
- static int
- op_exponent( level, precision )
- int level;
- int precision;
- #endif
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_exponent(): entered function level <%d>.",
- level );
- bwb_debug ( bwb_ebuf );
- #endif
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- string addition; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be taken as exponents." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- CURTASK exps[ level - 1 ].nval
- = (bnumber) pow( (double) exp_getnval( &( CURTASK exps[ level - 1 ] )),
- (double) exp_getnval( &( CURTASK exps[ level + 1 ] )) );
- break;
-
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = (char) precision;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_intdiv()
-
- DESCRIPTION: This function divides the number on
- the left by the number on the right,
- returning the result as an integer.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_intdiv( int level, int precision )
- #else
- static int
- op_intdiv( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- string addition; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be divided." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- default:
- if ( exp_getnval( &( CURTASK exps[ level + 1 ] ))
- == (bnumber) 0 )
- {
- CURTASK exps[ level - 1 ].nval = (bnumber) -1;
- op_pulldown( 2 );
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Divide by 0." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dbz );
- #endif
- return FALSE;
- }
-
- CURTASK exps[ level - 1 ].nval
- = exp_getnval( &( CURTASK exps[ level - 1 ] ))
- / exp_getnval( &( CURTASK exps[ level + 1 ] ));
- break;
- }
-
- /* set variable to requested precision */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_or()
-
- DESCRIPTION: This function compares two integers and
- performs a logical OR on them.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_or( int level, int precision )
- #else
- static int
- op_or( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- logical comparison; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be compared logically." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- CURTASK exps[ level - 1 ].nval
- = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
- | (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
- break;
-
- }
-
- /* set variable type to integer */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_and()
-
- DESCRIPTION: This function compares two integers and
- performs a logical AND on them.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_and( int level, int precision )
- #else
- static int
- op_and( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
-
- /* both sides of the operation should be numbers for
- logical comparison; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be compared logically." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- CURTASK exps[ level - 1 ].nval
- = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
- & (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
- break;
-
- }
-
- /* set variable type to integer */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_not()
-
- DESCRIPTION: This function performs a logical NOT on
- the integer to the right.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_not( int level, int precision )
- #else
- static int
- op_not( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
-
- /* both sides of the operation should be numbers for
- logical comparison; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be compared logically." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- default:
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_not(): argument is <%d>, precision <%c>",
- (unsigned int) exp_getnval( &( CURTASK exps[ level + 1 ] )), precision );
- bwb_debug( bwb_ebuf );
- #endif
-
- CURTASK exps[ level ].nval = (bnumber)
- ~( (int) exp_getnval( &( CURTASK exps[ level + 1 ] )) );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_not(): result is <%d>, precision <%c>",
- (unsigned int) exp_getnval( &( CURTASK exps[ level ] )), precision );
- bwb_debug( bwb_ebuf );
- #endif
-
- break;
- }
-
- /* set variable type to integer */
-
- CURTASK exps[ level ].type = NUMBER;
- CURTASK exps[ level ].operation = NUMBER;
-
- /* decrement the stack once */
-
- op_pulldown( 1 );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_not(): CURTASK expsc <%d>, level <%d> result <%d>",
- CURTASK expsc, level, CURTASK exps[ CURTASK expsc ].nval );
- bwb_debug( bwb_ebuf );
- #endif
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_xor()
-
- DESCRIPTION: This function compares two integers and
- performs a logical XOR on them.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_xor( int level, int precision )
- #else
- static int
- op_xor( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
- /* both sides of the operation should be numbers for
- logical comparison; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be compared logically." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- case NUMBER:
- CURTASK exps[ level - 1 ].nval
- = (bnumber) ((int) exp_getnval( &( CURTASK exps[ level - 1 ] ))
- ^ (int) exp_getnval( &( CURTASK exps[ level + 1 ] )));
- break;
-
- }
-
- /* set variable type to integer */
-
- CURTASK exps[ level - 1 ].type = NUMBER;
- CURTASK exps[ level - 1 ].operation = NUMBER;
-
- /* decrement the stack twice */
-
- op_pulldown( 2 );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_negation()
-
- DESCRIPTION: This function performs a negation on the
- element to the right.
- Added by JBV 10/95
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_negation( int level, int precision )
- #else
- static int
- op_negation( level, precision )
- int level;
- int precision;
- #endif
- {
-
- switch( precision )
- {
- case STRING:
-
-
- /* both sides of the operation should be numbers for
- logical comparison; if not, report an error */
-
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Strings cannot be compared logically." );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_mismatch );
- #endif
-
- break;
-
- default:
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_negation(): argument is <%f>, precision <%c>",
- exp_getnval( &( CURTASK exps[ level + 1 ] )), precision );
- bwb_debug( bwb_ebuf );
- #endif
-
- CURTASK exps[ level ].nval = (bnumber)
- -( exp_getnval( &( CURTASK exps[ level + 1 ] )) );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_negation(): result is <%f>, precision <%c>",
- exp_getnval( &( CURTASK exps[ level ] )), precision );
- bwb_debug( bwb_ebuf );
- #endif
-
- break;
- }
-
- /* set variable type to requested precision (JBV) */
-
- CURTASK exps[ level ].type = (char) precision;
- CURTASK exps[ level ].operation = NUMBER;
-
- /* decrement the stack once */
-
- op_pulldown( 1 );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_negation(): CURTASK expsc <%d>, level <%d> result <%f>",
- CURTASK expsc, level, CURTASK exps[ CURTASK expsc ].nval );
- bwb_debug( bwb_ebuf );
- #endif
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_islevelstr()
-
- DESCRIPTION: This function determines whether the
- operation at a specified level involves a
- string constant or variable.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_islevelstr( int level )
- #else
- static int
- op_islevelstr( level )
- int level;
- #endif
- {
-
- /* first see if the level holds a string constant */
-
- if ( CURTASK exps[ level ].operation == CONST_STRING )
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
- level );
- bwb_debug( bwb_ebuf );
- #endif
-
- return TRUE;
- }
-
- /* see if the level holds a string variable */
-
- if ( CURTASK exps[ level ].operation == VARIABLE )
- {
- if ( CURTASK exps[ level ].xvar->type == STRING )
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_islevelstr(): string detected at level <%d>.",
- level );
- bwb_debug( bwb_ebuf );
- #endif
-
- return TRUE;
- }
- }
-
- /* test has failed, return FALSE */
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_islevelstr(): string not detected at level <%d>.",
- level );
- bwb_debug( bwb_ebuf );
- #endif
-
- return FALSE;
-
- }
-
- /***************************************************************
-
- FUNCTION: op_getprecision()
-
- DESCRIPTION: This function finds the precision for
- an operation by comparing the precision
- at this level and that two levels below.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_getprecision( int level )
- #else
- static int
- op_getprecision( level )
- int level;
- #endif
- {
-
- /* first test for string value */
-
- if ( ( CURTASK exps[ level + 1 ].type == STRING )
- || ( CURTASK exps[ level - 1 ].type == STRING ) )
- {
- return STRING;
- }
-
- /* Both are numbers, so we should be able to find a suitable
- precision level by starting with the top and moving down;
- check first for double precision */
-
- else
- {
- return NUMBER;
- }
-
- }
-
- /***************************************************************
-
- FUNCTION: op_pulldown()
-
- DESCRIPTION: This function pulls the expression stack
- down a specified number of levels, decrementing
- the expression stack counter (bycalling dec_esc())
- and decrementing the current "level" of operation
- processing.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- op_pulldown( int how_far )
- #else
- static int
- op_pulldown( how_far )
- int how_far;
- #endif
- {
- int level;
- register int c;
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in op_pulldown(): pull down e stack <%d> place(s)",
- how_far );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* first pull down the actual variables themselves */
-
- level = op_level + ( 2 - how_far );
- while ( CURTASK expsc >= ( level + how_far ) )
- {
-
- /*------------------------------------------------------*/
- /* But before memcpy, deallocate sbuffer for level, and */
- /* afterwards, set sbuffer for level + how_far to NULL! */
- /* Else konfusion reigns the next time around... (JBV) */
- /*------------------------------------------------------*/
-
- if( CURTASK exps[ level ].sval.sbuffer != NULL ) /* JBV */
- FREE( CURTASK exps[ level ].sval.sbuffer, "op_pulldown" );
- memcpy( &CURTASK exps[ level ], &CURTASK exps[ level + how_far ],
- (size_t) ( sizeof( struct exp_ese )) );
- CURTASK exps[ level + how_far ].sval.sbuffer = NULL; /* JBV */
-
- ++level;
-
- }
-
- /* decrement the expression stack counter */
-
- for ( c = 0; c < how_far; ++c )
- {
-
- if ( dec_esc() == TRUE )
- {
- --op_level;
- }
- else
- {
- return FALSE;
- }
-
- }
-
- return TRUE;
-
- }
-
-
|