diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 2dd07f603d..e188066a7f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,12 @@ +19990520-19:35 EST David G. Holm + Thanks go to "Victor Szel" + * source/compiler/harbour.l + - Saves number of decimal places in double constants + * source/compiler/harbour.y + - Includes number of decimal places when creating pcode for _PUSHDOUBLE + * source/vm/hvm.c + - Pcode for _PUSHDOUBLE extracts number of decimal places + Thu May 20 16:03:24 1999 Gonzalo A. Diethelm * source/rtl/dates.c: diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index 8f478c1b58..1a256286f7 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -717,25 +717,33 @@ Separator {SpaceTab}|{Comment}|{LineCont} {InvalidNumber} GenError( ERR_NUMERIC_FORMAT, NULL, NULL ); -{Number} { yylval.dNumber = atof( yytext ); - if( strchr( yytext, '.' ) ) +{Number} { char * ptr; + yylval.dNum.dNumber = atof( yytext ); + ptr = strchr( yytext, '.' ); + if( ptr ) + { + yylval.dNum.bDec = strlen( ptr + 1 ); return DOUBLE; + } else { - if( ( double )SHRT_MIN <= yylval.dNumber && - yylval.dNumber <= ( double )SHRT_MAX ) + if( ( double )SHRT_MIN <= yylval.dNum.dNumber && + yylval.dNum.dNumber <= ( double )SHRT_MAX ) { - yylval.iNumber = ( int ) yylval.dNumber; + yylval.iNumber = ( int ) yylval.dNum.dNumber; return INTEGER; } - else if( ( double )LONG_MIN <= yylval.dNumber && - yylval.dNumber <= ( double )LONG_MAX ) + else if( ( double )LONG_MIN <= yylval.dNum.dNumber && + yylval.dNum.dNumber <= ( double )LONG_MAX ) { - yylval.lNumber = ( long ) yylval.dNumber; + yylval.lNumber = ( long ) yylval.dNum.dNumber; return INTLONG; } else + { + yylval.dNum.bDec = 0; return DOUBLE; + } } } @@ -755,7 +763,8 @@ Separator {SpaceTab}|{Comment}|{LineCont} } else { - yylval.dNumber = lNumber; + yylval.dNum.dNumber = lNumber; + yylval.dNum.bDec = 0; return DOUBLE; } } diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 0df8db0344..7907be4e9c 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -166,7 +166,7 @@ void Line( void ); /* generates the pcode with the currentl void LineBody( void ); /* generates the pcode with the currently compiled source code line */ void Message( char * szMsgName ); /* sends a message to an object */ void PopId( char * szVarName ); /* generates the pcode to pop a value from the virtual machine stack onto a variable */ -void PushDouble( double fNumber ); /* Pushes a number on the virtual machine stack */ +void PushDouble( double fNumber, BYTE bDec ); /* Pushes a number on the virtual machine stack */ void PushId( char * szVarName ); /* generates the pcode to push a variable value to the virtual machine stack */ void PushIdByRef( char * szVarName ); /* generates the pcode to push a variable by reference to the virtual machine stack */ void PushInteger( int iNumber ); /* Pushes a integer number on the virtual machine stack */ @@ -375,7 +375,11 @@ PATHNAMES *_pIncludePath = NULL; char * string; /* to hold a string returned by lex */ int iNumber; /* to hold a number returned by lex */ long lNumber; /* to hold a long number returned by lex */ - double dNumber; /* to hold a double number returned by lex */ + struct + { + double dNumber; /* to hold a double number returned by lex */ + unsigned char bDec; /* to hold the number of decimal points in the value */ + } dNum; void * pVoid; /* to hold any memory structure we may need */ }; @@ -414,8 +418,8 @@ PATHNAMES *_pIncludePath = NULL; /*the highest precedence*/ %type IDENTIFIER LITERAL FunStart MethStart IdSend -%type DOUBLE ObjectData -%type ArgList ElemList ExpList FunCall FunScope IncDec Logical Params ParamList +%type DOUBLE ObjectData +%type ArgList ElemList ExpList FunCall FunScope IncDec Logical Params ParamList %type INTEGER BlockExpList Argument IfBegin VarId VarList MethParams ObjFunCall %type MethCall BlockList FieldList %type INTLONG WhileBegin BlockBegin @@ -561,7 +565,7 @@ ObjFunCall : FunCall ':' { Function( $1 ); $$ = $1; } ; Expression : NIL { PushNil(); } - | DOUBLE { PushDouble( $1 ); } + | DOUBLE { PushDouble( $1.dNumber,$1.bDec ); } | INTEGER { PushInteger( $1 ); } | INTLONG { PushLong( $1 ); } | LITERAL { PushString( $1 ); } @@ -2213,11 +2217,12 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag int i; ++lPCodePos; fprintf( yyc, " _PUSHDOUBLE, " ); - for( i = 0; i < sizeof( double ); ++i ) + for( i = 0; i < sizeof( double ) + sizeof( BYTE ); ++i ) fprintf( yyc, "%i, ", ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ] ); - fprintf( yyc, "/* %f */\n", + fprintf( yyc, "/* %.*f, %d */\n", + *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ), *( ( double * ) &( pFunc->pCode[ lPCodePos ] ) ) ); - lPCodePos += sizeof( double ); + lPCodePos += sizeof( double ) + sizeof( BYTE ); } break; @@ -2909,15 +2914,11 @@ void PushNil( void ) } /* generates the pcode to push a double number on the virtual machine stack */ -void PushDouble( double dNumber ) +void PushDouble( double dNumber, BYTE bDec ) { - if( dNumber ) - { - GenPCode1( _PUSHDOUBLE ); - GenPCodeN( ( BYTE * ) &dNumber, sizeof( double ) ); - } - else - GenPCode1( _ZERO ); + GenPCode1( _PUSHDOUBLE ); + GenPCodeN( ( BYTE * ) &dNumber, sizeof( double ) ); + GenPCode1( bDec ); } /* generates the pcode to push a integer number on the virtual machine stack */ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 072bcb8f82..21cc9d1e67 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -469,8 +469,8 @@ void VirtualMachine( PBYTE pCode, PSYMBOL pSymbols ) break; case _PUSHDOUBLE: - PushDouble( * ( double * ) ( &pCode[ w + 1 ] ), hb_set.HB_SET_DECIMALS ); - w += 1 + sizeof( double ); + PushDouble( * ( double * ) ( &pCode[ w + 1 ] ), ( WORD ) * ( BYTE * ) &pCode[ w + 1 + sizeof( double ) ] ); + w += 1 + sizeof( double ) + 1; break; case _PUSHINT: