From 0b16eadcf8426271211a8a005e0e3ef2131fd979 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 5 Oct 1999 16:28:37 +0000 Subject: [PATCH] 19991005-18:02 GMT+1 --- harbour/ChangeLog | 28 ++ harbour/include/hbver.h | 2 +- harbour/include/pcode.h | 4 +- harbour/source/compiler/genc.c | 8 +- harbour/source/compiler/genhrb.c | 4 +- harbour/source/compiler/harbour.c | 7 + harbour/source/compiler/harbour.y | 14 +- harbour/source/vm/hvm.c | 672 +++++++++++++++--------------- harbour/source/vm/mainstd.c | 7 +- harbour/source/vm/mainwin.c | 4 +- harbour/tests/rtl_test.prg | 234 ++++++++--- 11 files changed, 578 insertions(+), 406 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 78edd71776..02168cec1f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,31 @@ +19991005-18:02 GMT+1 Victor Szel + * tests/rtl_test.prg + + Added more complete tests for <,>,<=,>=,!= operators. + * source/vm/hvm.c + % hb_vmPopDate() is no more checking the type of the popped value, and + the related unrecoverable error is also removed, since the callers + do this check before each call. + * Some more function grouping, small corrections. + ! hb_vmLess(), hb_vmLessEqual(), hb_vmGreater(), hb_vmGreaterEqual() + some cases were not handled, so stack corruption could occure, when + two ARRAY/BLOCK/OBJECT were compared. Fixed. + ! hb_vmNotEqual() fixed for ARRAY/OBJECT/BLOCK types. + * source/vm/hvm.c + include/pcode.h + source/compiler/genc.c + source/compiler/genhrb.c + source/compiler/harbour.y + * HB_P_GENARRAY -> HB_P_ARRAYGEN + * HB_P_DIMARRAY -> HB_P_ARRAYDIM + !! WARNING !! Please rebuild all .PRG files, since the pcode values have + changed. + * include/hbver.h + + Revision set to "a" + * source/compiler/harbour.c + + isatty.c put back in order. + * source/compiler/main*.c + + Some small cleanups. + 19991005-14:41 GMT+1 Victor Szel * tests/run_tsta.bat tests/test_all.prg diff --git a/harbour/include/hbver.h b/harbour/include/hbver.h index f934518387..1ffe9881e9 100644 --- a/harbour/include/hbver.h +++ b/harbour/include/hbver.h @@ -84,7 +84,7 @@ extern int hb_day; #define hb_major 0 /* Major version number */ #define hb_minor 0 /* Minor version number */ -#define hb_revision "" /* Revision letter */ +#define hb_revision "a" /* Revision letter */ #define hb_build 30 /* Build number */ #define hb_year 1999 /* Build year */ #define hb_month 9 /* Build month */ diff --git a/harbour/include/pcode.h b/harbour/include/pcode.h index d8a5aaef68..eb07839c64 100644 --- a/harbour/include/pcode.h +++ b/harbour/include/pcode.h @@ -41,6 +41,8 @@ typedef enum HB_P_AND, /* peforms the logical AND of two latest stack values, removes them and places result */ HB_P_ARRAYAT, /* places on the virtual machine stack an array element */ HB_P_ARRAYPUT, /* sets array element, the array and the index are both on the stack */ + HB_P_ARRAYDIM, /* instructs the virtual machine to build an array with some specific dimensions */ + HB_P_ARRAYGEN, /* instructs the virtual machine to build an array and load elemnst from the stack */ HB_P_EQUAL, /* check if the latest two values on the stack are equal, removing them and leaving there the result */ HB_P_ENDBLOCK, /* end of a codeblock definition */ HB_P_ENDPROC, /* instructs the virtual machine to end execution */ @@ -50,11 +52,9 @@ typedef enum HB_P_FUNCTION, /* instructs the virtual machine to execute a function saving its result */ HB_P_FRAME, /* instructs the virtual machine about how many parameters and locals a function uses */ HB_P_FUNCPTR, /* returns a function address pointer */ - HB_P_GENARRAY, /* instructs the virtual machine to build an array and load elemnst from the stack */ HB_P_GREATER, /* checks if the second latest value on the stack is greater that the lastest one */ HB_P_GREATEREQUAL, /* checks if the second latest value on the stack is greater equal that the latest one, leaves the result only */ HB_P_DEC, /* decrements the latest value on the virtual machine stack */ - HB_P_DIMARRAY, /* instructs the virtual machine to build an array with some specific dimensions */ HB_P_DIVIDE, /* divides the latest two values on the stack, removing them and leaving there the result */ HB_P_DO, /* instructs the virtual machine to execute a function discarding its result */ HB_P_DUPLICATE, /* places a copy of the latest virtual machine stack value on to the stack */ diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 75c8705f0e..f52cead9b8 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -210,9 +210,9 @@ void GenCCode( PHB_FNAME pFileName ) /* generates the C language output */ lPCodePos++; break; - case HB_P_DIMARRAY: + case HB_P_ARRAYDIM: w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\tHB_P_DIMARRAY, %i, %i,", + fprintf( yyc, "\tHB_P_ARRAYDIM, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); if( _bComments ) fprintf( yyc, "\t/* %i */", w ); @@ -315,9 +315,9 @@ void GenCCode( PHB_FNAME pFileName ) /* generates the C language output */ lPCodePos += 3; break; - case HB_P_GENARRAY: + case HB_P_ARRAYGEN: w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\tHB_P_GENARRAY, %i, %i,", + fprintf( yyc, "\tHB_P_ARRAYGEN, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] ); if( _bComments ) fprintf( yyc, "\t/* %i */", w ); diff --git a/harbour/source/compiler/genhrb.c b/harbour/source/compiler/genhrb.c index 6424fc5edb..0a0e35c797 100644 --- a/harbour/source/compiler/genhrb.c +++ b/harbour/source/compiler/genhrb.c @@ -206,10 +206,10 @@ void GenPortObj( PHB_FNAME pFileName ) fputc( pFunc->pCode[ lPCodePos++ ], yyc ); break; - case HB_P_DIMARRAY: + case HB_P_ARRAYDIM: case HB_P_DO: case HB_P_FUNCTION: - case HB_P_GENARRAY: + case HB_P_ARRAYGEN: case HB_P_JUMP: case HB_P_JUMPFALSE: case HB_P_JUMPTRUE: diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index fc3021bac7..ef8d8adf59 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -46,3 +46,10 @@ int main( int argc, char * argv[] ) { return harbour_main( argc, argv ); } + +#ifdef __IBMCPP__ +int isatty( int handle ) +{ + return ( handle < 4 ) ? 1 : 0; +} +#endif diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 11bd0f7d3a..f663e636f2 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -198,7 +198,7 @@ void AddVar( char * szVarName ); /* add a new param, local, static variable to a PCOMSYMBOL AddSymbol( char *, USHORT * ); void CheckDuplVars( PVAR pVars, char * szVarName, int iVarScope ); /*checks for duplicate variables definitions */ void Dec( void ); /* generates the pcode to decrement the latest value on the virtual machine stack */ -void DimArray( int iDimensions ); /* instructs the virtual machine to build an array with wDimensions */ +void ArrayDim( int iDimensions ); /* instructs the virtual machine to build an array with wDimensions */ void Do( BYTE bParams ); /* generates the pcode to execute a Clipper function discarding its result */ void Duplicate( void ); /* duplicates the virtual machine latest stack latest value and places it on the stack */ void DupPCode( ULONG ulStart ); /* duplicates the current generated pcode from an offset */ @@ -1044,8 +1044,8 @@ VarDef : IDENTIFIER { cVarType = ' '; AddV | IDENTIFIER AS_ARRAY INASSIGN { cVarType = 'A'; AddVar( $1 ); } Expression { PopId( $1 ); } | IDENTIFIER AS_BLOCK INASSIGN { cVarType = 'B'; AddVar( $1 ); } Expression { PopId( $1 ); } | IDENTIFIER AS_OBJECT INASSIGN { cVarType = 'O'; AddVar( $1 ); } Expression { PopId( $1 ); } - | IDENTIFIER ArrExpList ']' { cVarType = ' '; AddVar( $1 ); DimArray( $2 ); PopId( $1 ); } - | IDENTIFIER ArrExpList ']' AS_ARRAY { cVarType = 'A'; AddVar( $1 ); DimArray( $2 ); PopId( $1 ); } + | IDENTIFIER ArrExpList ']' { cVarType = ' '; AddVar( $1 ); ArrayDim( $2 ); PopId( $1 ); } + | IDENTIFIER ArrExpList ']' AS_ARRAY { cVarType = 'A'; AddVar( $1 ); ArrayDim( $2 ); PopId( $1 ); } ; ArrExpList : '[' Expression { $$ = 1; } @@ -4070,9 +4070,9 @@ void Dec( void ) } } -void DimArray( int iDimensions ) +void ArrayDim( int iDimensions ) { - GenPCode3( HB_P_DIMARRAY, LOBYTE( iDimensions ), HIBYTE( iDimensions ) ); + GenPCode3( HB_P_ARRAYDIM, LOBYTE( iDimensions ), HIBYTE( iDimensions ) ); } void Do( BYTE bParams ) @@ -4245,14 +4245,14 @@ void Function( BYTE bParams ) void GenArray( int iElements ) { - GenPCode3( HB_P_GENARRAY, LOBYTE( iElements ), HIBYTE( iElements ) ); + GenPCode3( HB_P_ARRAYGEN, LOBYTE( iElements ), HIBYTE( iElements ) ); if( _iWarnings ) { PSTACK_VAL_TYPE pFree; int iIndex; - /* Releasing the stack items used by the _GENARRAY (other than the 1st element). */ + /* Releasing the stack items used by the HB_P_ARRAYGEN (other than the 1st element). */ for( iIndex = iElements; iIndex > 1; iIndex-- ) { pFree = pStackValType; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index e8a55dfa0b..4fb0f1d422 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -72,7 +72,7 @@ extern HARBOUR HB_SYSINIT( void ); /* PCode functions */ -/* Operators ( mathematical / character / misc ) */ +/* Operators (mathematical / character / misc) */ static void hb_vmNegate( void ); /* negates (-) the latest value on the stack */ static void hb_vmPlus( void ); /* sums the latest two values on the stack, removes them and leaves the result */ static void hb_vmMinus( void ); /* substracts the latest two values on the stack, removes them and leaves the result */ @@ -111,41 +111,41 @@ static void hb_vmOperatorCall( PHB_ITEM, PHB_ITEM, char * ); /* call an overl static void hb_vmOperatorCallUnary( PHB_ITEM, char * ); /* call an overloaded unary operator */ /* Database */ -static ERRCODE hb_vmSelectWorkarea( PHB_ITEM ); /* select the workarea using a given item or a substituted value */ -static void hb_vmSwapAlias( void ); /* swaps items on the eval stack and pops the workarea number */ +static ERRCODE hb_vmSelectWorkarea( PHB_ITEM ); /* select the workarea using a given item or a substituted value */ +static void hb_vmSwapAlias( void ); /* swaps items on the eval stack and pops the workarea number */ /* Execution */ -static HARBOUR hb_vmDoBlock( void ); /* executes a codeblock */ -static void hb_vmFrame( BYTE bLocals, BYTE bParams ); /* increases the stack pointer for the amount of locals and params suplied */ +static HARBOUR hb_vmDoBlock( void ); /* executes a codeblock */ static void hb_vmLocalName( USHORT uiLocal, char * szLocalName ); /* locals and parameters index and name information for the debugger */ static void hb_vmModuleName( char * szModuleName ); /* PRG and function name information for the debugger */ +static void hb_vmFrame( BYTE bLocals, BYTE bParams ); /* increases the stack pointer for the amount of locals and params suplied */ static void hb_vmSFrame( PHB_SYMB pSym ); /* sets the statics frame for a function */ static void hb_vmStatics( PHB_SYMB pSym ); /* increases the the global statics array to hold a PRG statics */ -static void hb_vmRetValue( void ); /* pops the latest stack value into stack.Return */ -static void hb_vmEndBlock( void ); /* copies the last codeblock pushed value into the return value */ +static void hb_vmEndBlock( void ); /* copies the last codeblock pushed value into the return value */ +static void hb_vmRetValue( void ); /* pops the latest stack value into stack.Return */ static void hb_vmDebuggerShowLine( USHORT uiLine ); /* makes the debugger shows a specific source code line */ -static void hb_vmDebuggerEndProc( void ); /* notifies the debugger for an endproc */ +static void hb_vmDebuggerEndProc( void ); /* notifies the debugger for an endproc */ /* Push */ -static void hb_vmPushAlias( void ); /* pushes the current workarea number */ -static void hb_vmPushAliasedField( PHB_SYMB ); /* pushes an aliased field on the eval stack */ +static void hb_vmPushAlias( void ); /* pushes the current workarea number */ +static void hb_vmPushAliasedField( PHB_SYMB ); /* pushes an aliased field on the eval stack */ static void hb_vmPushBlock( BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */ -static void hb_vmPushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */ -static void hb_vmPushLocalByRef( SHORT iLocal ); /* pushes a local by refrence onto the stack */ -static void hb_vmPushStatic( USHORT uiStatic ); /* pushes the containts of a static onto the stack */ -static void hb_vmPushStaticByRef( USHORT uiLocal ); /* pushes a static by refrence onto the stack */ -static void hb_vmDuplicate( void ); /* duplicates the latest value on the stack */ -static void hb_vmDuplTwo( void ); /* duplicates the latest two value on the stack */ +static void hb_vmPushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */ +static void hb_vmPushLocalByRef( SHORT iLocal ); /* pushes a local by refrence onto the stack */ +static void hb_vmPushStatic( USHORT uiStatic ); /* pushes the containts of a static onto the stack */ +static void hb_vmPushStaticByRef( USHORT uiStatic ); /* pushes a static by refrence onto the stack */ +static void hb_vmDuplicate( void ); /* duplicates the latest value on the stack */ +static void hb_vmDuplTwo( void ); /* duplicates the latest two value on the stack */ /* Pop */ -static void hb_vmPopAlias( void ); /* pops the workarea number form the eval stack */ -static void hb_vmPopAliasedField( PHB_SYMB ); /* pops an aliased field from the eval stack*/ -static long hb_vmPopDate( void ); /* pops the stack latest value and returns its date value as a LONG */ -static double hb_vmPopNumber( void ); /* pops the stack latest value and returns its numeric value */ -static double hb_vmPopDouble( int * ); /* pops the stack latest value and returns its double numeric format value */ static BOOL hb_vmPopLogical( void ); /* pops the stack latest value and returns its logical value */ -static void hb_vmPopLocal( SHORT iLocal ); /* pops the stack latest value onto a local */ -static void hb_vmPopStatic( USHORT uiStatic ); /* pops the stack latest value onto a static */ +static long hb_vmPopDate( void ); /* pops the stack latest value and returns its date value as a LONG */ +static double hb_vmPopNumber( void ); /* pops the stack latest value and returns its numeric value */ +static double hb_vmPopDouble( int * ); /* pops the stack latest value and returns its double numeric format value */ +static void hb_vmPopAlias( void ); /* pops the workarea number form the eval stack */ +static void hb_vmPopAliasedField( PHB_SYMB ); /* pops an aliased field from the eval stack*/ +static void hb_vmPopLocal( SHORT iLocal ); /* pops the stack latest value onto a local */ +static void hb_vmPopStatic( USHORT uiStatic ); /* pops the stack latest value onto a static */ /* stack management functions */ static void hb_stackDec( void ); /* pops an item from the stack without clearing it's contents */ @@ -306,6 +306,7 @@ void hb_vmInit( void ) for( i = 1; i < hb_cmdargARGC(); i++ ) /* places application parameters on the stack */ { char ** argv = hb_cmdargARGV(); + /* Filter out any parameters beginning with //, like //INFO */ if( ! hb_cmdargIsInternal( argv[ i ] ) ) { @@ -487,12 +488,12 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w++; break; - case HB_P_DIMARRAY: + case HB_P_ARRAYDIM: hb_vmArrayDim( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); w += 3; break; - case HB_P_GENARRAY: + case HB_P_ARRAYGEN: hb_vmArrayGen( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); w += 3; break; @@ -721,27 +722,41 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w++; break; - case HB_P_DUPLICATE: - hb_vmDuplicate(); + case HB_P_ZERO: + hb_vmPushInteger( 0 ); w++; break; - case HB_P_DUPLTWO: - hb_vmDuplTwo(); + case HB_P_PUSHNIL: + stack.pPos->type = IT_NIL; + hb_stackPush(); + HB_DEBUG( "(hb_vmPushNil)\n" ); w++; break; - case HB_P_PUSHALIAS: - hb_vmPushAlias(); - w++; - break; - - case HB_P_PUSHALIASEDFIELD: - uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - hb_vmPushAliasedField( pSymbols + uiParams ); + case HB_P_PUSHINT: + hb_vmPushInteger( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); w += 3; break; + case HB_P_PUSHLONG: + hb_vmPushLong( * ( long * ) ( &pCode[ w + 1 ] ) ); + w += 5; + break; + + case HB_P_PUSHDOUBLE: + hb_vmPushDouble( * ( double * ) ( &pCode[ w + 1 ] ), ( int ) * ( BYTE * ) &pCode[ w + 1 + sizeof( double ) ] ); + w += 1 + sizeof( double ) + 1; + break; + + case HB_P_PUSHSTR: + { + USHORT uiSize = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + hb_vmPushString( ( char * ) pCode + w + 3, ( ULONG ) uiSize ); + w += ( uiSize + 3 ); + } + break; + case HB_P_PUSHBLOCK: /* +0 -> _pushblock * +1 +2 -> size of codeblock @@ -753,9 +768,26 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w += ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); break; - case HB_P_PUSHDOUBLE: - hb_vmPushDouble( * ( double * ) ( &pCode[ w + 1 ] ), ( int ) * ( BYTE * ) &pCode[ w + 1 + sizeof( double ) ] ); - w += 1 + sizeof( double ) + 1; + case HB_P_PUSHSELF: + hb_vmPush( stack.pBase + 1 ); + w++; + break; + + case HB_P_PUSHSYM: + uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + hb_vmPushSymbol( pSymbols + uiParams ); + w += 3; + break; + + case HB_P_PUSHALIAS: + hb_vmPushAlias(); + w++; + break; + + case HB_P_PUSHALIASEDFIELD: + uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); + hb_vmPushAliasedField( pSymbols + uiParams ); + w += 3; break; case HB_P_PUSHFIELD: @@ -768,11 +800,6 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w += 3; break; - case HB_P_PUSHINT: - hb_vmPushInteger( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); - w += 3; - break; - case HB_P_PUSHLOCAL: hb_vmPushLocal( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); w += 3; @@ -783,9 +810,14 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w += 3; break; - case HB_P_PUSHLONG: - hb_vmPushLong( * ( long * ) ( &pCode[ w + 1 ] ) ); - w += 5; + case HB_P_PUSHSTATIC: + hb_vmPushStatic( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + w += 3; + break; + + case HB_P_PUSHSTATICREF: + hb_vmPushStaticByRef( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + w += 3; break; case HB_P_PUSHMEMVAR: @@ -804,42 +836,6 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w += 3; break; - case HB_P_PUSHNIL: - stack.pPos->type = IT_NIL; - hb_stackPush(); - HB_DEBUG( "(hb_vmPushNil)\n" ); - w++; - break; - - case HB_P_PUSHSELF: - hb_vmPush( stack.pBase + 1 ); - w++; - break; - - case HB_P_PUSHSTATIC: - hb_vmPushStatic( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); - w += 3; - break; - - case HB_P_PUSHSTATICREF: - hb_vmPushStaticByRef( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); - w += 3; - break; - - case HB_P_PUSHSTR: - { - USHORT uiSize = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - hb_vmPushString( ( char * ) pCode + w + 3, ( ULONG ) uiSize ); - w += ( uiSize + 3 ); - } - break; - - case HB_P_PUSHSYM: - uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); - hb_vmPushSymbol( pSymbols + uiParams ); - w += 3; - break; - case HB_P_PUSHVARIABLE: /* Push a value of variable of unknown type onto the eval stack */ @@ -878,8 +874,13 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) } break; - case HB_P_ZERO: - hb_vmPushInteger( 0 ); + case HB_P_DUPLICATE: + hb_vmDuplicate(); + w++; + break; + + case HB_P_DUPLTWO: + hb_vmDuplTwo(); w++; break; @@ -918,6 +919,11 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w += 3; break; + case HB_P_POPSTATIC: + hb_vmPopStatic( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); + w += 3; + break; + case HB_P_POPMEMVAR: uiParams = pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ); hb_stackDec(); @@ -945,11 +951,6 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) w += 3; break; - case HB_P_POPSTATIC: - hb_vmPopStatic( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) ); - w += 3; - break; - /* misc */ case HB_P_NOOP: @@ -1431,7 +1432,7 @@ static void hb_vmEqual( BOOL bExact ) hb_stackPop(); hb_vmPushLogical( bResult ); } - else if( ( pItem1->type != pItem2->type ) || + else if( pItem1->type != pItem2->type || ( IS_BLOCK( pItem1 ) && IS_BLOCK( pItem2 ) ) || ( ! bExact && IS_ARRAY( pItem1 ) && IS_ARRAY( pItem2 ) ) ) { @@ -1506,7 +1507,9 @@ static void hb_vmNotEqual( void ) else if( IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "#" ) ) hb_vmOperatorCall( pItem1, pItem2, "#" ); - else if( pItem1->type != pItem2->type ) + else if( pItem1->type != pItem2->type || + ( IS_BLOCK( pItem1 ) && IS_BLOCK( pItem2 ) ) || + ( IS_ARRAY( pItem1 ) && IS_ARRAY( pItem2 ) ) ) { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1072, NULL, "<>" ); @@ -1561,12 +1564,13 @@ static void hb_vmLess( void ) else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, "<" ) ) hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, "<" ); - else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<" ); if( pResult ) { + hb_stackPop(); hb_stackPop(); hb_vmPush( pResult ); hb_itemRelease( pResult ); @@ -1608,12 +1612,13 @@ static void hb_vmLessEqual( void ) else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, "<=" ) ) hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, "<=" ); - else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1074, NULL, "<=" ); if( pResult ) { + hb_stackPop(); hb_stackPop(); hb_vmPush( pResult ); hb_itemRelease( pResult ); @@ -1655,12 +1660,13 @@ static void hb_vmGreater( void ) else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, ">" ) ) hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, ">" ); - else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1075, NULL, ">" ); if( pResult ) { + hb_stackPop(); hb_stackPop(); hb_vmPush( pResult ); hb_itemRelease( pResult ); @@ -1702,12 +1708,13 @@ static void hb_vmGreaterEqual( void ) else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, ">=" ) ) hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, ">=" ); - else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1076, NULL, ">=" ); if( pResult ) { + hb_stackPop(); hb_stackPop(); hb_vmPush( pResult ); hb_itemRelease( pResult ); @@ -2248,21 +2255,6 @@ static HARBOUR hb_vmDoBlock( void ) HB_DEBUG( "End of DoBlock\n" ); } -static void hb_vmFrame( BYTE bLocals, BYTE bParams ) -{ - int iTotal = bLocals + bParams; - - if( iTotal ) - { - int i; - - for( i = 0; i < ( iTotal - stack.pBase->item.asSymbol.paramcnt ); i++ ) - hb_vmPushNil(); - } - - HB_DEBUG( "Frame\n" ); -} - void hb_vmFunction( USHORT uiParams ) { hb_itemClear( &stack.Return ); @@ -2288,6 +2280,21 @@ static void hb_vmModuleName( char * szModuleName ) /* PRG and function name info s_bDebugShowLines = TRUE; } +static void hb_vmFrame( BYTE bLocals, BYTE bParams ) +{ + int iTotal = bLocals + bParams; + + if( iTotal ) + { + int i; + + for( i = 0; i < ( iTotal - stack.pBase->item.asSymbol.paramcnt ); i++ ) + hb_vmPushNil(); + } + + HB_DEBUG( "Frame\n" ); +} + static void hb_vmSFrame( PHB_SYMB pSym ) /* sets the statics frame for a function */ { /* _INITSTATICS is now the statics frame. Statics() changed it! */ @@ -2295,15 +2302,6 @@ static void hb_vmSFrame( PHB_SYMB pSym ) /* sets the statics frame for a fu HB_DEBUG( "SFrame\n" ); } -static void hb_vmRetValue( void ) -{ - hb_stackDec(); /* make the last item visible */ - hb_itemCopy( &stack.Return, stack.pPos ); /* copy it */ - hb_itemClear( stack.pPos ); /* now clear it */ - - HB_DEBUG( "hb_vmRetValue\n" ); -} - static void hb_vmStatics( PHB_SYMB pSym ) /* initializes the global aStatics array or redimensionates it */ { USHORT uiStatics = hb_vmPopNumber(); @@ -2330,6 +2328,15 @@ static void hb_vmEndBlock( void ) HB_DEBUG( "EndBlock\n" ); } +static void hb_vmRetValue( void ) +{ + hb_stackDec(); /* make the last item visible */ + hb_itemCopy( &stack.Return, stack.pPos ); /* copy it */ + hb_itemClear( stack.pPos ); /* now clear it */ + + HB_DEBUG( "hb_vmRetValue\n" ); +} + static void hb_vmDebuggerEndProc( void ) { HB_ITEM item; @@ -2360,6 +2367,144 @@ static void hb_vmDebuggerShowLine( USHORT uiLine ) /* makes the debugger shows a /* Push */ /* ------------------------------- */ +void hb_vmPush( PHB_ITEM pItem ) +{ + hb_itemCopy( stack.pPos, pItem ); + hb_stackPush(); + + HB_DEBUG( "hb_vmPush\n" ); +} + +void hb_vmPushNil( void ) +{ + stack.pPos->type = IT_NIL; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushNil\n" ); +} + +void hb_vmPushLogical( BOOL bValue ) +{ + stack.pPos->type = IT_LOGICAL; + stack.pPos->item.asLogical.value = bValue; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushLogical\n" ); +} + +void hb_vmPushNumber( double dNumber, int iDec ) +{ + if( iDec ) + hb_vmPushDouble( dNumber, iDec ); + + else if( SHRT_MIN <= dNumber && dNumber <= SHRT_MAX ) + hb_vmPushInteger( dNumber ); + + else if( LONG_MIN <= dNumber && dNumber <= LONG_MAX ) + hb_vmPushLong( dNumber ); + + else + hb_vmPushDouble( dNumber, hb_set.HB_SET_DECIMALS ); +} + +void hb_vmPushInteger( int iNumber ) +{ + stack.pPos->type = IT_INTEGER; + stack.pPos->item.asInteger.value = iNumber; + stack.pPos->item.asInteger.length = 10; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushInteger\n" ); +} + +void hb_vmPushLong( long lNumber ) +{ + stack.pPos->type = IT_LONG; + stack.pPos->item.asLong.value = lNumber; + stack.pPos->item.asLong.length = 10; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushLong\n" ); +} + +void hb_vmPushDouble( double dNumber, int iDec ) +{ + stack.pPos->type = IT_DOUBLE; + stack.pPos->item.asDouble.value = dNumber; + stack.pPos->item.asDouble.length = ( dNumber > 10000000000.0 ) ? 20 : 10; + stack.pPos->item.asDouble.decimal = ( iDec > 9 ) ? 9 : iDec; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushDouble\n" ); +} + +void hb_vmPushDate( LONG lDate ) +{ + stack.pPos->type = IT_DATE; + stack.pPos->item.asDate.value = lDate; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushDate\n" ); +} + +void hb_vmPushString( char * szText, ULONG length ) +{ + char * szTemp = ( char * ) hb_xgrab( length + 1 ); + + hb_xmemcpy( szTemp, szText, length ); + szTemp[ length ] = '\0'; + + stack.pPos->type = IT_STRING; + stack.pPos->item.asString.length = length; + stack.pPos->item.asString.value = szTemp; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushString\n" ); +} + +void hb_vmPushSymbol( PHB_SYMB pSym ) +{ + stack.pPos->type = IT_SYMBOL; + stack.pPos->item.asSymbol.value = pSym; + stack.pPos->item.asSymbol.stackbase = stack.pPos - stack.pItems; + hb_stackPush(); + + HB_DEBUG2( "hb_vmPushSymbol: %s\n", pSym->szName ); +} + +/* +0 -> HB_P_PUSHBLOCK + * +1 +2 -> size of codeblock + * +3 +4 -> number of expected parameters + * +5 +6 -> number of referenced local variables + * +7 -> start of table with referenced local variables + */ +static void hb_vmPushBlock( BYTE * pCode, PHB_SYMB pSymbols ) +{ + USHORT uiLocals; + + stack.pPos->type = IT_BLOCK; + + uiLocals = pCode[ 5 ] + ( pCode[ 6 ] * 256 ); + stack.pPos->item.asBlock.value = + hb_codeblockNew( pCode + 7 + uiLocals * 2, /* pcode buffer */ + uiLocals, /* number of referenced local variables */ + ( USHORT * ) ( pCode + 7 ), /* table with referenced local variables */ + pSymbols ); + + /* store the statics base of function where the codeblock was defined + */ + stack.pPos->item.asBlock.statics = stack.iStatics; + /* store the number of expected parameters + */ + stack.pPos->item.asBlock.paramcnt = pCode[ 3 ] + ( pCode[ 4 ] * 256 ); + /* store the line number where the codeblock was defined + */ + stack.pPos->item.asBlock.lineno = stack.pBase->item.asSymbol.lineno; + hb_stackPush(); + + HB_DEBUG( "hb_vmPushBlock\n" ); +} + /* pushes current workarea number on the eval stack */ static void hb_vmPushAlias( void ) @@ -2452,144 +2597,6 @@ static void hb_vmPushStaticByRef( USHORT uiStatic ) HB_DEBUG2( "hb_vmPushStaticByRef %i\n", uiStatic ); } -void hb_vmPush( PHB_ITEM pItem ) -{ - hb_itemCopy( stack.pPos, pItem ); - hb_stackPush(); - - HB_DEBUG( "hb_vmPush\n" ); -} - -void hb_vmPushLogical( BOOL bValue ) -{ - stack.pPos->type = IT_LOGICAL; - stack.pPos->item.asLogical.value = bValue; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushLogical\n" ); -} - -void hb_vmPushNil( void ) -{ - stack.pPos->type = IT_NIL; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushNil\n" ); -} - -void hb_vmPushNumber( double dNumber, int iDec ) -{ - if( iDec ) - hb_vmPushDouble( dNumber, iDec ); - - else if( SHRT_MIN <= dNumber && dNumber <= SHRT_MAX ) - hb_vmPushInteger( dNumber ); - - else if( LONG_MIN <= dNumber && dNumber <= LONG_MAX ) - hb_vmPushLong( dNumber ); - - else - hb_vmPushDouble( dNumber, hb_set.HB_SET_DECIMALS ); -} - -void hb_vmPushString( char * szText, ULONG length ) -{ - char * szTemp = ( char * ) hb_xgrab( length + 1 ); - - hb_xmemcpy( szTemp, szText, length ); - szTemp[ length ] = '\0'; - - stack.pPos->type = IT_STRING; - stack.pPos->item.asString.length = length; - stack.pPos->item.asString.value = szTemp; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushString\n" ); -} - -void hb_vmPushSymbol( PHB_SYMB pSym ) -{ - stack.pPos->type = IT_SYMBOL; - stack.pPos->item.asSymbol.value = pSym; - stack.pPos->item.asSymbol.stackbase = stack.pPos - stack.pItems; - hb_stackPush(); - - HB_DEBUG2( "hb_vmPushSymbol: %s\n", pSym->szName ); -} - -/* +0 -> HB_P_PUSHBLOCK - * +1 +2 -> size of codeblock - * +3 +4 -> number of expected parameters - * +5 +6 -> number of referenced local variables - * +7 -> start of table with referenced local variables - */ -static void hb_vmPushBlock( BYTE * pCode, PHB_SYMB pSymbols ) -{ - USHORT uiLocals; - - stack.pPos->type = IT_BLOCK; - - uiLocals = pCode[ 5 ] + ( pCode[ 6 ] * 256 ); - stack.pPos->item.asBlock.value = - hb_codeblockNew( pCode + 7 + uiLocals * 2, /* pcode buffer */ - uiLocals, /* number of referenced local variables */ - ( USHORT * ) ( pCode + 7 ), /* table with referenced local variables */ - pSymbols ); - - /* store the statics base of function where the codeblock was defined - */ - stack.pPos->item.asBlock.statics = stack.iStatics; - /* store the number of expected parameters - */ - stack.pPos->item.asBlock.paramcnt = pCode[ 3 ] + ( pCode[ 4 ] * 256 ); - /* store the line number where the codeblock was defined - */ - stack.pPos->item.asBlock.lineno = stack.pBase->item.asSymbol.lineno; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushBlock\n" ); -} - -void hb_vmPushDate( LONG lDate ) -{ - stack.pPos->type = IT_DATE; - stack.pPos->item.asDate.value = lDate; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushDate\n" ); -} - -void hb_vmPushDouble( double dNumber, int iDec ) -{ - stack.pPos->type = IT_DOUBLE; - stack.pPos->item.asDouble.value = dNumber; - stack.pPos->item.asDouble.length = ( dNumber > 10000000000.0 ) ? 20 : 10; - stack.pPos->item.asDouble.decimal = ( iDec > 9 ) ? 9 : iDec; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushDouble\n" ); -} - -void hb_vmPushInteger( int iNumber ) -{ - stack.pPos->type = IT_INTEGER; - stack.pPos->item.asInteger.value = iNumber; - stack.pPos->item.asInteger.length = 10; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushInteger\n" ); -} - -void hb_vmPushLong( long lNumber ) -{ - stack.pPos->type = IT_LONG; - stack.pPos->item.asLong.value = lNumber; - stack.pPos->item.asLong.length = 10; - hb_stackPush(); - - HB_DEBUG( "hb_vmPushLong\n" ); -} - static void hb_vmDuplicate( void ) { hb_itemCopy( stack.pPos, stack.pPos - 1 ); @@ -2608,50 +2615,73 @@ static void hb_vmDuplTwo( void ) /* Pop */ /* ------------------------------- */ -static long hb_vmPopDate( void ) +static BOOL hb_vmPopLogical( void ) { - hb_stackDec(); + HB_DEBUG( "hb_vmPopLogical\n" ); - if( IS_DATE( stack.pPos ) ) + if( IS_LOGICAL( stack.pPos - 1 ) ) { + hb_stackDec(); + stack.pPos->type = IT_NIL; - return stack.pPos->item.asDate.value; + return stack.pPos->item.asLogical.value; } else { - hb_errInternal( 9999, "Incorrect item value trying to Pop a date value", NULL, NULL ); - return 0; /* To suppress compiler warning */ + hb_errRT_BASE( EG_ARG, 1066, NULL, hb_langDGetErrorDesc( EG_CONDITION ) ); + return FALSE; } } -/* Pops the item from the eval stack and uses it to select the current - * workarea - */ -static void hb_vmPopAlias( void ) +/* NOTE: Type checking should be done by the caller. */ + +static long hb_vmPopDate( void ) { + HB_DEBUG( "hb_vmPopDate\n" ); + hb_stackDec(); - hb_vmSelectWorkarea( stack.pPos ); - HB_DEBUG( "hb_vmPopAlias\n" ); + stack.pPos->type = IT_NIL; + return stack.pPos->item.asDate.value; } -/* Pops the alias to use it to select a workarea and next pops a value - * into given field - */ -static void hb_vmPopAliasedField( PHB_SYMB pSym ) +/* NOTE: Type checking should be done by the caller. */ + +static double hb_vmPopNumber( void ) { - int iCurrArea = hb_rddGetCurrentWorkAreaNumber(); + PHB_ITEM pItem = stack.pPos - 1; + double dNumber; - if( hb_vmSelectWorkarea( stack.pPos - 1 ) == SUCCESS ) - hb_rddPutFieldValue( stack.pPos - 2, pSym ); + hb_stackDec(); - hb_rddSelectWorkAreaNumber( iCurrArea ); - hb_stackDec(); /* alias - it was cleared in hb_vmSelectWorkarea */ - hb_stackPop(); /* field value */ + switch( pItem->type & ~IT_BYREF ) + { + case IT_INTEGER: + dNumber = ( double ) pItem->item.asInteger.value; + break; - HB_DEBUG( "hb_vmPopAliasedField\n" ); + case IT_LONG: + dNumber = ( double ) pItem->item.asLong.value; + break; + + case IT_DOUBLE: + dNumber = pItem->item.asDouble.value; + break; + + default: + hb_errInternal( 9999, "Incorrect item on the stack trying to pop a number", NULL, NULL ); + break; + } + + stack.pPos->type = IT_NIL; + + HB_DEBUG( "hb_vmPopNumber\n" ); + + return dNumber; } +/* NOTE: Type checking should be done by the caller. */ + static double hb_vmPopDouble( int * piDec ) { double dNumber; @@ -2687,6 +2717,34 @@ static double hb_vmPopDouble( int * piDec ) return dNumber; } +/* Pops the item from the eval stack and uses it to select the current + * workarea + */ +static void hb_vmPopAlias( void ) +{ + hb_stackDec(); + hb_vmSelectWorkarea( stack.pPos ); + + HB_DEBUG( "hb_vmPopAlias\n" ); +} + +/* Pops the alias to use it to select a workarea and next pops a value + * into given field + */ +static void hb_vmPopAliasedField( PHB_SYMB pSym ) +{ + int iCurrArea = hb_rddGetCurrentWorkAreaNumber(); + + if( hb_vmSelectWorkarea( stack.pPos - 1 ) == SUCCESS ) + hb_rddPutFieldValue( stack.pPos - 2, pSym ); + + hb_rddSelectWorkAreaNumber( iCurrArea ); + hb_stackDec(); /* alias - it was cleared in hb_vmSelectWorkarea */ + hb_stackPop(); /* field value */ + + HB_DEBUG( "hb_vmPopAliasedField\n" ); +} + static void hb_vmPopLocal( SHORT iLocal ) { hb_stackDec(); @@ -2712,55 +2770,6 @@ static void hb_vmPopLocal( SHORT iLocal ) HB_DEBUG( "hb_vmPopLocal\n" ); } -static BOOL hb_vmPopLogical( void ) -{ - if( IS_LOGICAL( stack.pPos - 1 ) ) - { - hb_stackDec(); - - stack.pPos->type = IT_NIL; - return stack.pPos->item.asLogical.value; - } - else - { - hb_errRT_BASE( EG_ARG, 1066, NULL, hb_langDGetErrorDesc( EG_CONDITION ) ); - return FALSE; - } -} - -static double hb_vmPopNumber( void ) -{ - PHB_ITEM pItem = stack.pPos - 1; - double dNumber; - - hb_stackDec(); - - switch( pItem->type & ~IT_BYREF ) - { - case IT_INTEGER: - dNumber = ( double ) pItem->item.asInteger.value; - break; - - case IT_LONG: - dNumber = ( double ) pItem->item.asLong.value; - break; - - case IT_DOUBLE: - dNumber = pItem->item.asDouble.value; - break; - - default: - hb_errInternal( 9999, "Incorrect item on the stack trying to pop a number", NULL, NULL ); - break; - } - - stack.pPos->type = IT_NIL; - - HB_DEBUG( "hb_vmPopNumber\n" ); - - return dNumber; -} - static void hb_vmPopStatic( USHORT uiStatic ) { PHB_ITEM pStatic; @@ -3392,6 +3401,7 @@ void hb_vmRequestBreak( PHB_ITEM pItem ) { if( pItem ) hb_itemCopy( stack.pItems + s_lRecoverBase + HB_RECOVER_VALUE, pItem ); + s_uiActionRequest = HB_BREAK_REQUESTED; } else diff --git a/harbour/source/vm/mainstd.c b/harbour/source/vm/mainstd.c index c7d6f6cb60..571610517d 100644 --- a/harbour/source/vm/mainstd.c +++ b/harbour/source/vm/mainstd.c @@ -33,10 +33,6 @@ * */ -void hb_cmdargInit( int argc, char * argv[] ); -void hb_vmInit( void ); -void hb_vmQuit( void ); - #include "extend.h" #include "ctoharb.h" @@ -46,5 +42,8 @@ int main( int argc, char * argv[] ) hb_vmInit(); hb_vmQuit(); + /* NOTE: The exit value is set by _exit() */ + /* NOTE: This point is never reached */ + return 0; } diff --git a/harbour/source/vm/mainwin.c b/harbour/source/vm/mainwin.c index d3cf2815af..75cb3ae882 100644 --- a/harbour/source/vm/mainwin.c +++ b/harbour/source/vm/mainwin.c @@ -39,7 +39,8 @@ void hb_cmdargInit( int argc, char * argv[] ); void hb_vmInit( void ); void hb_vmQuit( void ); -HANDLE hb_g_hInstance = 0, hb_g_hPrevInstance = 0; +HANDLE hb_g_hInstance = 0; +HANDLE hb_g_hPrevInstance = 0; int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ HINSTANCE hPrevInstance, /* handle to previous instance */ @@ -55,6 +56,7 @@ int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ hb_vmQuit(); /* NOTE: The exit value is set by _exit() */ + /* NOTE: This point is never reached */ return 0; } diff --git a/harbour/tests/rtl_test.prg b/harbour/tests/rtl_test.prg index 8c7ea7bf1e..8189eb58aa 100644 --- a/harbour/tests/rtl_test.prg +++ b/harbour/tests/rtl_test.prg @@ -298,6 +298,8 @@ STATIC FUNCTION Main_HVM() /* (operators) */ + /* <= */ + TEST_LINE( 2 <= 1 , .F. ) TEST_LINE( 1 <= 2 , .T. ) TEST_LINE( 2.0 <= 2 , .T. ) @@ -319,6 +321,9 @@ STATIC FUNCTION Main_HVM() TEST_LINE( "A" <= "Z" , .T. ) TEST_LINE( "Z" <= " " , .F. ) TEST_LINE( Chr(0) <= " " , .T. ) + + /* < */ + TEST_LINE( 2 < 1 , .F. ) TEST_LINE( 1 < 2 , .T. ) TEST_LINE( 2.0 < 2 , .F. ) @@ -340,6 +345,9 @@ STATIC FUNCTION Main_HVM() TEST_LINE( "A" < "Z" , .T. ) TEST_LINE( "Z" < "A" , .F. ) TEST_LINE( Chr(0) < " " , .T. ) + + /* >= */ + TEST_LINE( 2 >= 1 , .T. ) TEST_LINE( 1 >= 2 , .F. ) TEST_LINE( 2.0 >= 2 , .T. ) @@ -361,6 +369,9 @@ STATIC FUNCTION Main_HVM() TEST_LINE( "A" >= "Z" , .F. ) TEST_LINE( "Z" >= "A" , .T. ) TEST_LINE( Chr(0) >= " " , .F. ) + + /* > */ + TEST_LINE( 2 > 1 , .T. ) TEST_LINE( 1 > 2 , .F. ) TEST_LINE( 2.0 > 2 , .F. ) @@ -383,6 +394,174 @@ STATIC FUNCTION Main_HVM() TEST_LINE( "Z" > "A" , .T. ) TEST_LINE( Chr(0) > " " , .F. ) + /* =, == */ + + SET EXACT ON + TEST_LINE( "123" = "123 " , .T. ) + TEST_LINE( " 123" = "123" , .F. ) + TEST_LINE( "123" = "12345" , .F. ) + TEST_LINE( "12345" = "123" , .F. ) + TEST_LINE( "123" = "" , .F. ) + TEST_LINE( "" = "123" , .F. ) + TEST_LINE( "A" == "A" , .T. ) + TEST_LINE( "Z" == "A" , .F. ) + TEST_LINE( "A" == "A " , .F. ) + TEST_LINE( "AA" == "A" , .F. ) + SET EXACT OFF + TEST_LINE( "123" = "123 " , .F. ) + TEST_LINE( " 123" = "123" , .F. ) + TEST_LINE( "123" = "12345" , .F. ) + TEST_LINE( "12345" = "123" , .T. ) + TEST_LINE( "123" = "" , .T. ) + TEST_LINE( "" = "123" , .F. ) + TEST_LINE( "A" == "A" , .T. ) + TEST_LINE( "Z" == "A" , .F. ) + TEST_LINE( "A" == "A " , .F. ) + TEST_LINE( "AA" == "A" , .F. ) + + TEST_LINE( scString = scString , .T. ) + TEST_LINE( scString = scStringE , .T. ) + TEST_LINE( scString = scStringZ , .F. ) + TEST_LINE( scStringE = scString , .F. ) + TEST_LINE( scStringE = scStringE , .T. ) + TEST_LINE( scStringE = scStringZ , .F. ) + TEST_LINE( scStringZ = scString , .F. ) + TEST_LINE( scStringZ = scStringE , .T. ) + TEST_LINE( scStringZ = scStringZ , .T. ) + + /* != */ + + SET EXACT ON + TEST_LINE( "123" != "123 " , .F. ) + TEST_LINE( " 123" != "123" , .T. ) + TEST_LINE( "123" != "12345" , .T. ) + TEST_LINE( "12345" != "123" , .T. ) + TEST_LINE( "123" != "" , .T. ) + TEST_LINE( "" != "123" , .T. ) + TEST_LINE( "A" != "A" , .F. ) + TEST_LINE( "Z" != "A" , .T. ) + TEST_LINE( "A" != "A " , .F. ) + TEST_LINE( "AA" != "A" , .T. ) + SET EXACT OFF + TEST_LINE( "123" != "123 " , .T. ) + TEST_LINE( " 123" != "123" , .T. ) + TEST_LINE( "123" != "12345" , .T. ) + TEST_LINE( "12345" != "123" , .F. ) + TEST_LINE( "123" != "" , .F. ) + TEST_LINE( "" != "123" , .T. ) + TEST_LINE( "A" != "A" , .F. ) + TEST_LINE( "Z" != "A" , .T. ) + TEST_LINE( "A" != "A " , .T. ) + TEST_LINE( "AA" != "A" , .F. ) + + TEST_LINE( scString != scString , .F. ) + TEST_LINE( scString != scStringE , .F. ) + TEST_LINE( scString != scStringZ , .T. ) + TEST_LINE( scStringE != scString , .T. ) + TEST_LINE( scStringE != scStringE , .F. ) + TEST_LINE( scStringE != scStringZ , .T. ) + TEST_LINE( scStringZ != scString , .T. ) + TEST_LINE( scStringZ != scStringE , .F. ) + TEST_LINE( scStringZ != scStringZ , .F. ) + + /* == special */ + + TEST_LINE( NIL == NIL , .T. ) + TEST_LINE( scString == NIL , .F. ) + TEST_LINE( scString == 1 , "E BASE 1070 Argument error == F:S" ) + TEST_LINE( soObject == "" , "E BASE 1070 Argument error == F:S" ) + TEST_LINE( soObject == soObject , .T. ) + TEST_LINE( soObject == ErrorNew() , .F. ) + TEST_LINE( ErrorNew() == ErrorNew() , .F. ) + TEST_LINE( soObject == TBColumnNew() , .F. ) + TEST_LINE( saArray == saArray , .T. ) + TEST_LINE( {} == {} , .F. ) + TEST_LINE( {|| NIL } == {|| NIL } , "E BASE 1070 Argument error == F:S" ) + + /* = special */ + + TEST_LINE( NIL = NIL , .T. ) + TEST_LINE( scString = NIL , .F. ) + TEST_LINE( scString = 1 , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( soObject = "" , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( soObject = soObject , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( soObject = ErrorNew() , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( ErrorNew() = ErrorNew() , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( soObject = TBColumnNew() , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( saArray = saArray , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( {} = {} , "E BASE 1071 Argument error = F:S" ) + TEST_LINE( {|| NIL } = {|| NIL } , "E BASE 1071 Argument error = F:S" ) + + /* != special */ + + TEST_LINE( NIL != NIL , .F. ) + TEST_LINE( scString != NIL , .T. ) + TEST_LINE( scString != 1 , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( soObject != "" , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( soObject != soObject , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( soObject != ErrorNew() , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( ErrorNew() != ErrorNew() , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( soObject != TBColumnNew() , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( saArray != saArray , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( {} != {} , "E BASE 1072 Argument error <> F:S" ) + TEST_LINE( {|| NIL } != {|| NIL } , "E BASE 1072 Argument error <> F:S" ) + + /* < special */ + + TEST_LINE( NIL < NIL , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( scString < NIL , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( scString < 1 , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( soObject < "" , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( soObject < soObject , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( soObject < ErrorNew() , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( ErrorNew() < ErrorNew() , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( soObject < TBColumnNew() , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( saArray < saArray , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( {} < {} , "E BASE 1073 Argument error < F:S" ) + TEST_LINE( {|| NIL } < {|| NIL } , "E BASE 1073 Argument error < F:S" ) + + /* <= special */ + + TEST_LINE( NIL <= NIL , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( scString <= NIL , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( scString <= 1 , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( soObject <= "" , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( soObject <= soObject , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( soObject <= ErrorNew() , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( ErrorNew() <= ErrorNew() , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( soObject <= TBColumnNew() , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( saArray <= saArray , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( {} <= {} , "E BASE 1074 Argument error <= F:S" ) + TEST_LINE( {|| NIL } <= {|| NIL } , "E BASE 1074 Argument error <= F:S" ) + + /* > special */ + + TEST_LINE( NIL > NIL , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( scString > NIL , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( scString > 1 , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( soObject > "" , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( soObject > soObject , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( soObject > ErrorNew() , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( ErrorNew() > ErrorNew() , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( soObject > TBColumnNew() , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( saArray > saArray , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( {} > {} , "E BASE 1075 Argument error > F:S" ) + TEST_LINE( {|| NIL } > {|| NIL } , "E BASE 1075 Argument error > F:S" ) + + /* >= special */ + + TEST_LINE( NIL >= NIL , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( scString >= NIL , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( scString >= 1 , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( soObject >= "" , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( soObject >= soObject , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( soObject >= ErrorNew() , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( ErrorNew() >= ErrorNew() , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( soObject >= TBColumnNew() , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( saArray >= saArray , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( {} >= {} , "E BASE 1076 Argument error >= F:S" ) + TEST_LINE( {|| NIL } >= {|| NIL } , "E BASE 1076 Argument error >= F:S" ) + //NOTE: These expressions have to be written with no separators! TEST_LINE( mnIntP==10.or.mnIntP=0 , .T. ) TEST_LINE( mnIntP==10.and.mnLongP=0 , .F. ) @@ -526,60 +705,7 @@ STATIC FUNCTION Main_HVM() TEST_LINE( saArray[ "1" ] , "E BASE 1068 Argument error array access F:S" ) TEST_LINE( saArray[ "1" ] := 1 , "E BASE 1069 Argument error array assign " ) - TEST_LINE( scString > 1 , "E BASE 1075 Argument error > F:S" ) - TEST_LINE( scString >= 1 , "E BASE 1076 Argument error >= F:S" ) - TEST_LINE( scString <> 1 , "E BASE 1072 Argument error <> F:S" ) - - SET EXACT ON - TEST_LINE( "123" = "123 " , .T. ) - TEST_LINE( " 123" = "123" , .F. ) - TEST_LINE( "123" = "12345" , .F. ) - TEST_LINE( "12345" = "123" , .F. ) - TEST_LINE( "123" = "" , .F. ) - TEST_LINE( "" = "123" , .F. ) - TEST_LINE( "A" == "A" , .T. ) - TEST_LINE( "Z" == "A" , .F. ) - TEST_LINE( "A" == "A " , .F. ) - TEST_LINE( "AA" == "A" , .F. ) - SET EXACT OFF - TEST_LINE( "123" = "123 " , .F. ) - TEST_LINE( " 123" = "123" , .F. ) - TEST_LINE( "123" = "12345" , .F. ) - TEST_LINE( "12345" = "123" , .T. ) - TEST_LINE( "123" = "" , .T. ) - TEST_LINE( "" = "123" , .F. ) - TEST_LINE( "A" == "A" , .T. ) - TEST_LINE( "Z" == "A" , .F. ) - TEST_LINE( "A" == "A " , .F. ) - TEST_LINE( "AA" == "A" , .F. ) - TEST_LINE( scString = scString , .T. ) - TEST_LINE( scString = scStringE , .T. ) - TEST_LINE( scString = scStringZ , .F. ) - TEST_LINE( scStringE = scString , .F. ) - TEST_LINE( scStringE = scStringE , .T. ) - TEST_LINE( scStringE = scStringZ , .F. ) - TEST_LINE( scStringZ = scString , .F. ) - TEST_LINE( scStringZ = scStringE , .T. ) - TEST_LINE( scStringZ = scStringZ , .T. ) - - TEST_LINE( scString == 1 , "E BASE 1070 Argument error == F:S" ) - TEST_LINE( soObject == soObject , .T. ) - TEST_LINE( soObject = soObject , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( soObject == ErrorNew() , .F. ) - TEST_LINE( soObject = ErrorNew() , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( ErrorNew() == ErrorNew() , .F. ) - TEST_LINE( ErrorNew() = ErrorNew() , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( soObject == TBColumnNew() , .F. ) - TEST_LINE( soObject = TBColumnNew() , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( saArray == saArray , .T. ) - TEST_LINE( saArray = saArray , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( {} == {} , .F. ) - TEST_LINE( {} = {} , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( {|| NIL } == {|| NIL } , "E BASE 1070 Argument error == F:S" ) - TEST_LINE( {|| NIL } = {|| NIL } , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( scString = 1 , "E BASE 1071 Argument error = F:S" ) - TEST_LINE( scString < 1 , "E BASE 1073 Argument error < F:S" ) - TEST_LINE( scString <= 1 , "E BASE 1074 Argument error <= F:S" ) + /* Alias */ TEST_LINE( ("NOTHERE")->NOFIELD , "E BASE 1002 Alias does not exist NOTHERE F:R" ) TEST_LINE( (mcString)->NOFIELD , "E BASE 1002 Alias does not exist HELLO F:R" )