19991005-18:02 GMT+1

This commit is contained in:
Viktor Szakats
1999-10-05 16:28:37 +00:00
parent 5f71da088b
commit 0b16eadcf8
11 changed files with 578 additions and 406 deletions

View File

@@ -1,3 +1,31 @@
19991005-18:02 GMT+1 Victor Szel <info@szelvesz.hu>
* 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 <info@szelvesz.hu>
* tests/run_tsta.bat
tests/test_all.prg

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 );

View File

@@ -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:

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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" )