2005-11-14 11:00 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
* include/hbcomp.h
* include/hberrors.h
* include/hbexpra.c
* include/hbexprb.c
* include/hbexprop.h
* include/hbhash.h
* include/hbmacro.h
* include/hbpcode.h
* source/common/Makefile
* source/common/expropt1.c
* source/common/expropt2.c
* source/common/hbhash.c
* source/compiler/expropta.c
* source/compiler/exproptb.c
* source/compiler/genc.c
* source/compiler/harbour.c
* source/compiler/harbour.l
* source/compiler/harbour.y
* source/compiler/hbfix.c
* source/compiler/hbgenerr.c
* source/compiler/hbident.c
* source/compiler/hbpcode.c
* source/macro/macro.l
* source/macro/macro.y
* source/macro/macroa.c
* source/macro/macrob.c
* source/rtl/dates.c
* source/vm/hvm.c
* source/vm/macro.c
+ source/common/hbdate.c
+ tests/ddate.prg
+ tests/switch.prg
+added support for DATE type constants in the following format:
0dYYYYMMDD
for example (see tests/ddate.prg for more):
IF( dDate > 0d20051112 )
+added support for SWITCH command (see tests/switch.prg)
SWITCH <expr>
CASE <integer_expression>
...
[EXIT]
CASE <string_expression>
...
[EXIT]
[OTHERWISE]
...
END
Notice:
- Integer and string expressions can be mixed in a single
SWITCH command with no runtime errors;
- CASE expression have to be resolved at compile time and
the result has to be either an integer or string constant
- if there is no EXIT statement then next CASE is executed
(or OTHERWISE for the last CASE)
For example:
CASE 1+32+2*4
CASE CHR(64)
CASE ASC('A')
CASE "A"+CHR(13)
Notice:
The above changes apply only to FLEX version!
This commit is contained in:
@@ -7,6 +7,74 @@
|
||||
For example:
|
||||
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2005-11-14 11:00 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
|
||||
* include/hbcomp.h
|
||||
* include/hberrors.h
|
||||
* include/hbexpra.c
|
||||
* include/hbexprb.c
|
||||
* include/hbexprop.h
|
||||
* include/hbhash.h
|
||||
* include/hbmacro.h
|
||||
* include/hbpcode.h
|
||||
* source/common/Makefile
|
||||
* source/common/expropt1.c
|
||||
* source/common/expropt2.c
|
||||
* source/common/hbhash.c
|
||||
* source/compiler/expropta.c
|
||||
* source/compiler/exproptb.c
|
||||
* source/compiler/genc.c
|
||||
* source/compiler/harbour.c
|
||||
* source/compiler/harbour.l
|
||||
* source/compiler/harbour.y
|
||||
* source/compiler/hbfix.c
|
||||
* source/compiler/hbgenerr.c
|
||||
* source/compiler/hbident.c
|
||||
* source/compiler/hbpcode.c
|
||||
* source/macro/macro.l
|
||||
* source/macro/macro.y
|
||||
* source/macro/macroa.c
|
||||
* source/macro/macrob.c
|
||||
* source/rtl/dates.c
|
||||
* source/vm/hvm.c
|
||||
* source/vm/macro.c
|
||||
+ source/common/hbdate.c
|
||||
+ tests/ddate.prg
|
||||
+ tests/switch.prg
|
||||
+added support for DATE type constants in the following format:
|
||||
0dYYYYMMDD
|
||||
for example (see tests/ddate.prg for more):
|
||||
IF( dDate > 0d20051112 )
|
||||
|
||||
+added support for SWITCH command (see tests/switch.prg)
|
||||
SWITCH <expr>
|
||||
CASE <integer_expression>
|
||||
...
|
||||
[EXIT]
|
||||
CASE <string_expression>
|
||||
...
|
||||
[EXIT]
|
||||
[OTHERWISE]
|
||||
...
|
||||
END
|
||||
|
||||
Notice:
|
||||
- Integer and string expressions can be mixed in a single
|
||||
SWITCH command with no runtime errors;
|
||||
- CASE expression have to be resolved at compile time and
|
||||
the result has to be either an integer or string constant
|
||||
- if there is no EXIT statement then next CASE is executed
|
||||
(or OTHERWISE for the last CASE)
|
||||
For example:
|
||||
CASE 1+32+2*4
|
||||
CASE CHR(64)
|
||||
CASE ASC('A')
|
||||
CASE "A"+CHR(13)
|
||||
|
||||
Notice:
|
||||
The above changes apply only to FLEX version!
|
||||
|
||||
|
||||
2005-11-13 21:21 UTC+0100 Jacek Kubica (kubica/at/wssk.wroc.pl)
|
||||
* harbour/contrib/ole/bldtest.bat
|
||||
* harbour/contrib/ole/hbtest.prg
|
||||
|
||||
@@ -380,6 +380,7 @@ extern void hb_compGenPushVarRef( char * szVarName ); /* generates the pcode
|
||||
extern void hb_compGenPushInteger( int iNumber ); /* Pushes a integer number on the virtual machine stack */
|
||||
extern void hb_compGenPushLogical( int iTrueFalse ); /* pushes a logical value on the virtual machine stack */
|
||||
extern void hb_compGenPushLong( HB_LONG lNumber ); /* Pushes a long number on the virtual machine stack */
|
||||
extern void hb_compGenPushDate( HB_LONG lNumber ); /* Pushes a date constant on the virtual machine stack */
|
||||
extern void hb_compGenPushNil( void ); /* Pushes nil on the virtual machine stack */
|
||||
extern void hb_compGenPushString( char * szText, ULONG ulLen ); /* Pushes a string on the virtual machine stack */
|
||||
extern void hb_compGenPushSymbol( char * szSymbolName, BOOL bFunction, BOOL bAlias ); /* Pushes a symbol on to the Virtual machine stack */
|
||||
@@ -534,6 +535,9 @@ extern USHORT hb_comp_wForCounter;
|
||||
extern USHORT hb_comp_wIfCounter;
|
||||
extern USHORT hb_comp_wWhileCounter;
|
||||
extern USHORT hb_comp_wCaseCounter;
|
||||
extern USHORT hb_comp_wSwitchCounter;
|
||||
extern BOOL hb_comp_long_optimize;
|
||||
extern BOOL hb_comp_bTextSubst;
|
||||
|
||||
extern char * hb_comp_szDeclaredFun;
|
||||
|
||||
|
||||
@@ -114,6 +114,9 @@ HB_EXTERN_BEGIN
|
||||
#define HB_COMP_ERR_OPTIMIZEDLOCAL_OUT_OF_RANGE 52
|
||||
#define HB_COMP_ERR_FORVAR_TOOMANY 53
|
||||
#define HB_COMP_ERR_FORVAR_DIFF 54
|
||||
#define HB_COMP_ERR_NOT_LITERAL_CASE 55
|
||||
#define HB_COMP_ERR_INVALID_STR 56
|
||||
#define HB_COMP_ERR_INVALID_DATE 57
|
||||
|
||||
#define HB_COMP_WARN_AMBIGUOUS_VAR 1
|
||||
#define HB_COMP_WARN_MEMVAR_ASSUMED 2
|
||||
|
||||
@@ -77,6 +77,7 @@ static BYTE s_PrecedTable[] = {
|
||||
HB_ET_NIL, /* HB_ET_NONE = 0, */
|
||||
HB_ET_NIL, /* HB_ET_NIL, */
|
||||
HB_ET_NIL, /* HB_ET_NUMERIC, */
|
||||
HB_ET_NIL, /* HB_ET_DATE, */
|
||||
HB_ET_NIL, /* HB_ET_STRING, */
|
||||
HB_ET_NIL, /* HB_ET_CODEBLOCK, */
|
||||
HB_ET_NIL, /* HB_ET_LOGICAL, */
|
||||
|
||||
@@ -123,6 +123,7 @@ HB_EXPR_PTR hb_compExprReduceIIF( HB_EXPR_PTR, HB_MACRO_DECL );
|
||||
static HB_EXPR_FUNC( hb_compExprUseDummy );
|
||||
static HB_EXPR_FUNC( hb_compExprUseNil );
|
||||
static HB_EXPR_FUNC( hb_compExprUseNumeric );
|
||||
static HB_EXPR_FUNC( hb_compExprUseDate );
|
||||
static HB_EXPR_FUNC( hb_compExprUseString );
|
||||
static HB_EXPR_FUNC( hb_compExprUseCodeblock );
|
||||
static HB_EXPR_FUNC( hb_compExprUseLogical );
|
||||
@@ -189,6 +190,7 @@ HB_EXPR_FUNC_PTR hb_comp_ExprTable[] = {
|
||||
hb_compExprUseDummy,
|
||||
hb_compExprUseNil,
|
||||
hb_compExprUseNumeric,
|
||||
hb_compExprUseDate,
|
||||
hb_compExprUseString,
|
||||
hb_compExprUseCodeblock,
|
||||
hb_compExprUseLogical,
|
||||
@@ -333,6 +335,38 @@ static HB_EXPR_FUNC( hb_compExprUseNumeric )
|
||||
return pSelf;
|
||||
}
|
||||
|
||||
/* actions for HB_ET_DATE expression
|
||||
*/
|
||||
static HB_EXPR_FUNC( hb_compExprUseDate )
|
||||
{
|
||||
switch( iMessage )
|
||||
{
|
||||
case HB_EA_REDUCE:
|
||||
break;
|
||||
case HB_EA_ARRAY_AT:
|
||||
hb_compErrorType( pSelf );
|
||||
break;
|
||||
case HB_EA_ARRAY_INDEX:
|
||||
hb_compErrorIndex( pSelf ); /* Date cannot be used as index element */
|
||||
break;
|
||||
case HB_EA_LVALUE:
|
||||
hb_compErrorLValue( pSelf );
|
||||
break;
|
||||
case HB_EA_PUSH_PCODE:
|
||||
HB_EXPR_PCODE1( hb_compGenPushDate, pSelf->value.asNum.lVal );
|
||||
break;
|
||||
case HB_EA_POP_PCODE:
|
||||
break;
|
||||
case HB_EA_PUSH_POP:
|
||||
case HB_EA_STATEMENT:
|
||||
hb_compWarnMeaningless( pSelf );
|
||||
case HB_EA_DELETE:
|
||||
break;
|
||||
}
|
||||
|
||||
return pSelf;
|
||||
}
|
||||
|
||||
/* actions for HB_ET_STRING expression
|
||||
*/
|
||||
static HB_EXPR_FUNC( hb_compExprUseString )
|
||||
@@ -358,7 +392,10 @@ static HB_EXPR_FUNC( hb_compExprUseString )
|
||||
|
||||
szDupl = hb_strupr( hb_strdup( pSelf->value.asString.string ) );
|
||||
HB_EXPR_PCODE2( hb_compGenPushString, pSelf->value.asString.string, pSelf->ulLength + 1 );
|
||||
|
||||
#if ! defined( HB_MACRO_SUPPORT )
|
||||
if( hb_comp_bTextSubst )
|
||||
{
|
||||
#endif
|
||||
bValidMacro = hb_compExprIsValidMacro( szDupl, &bUseTextSubst, HB_MACRO_PARAM );
|
||||
if( bUseTextSubst )
|
||||
{
|
||||
@@ -383,6 +420,9 @@ static HB_EXPR_FUNC( hb_compExprUseString )
|
||||
}
|
||||
}
|
||||
}
|
||||
#if ! defined( HB_MACRO_SUPPORT )
|
||||
}
|
||||
#endif
|
||||
hb_xfree( szDupl );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -70,6 +70,7 @@ HB_EXTERN_BEGIN
|
||||
#define HB_EV_SYMBOL 128
|
||||
#define HB_EV_VARREF 256
|
||||
#define HB_EV_FUNREF 512
|
||||
#define HB_EV_DATE 1024
|
||||
|
||||
/* messages sent to expressions
|
||||
*/
|
||||
@@ -114,6 +115,7 @@ typedef enum
|
||||
HB_ET_NONE = 0,
|
||||
HB_ET_NIL,
|
||||
HB_ET_NUMERIC,
|
||||
HB_ET_DATE,
|
||||
HB_ET_STRING,
|
||||
HB_ET_CODEBLOCK,
|
||||
HB_ET_LOGICAL,
|
||||
@@ -308,6 +310,7 @@ HB_EXPR_PTR hb_compExprNewEmpty( void );
|
||||
HB_EXPR_PTR hb_compExprNewNil( void );
|
||||
HB_EXPR_PTR hb_compExprNewDouble( double, BYTE, BYTE );
|
||||
HB_EXPR_PTR hb_compExprNewLong( HB_LONG );
|
||||
HB_EXPR_PTR hb_compExprNewDate( HB_LONG );
|
||||
HB_EXPR_PTR hb_compExprNewString( char * );
|
||||
HB_EXPR_PTR hb_compExprNewLogical( int );
|
||||
HB_EXPR_PTR hb_compExprNewSelf( void );
|
||||
@@ -371,8 +374,12 @@ void hb_compExprClear( HB_EXPR_PTR );
|
||||
char * hb_compExprDescription( HB_EXPR_PTR );
|
||||
int hb_compExprType( HB_EXPR_PTR );
|
||||
int hb_compExprIsInteger( HB_EXPR_PTR );
|
||||
int hb_compExprIsLong( HB_EXPR_PTR );
|
||||
int hb_compExprAsInteger( HB_EXPR_PTR );
|
||||
int hb_compExprIsString( HB_EXPR_PTR );
|
||||
int hb_compExprAsStringLen( HB_EXPR_PTR );
|
||||
char *hb_compExprAsString( HB_EXPR_PTR );
|
||||
char *hb_compExprAsSymbol( HB_EXPR_PTR );
|
||||
|
||||
void hb_compExprFree( HB_EXPR_PTR, HB_MACRO_DECL );
|
||||
void hb_compExprErrorType( HB_EXPR_PTR, HB_MACRO_DECL );
|
||||
|
||||
@@ -57,13 +57,16 @@
|
||||
|
||||
HB_EXTERN_BEGIN
|
||||
|
||||
#define HB_HASH_FUNC( hbfunc ) ULONG hbfunc( void *Value, void *Cargo )
|
||||
struct HB_HASH_TABLE_;
|
||||
|
||||
#define HB_HASH_FUNC( hbfunc ) ULONG hbfunc( struct HB_HASH_TABLE_ *HashPtr, void *Value, void *Cargo )
|
||||
typedef HB_HASH_FUNC( HB_HASH_FUNC_ );
|
||||
typedef HB_HASH_FUNC_ *HB_HASH_FUNC_PTR;
|
||||
|
||||
typedef struct HB_HASH_ITEM_
|
||||
{
|
||||
void *cargo; /* value stored in the hash table */
|
||||
void *ValPtr; /* value stored in the hash table */
|
||||
void *KeyPtr;
|
||||
ULONG key;
|
||||
struct HB_HASH_ITEM_ *next;
|
||||
} HB_HASH_ITEM, *HB_HASH_ITEM_PTR;
|
||||
@@ -79,13 +82,14 @@ typedef struct HB_HASH_TABLE_
|
||||
HB_HASH_FUNC_PTR pCompFunc; /* ptr to func that compares two itmes */
|
||||
} HB_HASH_TABLE, *HB_HASH_TABLE_PTR;
|
||||
|
||||
|
||||
extern HB_HASH_TABLE_PTR hb_hashTableCreate( ULONG ulSize,
|
||||
HB_HASH_FUNC_PTR pHashFunc,
|
||||
HB_HASH_FUNC_PTR pDelete,
|
||||
HB_HASH_FUNC_PTR pComp );
|
||||
extern void hb_hashTableKill( HB_HASH_TABLE_PTR pTable ); /* release all items and the hash table */
|
||||
extern BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pValue ); /* add a new item into the table */
|
||||
extern void * hb_hashTableFind( HB_HASH_TABLE_PTR pTable, void *pValue ); /* return the pointer to item's value or NULL if not found */
|
||||
extern BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pKey, void *pValue ); /* add a new item into the table */
|
||||
extern void * hb_hashTableFind( HB_HASH_TABLE_PTR pTable, void *pKey ); /* return the pointer to item's value or NULL if not found */
|
||||
extern HB_HASH_TABLE_PTR hb_hashTableResize( HB_HASH_TABLE_PTR pTable, ULONG ulNewSize ); /* resize the hash table */
|
||||
|
||||
HB_EXTERN_END
|
||||
|
||||
@@ -133,6 +133,7 @@ extern ULONG hb_compGenJumpTrue( LONG lOffset, HB_BISON_PTR pMacro );
|
||||
extern void hb_compMemvarGenPCode( BYTE bPCode, char * szVarName, HB_BISON_PTR pMacro );
|
||||
extern void hb_compGenPushSymbol( char * szSymbolName, BOOL bFunction, BOOL bAlias, HB_BISON_PTR pMacro );
|
||||
extern void hb_compGenPushLong( HB_LONG lNumber, HB_BISON_PTR pMacro );
|
||||
extern void hb_compGenPushDate( HB_LONG lNumber, HB_BISON_PTR pMacro );
|
||||
extern void hb_compGenMessage( char * szMsgName, HB_BISON_PTR pMacro );
|
||||
extern void hb_compGenMessageData( char * szMsg, HB_BISON_PTR pMacro );
|
||||
extern void hb_compGenPopVar( char * szVarName, HB_BISON_PTR pMacro );
|
||||
|
||||
@@ -196,8 +196,10 @@ typedef enum
|
||||
HB_P_ENUMNEXT, /* 129 Next item of FOR EACH loop */
|
||||
HB_P_ENUMPREV, /* 130 Previous item of FOR EACH loop */
|
||||
HB_P_ENUMEND, /* 131 End of FOR EACH loop */
|
||||
HB_P_SWITCH, /* 132 SWITCH using long values */
|
||||
HB_P_PUSHDATE, /* 133 SWITCH using long values */
|
||||
/* NOTE: This have to be the last definition */
|
||||
HB_P_LAST_PCODE /* 132 this defines the number of defined pcodes */
|
||||
HB_P_LAST_PCODE /* 134 this defines the number of defined pcodes */
|
||||
} HB_PCODE;
|
||||
|
||||
#endif /* HB_PCODE_H_ */
|
||||
|
||||
@@ -10,6 +10,7 @@ C_SOURCES=\
|
||||
hbgete.c \
|
||||
hbhash.c \
|
||||
hbstr.c \
|
||||
hbdate.c \
|
||||
hbtrace.c \
|
||||
hbver.c \
|
||||
hbverdsp.c \
|
||||
|
||||
@@ -76,6 +76,7 @@ static char * s_OperTable[] = {
|
||||
"",
|
||||
"NIL",
|
||||
"Numeric",
|
||||
"Date",
|
||||
"String",
|
||||
"Codeblock",
|
||||
"Logical",
|
||||
@@ -192,12 +193,50 @@ HB_EXPR_PTR hb_compExprNewLong( HB_LONG lValue )
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
HB_EXPR_PTR hb_compExprNewDate( HB_LONG lValue )
|
||||
{
|
||||
HB_EXPR_PTR pExpr;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewDate(%" PFHL "d)", lValue));
|
||||
|
||||
pExpr = hb_compExprNew( HB_ET_DATE );
|
||||
|
||||
pExpr->value.asNum.lVal = lValue;
|
||||
pExpr->ValType = HB_EV_DATE;
|
||||
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
int hb_compExprIsInteger( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
return ( pExpr->ExprType == HB_ET_NUMERIC && pExpr->value.asNum.NumType == HB_ET_LONG &&
|
||||
HB_LIM_INT16( pExpr->value.asNum.lVal ) );
|
||||
}
|
||||
|
||||
int hb_compExprIsLong( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
return ( pExpr->ExprType == HB_ET_NUMERIC && pExpr->value.asNum.NumType == HB_ET_LONG );
|
||||
}
|
||||
|
||||
int hb_compExprIsString( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
return ( pExpr->ExprType == HB_ET_STRING );
|
||||
}
|
||||
|
||||
char * hb_compExprAsString( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
if( pExpr->ExprType == HB_ET_STRING )
|
||||
return pExpr->value.asString.string;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hb_compExprAsStringLen( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
if( pExpr->ExprType == HB_ET_STRING )
|
||||
return pExpr->ulLength;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hb_compExprAsInteger( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
if( pExpr->ExprType == HB_ET_NUMERIC && pExpr->value.asNum.NumType == HB_ET_LONG )
|
||||
@@ -206,7 +245,15 @@ int hb_compExprAsInteger( HB_EXPR_PTR pExpr )
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *hb_compExprAsString( HB_EXPR_PTR pExpr )
|
||||
long hb_compExprAsLong( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
if( pExpr->ExprType == HB_ET_NUMERIC && pExpr->value.asNum.NumType == HB_ET_LONG )
|
||||
return pExpr->value.asNum.lVal;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *hb_compExprAsSymbol( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
switch( pExpr->ExprType )
|
||||
{
|
||||
|
||||
@@ -335,6 +335,31 @@ HB_EXPR_PTR hb_compExprReduceMinus( HB_EXPR_PTR pSelf, HB_MACRO_DECL )
|
||||
hb_compExprFree( pLeft, HB_MACRO_PARAM );
|
||||
hb_compExprFree( pRight, HB_MACRO_PARAM );
|
||||
}
|
||||
else if( pLeft->ExprType == HB_ET_DATE && pRight->ExprType == HB_ET_DATE )
|
||||
{
|
||||
pSelf->value.asNum.lVal = pLeft->value.asNum.lVal - pRight->value.asNum.lVal;
|
||||
pSelf->value.asNum.bDec = 0;
|
||||
pSelf->value.asNum.NumType = HB_ET_LONG;
|
||||
pSelf->ExprType = HB_ET_NUMERIC;
|
||||
pSelf->ValType = HB_EV_NUMERIC;
|
||||
hb_compExprFree( pLeft, HB_MACRO_PARAM );
|
||||
hb_compExprFree( pRight, HB_MACRO_PARAM );
|
||||
}
|
||||
else if( pLeft->ExprType == HB_ET_DATE && pRight->ExprType == HB_ET_NUMERIC )
|
||||
{
|
||||
if( pRight->value.asNum.NumType == HB_ET_LONG )
|
||||
{
|
||||
pSelf->value.asNum.lVal = pLeft->value.asNum.lVal - pRight->value.asNum.lVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSelf->value.asNum.lVal = pLeft->value.asNum.lVal - pRight->value.asNum.dVal;
|
||||
}
|
||||
pSelf->ExprType = HB_ET_DATE;
|
||||
pSelf->ValType = HB_EV_DATE;
|
||||
hb_compExprFree( pLeft, HB_MACRO_PARAM );
|
||||
hb_compExprFree( pRight, HB_MACRO_PARAM );
|
||||
}
|
||||
else if( pLeft->ExprType == HB_ET_STRING && pRight->ExprType == HB_ET_STRING )
|
||||
{
|
||||
/* TODO:
|
||||
@@ -445,6 +470,21 @@ HB_EXPR_PTR hb_compExprReducePlus( HB_EXPR_PTR pSelf, HB_MACRO_DECL )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( pLeft->ExprType == HB_ET_DATE && pRight->ExprType == HB_ET_NUMERIC )
|
||||
{
|
||||
if( pRight->value.asNum.NumType == HB_ET_LONG )
|
||||
{
|
||||
pSelf->value.asNum.lVal = pLeft->value.asNum.lVal + pRight->value.asNum.lVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSelf->value.asNum.lVal = pLeft->value.asNum.lVal + pRight->value.asNum.dVal;
|
||||
}
|
||||
pSelf->ExprType = HB_ET_DATE;
|
||||
pSelf->ValType = HB_EV_DATE;
|
||||
hb_compExprFree( pLeft, HB_MACRO_PARAM );
|
||||
hb_compExprFree( pRight, HB_MACRO_PARAM );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: Check for incompatible types e.g. "txt" + 3
|
||||
|
||||
170
harbour/source/common/hbdate.c
Normal file
170
harbour/source/common/hbdate.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Harbour Project source code:
|
||||
* The Date conversion module
|
||||
*
|
||||
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
|
||||
* www - http://www.harbour-project.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
||||
*
|
||||
* As a special exception, the Harbour Project gives permission for
|
||||
* additional uses of the text contained in its release of Harbour.
|
||||
*
|
||||
* The exception is that, if you link the Harbour libraries with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the Harbour library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the Harbour
|
||||
* Project under the name Harbour. If you copy code from other
|
||||
* Harbour Project or Free Software Foundation releases into a copy of
|
||||
* Harbour, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for Harbour, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*
|
||||
* Copyright 1999-2001 Viktor Szakats <viktor.szakats@syenar.hu>
|
||||
* hb_dateEncStr()
|
||||
* hb_dateDecStr()
|
||||
* hb_dateStrPut()
|
||||
* hb_dateStrGet()
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hbapi.h"
|
||||
#include "hbdate.h"
|
||||
|
||||
#ifdef HB_C52_STRICT
|
||||
#define HB_DATE_YEAR_LIMIT 2999
|
||||
#else
|
||||
#define HB_DATE_YEAR_LIMIT 9999
|
||||
#endif
|
||||
|
||||
LONG HB_EXPORT hb_dateEncode( int iYear, int iMonth, int iDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateEncode(%d, %d, %d)", iYear, iMonth, iDay));
|
||||
|
||||
/* Perform date validation */
|
||||
if( iYear >= 1 && iYear <= HB_DATE_YEAR_LIMIT &&
|
||||
iMonth >= 1 && iMonth <= 12 &&
|
||||
iDay >= 1 )
|
||||
{
|
||||
/* Month, year, and lower day limits are simple,
|
||||
but upper day limit is dependent upon month and leap year */
|
||||
int auiDayLimit[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
if( ( ( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 ) )
|
||||
auiDayLimit[ 1 ] = 29;
|
||||
|
||||
if( iDay <= auiDayLimit[ iMonth - 1 ] )
|
||||
{
|
||||
int iFactor = ( iMonth < 3 ) ? -1 : 0;
|
||||
|
||||
return ( ( LONG )( iFactor + 4800 + iYear ) * 1461 / 4 ) +
|
||||
( ( LONG )( iMonth - 2 - ( iFactor * 12 ) ) * 367 ) / 12 -
|
||||
( ( LONG )( ( iFactor + 4900 + iYear ) / 100 ) * 3 / 4 ) +
|
||||
( LONG ) iDay - 32075;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HB_EXPORT hb_dateDecode( LONG lJulian, int *piYear, int *piMonth, int *piDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateDecode(%ld, %p, %p, %p)", lJulian, piYear, piMonth, piDay));
|
||||
|
||||
if( lJulian > 0 )
|
||||
{
|
||||
LONG U, V, W, X;
|
||||
|
||||
lJulian += 68569;
|
||||
W = ( lJulian * 4 ) / 146097;
|
||||
lJulian -= ( ( 146097 * W ) + 3 ) / 4;
|
||||
X = 4000 * ( lJulian + 1 ) / 1461001;
|
||||
lJulian -= ( ( 1461 * X ) / 4 ) - 31;
|
||||
V = 80 * lJulian / 2447;
|
||||
U = V / 11;
|
||||
|
||||
*piYear = (int) ( X + U + ( W - 49 ) * 100 );
|
||||
*piMonth = (int) ( V + 2 - ( U * 12 ) );
|
||||
*piDay = (int) ( lJulian - ( 2447 * V / 80 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
*piYear =
|
||||
*piMonth =
|
||||
*piDay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HB_EXPORT hb_dateStrPut( char * szDate, int iYear, int iMonth, int iDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateStrPut(%p, %d, %d, %d)", szDate, iYear, iMonth, iDay));
|
||||
|
||||
if( iYear >= 0 && iMonth && iDay )
|
||||
{
|
||||
szDate[ 0 ] = ( ( iYear % 10000 ) / 1000 ) + '0';
|
||||
szDate[ 1 ] = ( ( iYear % 1000 ) / 100 ) + '0';
|
||||
szDate[ 2 ] = ( ( iYear % 100 ) / 10 ) + '0';
|
||||
szDate[ 3 ] = ( iYear % 10 ) + '0';
|
||||
|
||||
szDate[ 4 ] = ( iMonth / 10 ) + '0';
|
||||
szDate[ 5 ] = ( iMonth % 10 ) + '0';
|
||||
|
||||
szDate[ 6 ] = ( iDay / 10 ) + '0';
|
||||
szDate[ 7 ] = ( iDay % 10 ) + '0';
|
||||
}
|
||||
else if ( iYear || iMonth || iDay )
|
||||
memset( szDate, '0', 8 );
|
||||
else
|
||||
memset( szDate, ' ', 8 );
|
||||
}
|
||||
|
||||
void HB_EXPORT hb_dateStrGet( const char * szDate, int * piYear, int * piMonth, int * piDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateStrGet(%s, %p, %p, %p)", szDate, piYear, piMonth, piDay));
|
||||
|
||||
if( szDate && szDate[ 8 ] == '\0' )
|
||||
{
|
||||
/* Date string has correct length, so attempt to convert */
|
||||
*piYear = ( ( USHORT ) ( szDate[ 0 ] - '0' ) * 1000 ) +
|
||||
( ( USHORT ) ( szDate[ 1 ] - '0' ) * 100 ) +
|
||||
( ( USHORT ) ( szDate[ 2 ] - '0' ) * 10 ) +
|
||||
( USHORT ) ( szDate[ 3 ] - '0' );
|
||||
*piMonth = ( ( szDate[ 4 ] - '0' ) * 10 ) + ( szDate[ 5 ] - '0' );
|
||||
*piDay = ( ( szDate[ 6 ] - '0' ) * 10 ) + ( szDate[ 7 ] - '0' );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Date string missing or bad length, so force an empty date */
|
||||
*piYear =
|
||||
*piMonth =
|
||||
*piDay = 0;
|
||||
}
|
||||
}
|
||||
@@ -52,12 +52,13 @@
|
||||
|
||||
#include "hbhash.h"
|
||||
|
||||
static HB_HASH_ITEM_PTR hb_hashItemNew( ULONG ulKey, void * pValue )
|
||||
static HB_HASH_ITEM_PTR hb_hashItemNew( ULONG ulKey, void *pKey, void * pValue )
|
||||
{
|
||||
HB_HASH_ITEM_PTR pItem = (HB_HASH_ITEM_PTR) hb_xgrab( sizeof( HB_HASH_ITEM ) );
|
||||
|
||||
pItem->key = ulKey;
|
||||
pItem->cargo = pValue;
|
||||
pItem->KeyPtr = pKey;
|
||||
pItem->ValPtr = pValue;
|
||||
pItem->next = NULL;
|
||||
|
||||
return pItem;
|
||||
@@ -113,7 +114,7 @@ void hb_hashTableKill( HB_HASH_TABLE_PTR pTable )
|
||||
while( pItem )
|
||||
{
|
||||
if( pTable->pDeleteItemFunc )
|
||||
( pTable->pDeleteItemFunc )( pItem->cargo, NULL );
|
||||
( pTable->pDeleteItemFunc )( pTable, pItem->KeyPtr, pItem->ValPtr );
|
||||
pNext = pItem->next;
|
||||
hb_xfree( ( void * ) pItem );
|
||||
pItem = pNext;
|
||||
@@ -151,7 +152,7 @@ HB_HASH_TABLE_PTR hb_hashTableResize( HB_HASH_TABLE_PTR pTable, ULONG ulNewSize
|
||||
HB_HASH_ITEM_PTR pNewItem, pNext;
|
||||
|
||||
pNext = pItem->next;
|
||||
ulKey = ( pTable->pKeyFunc )( pItem->cargo, NULL );
|
||||
ulKey = ( pTable->pKeyFunc )( pNew, pItem->KeyPtr, pItem->ValPtr );
|
||||
pNewItem = pNew->pItems[ ulKey ];
|
||||
if( pNewItem )
|
||||
{
|
||||
@@ -179,22 +180,22 @@ HB_HASH_TABLE_PTR hb_hashTableResize( HB_HASH_TABLE_PTR pTable, ULONG ulNewSize
|
||||
}
|
||||
|
||||
/* add a new value into th ehash table */
|
||||
BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pValue )
|
||||
BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pKey, void *pValue )
|
||||
{
|
||||
ULONG ulKey;
|
||||
HB_HASH_ITEM_PTR pItem;
|
||||
|
||||
ulKey = ( pTable->pKeyFunc )( pValue, NULL );
|
||||
ulKey = ( pTable->pKeyFunc )( pTable, pKey, pValue );
|
||||
pItem = pTable->pItems[ ulKey ];
|
||||
if( pItem )
|
||||
{
|
||||
while( pItem->next )
|
||||
pItem = pItem->next;
|
||||
pItem->next = hb_hashItemNew( ulKey, pValue );
|
||||
pItem->next = hb_hashItemNew( ulKey, pKey, pValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
pTable->pItems[ ulKey ] = hb_hashItemNew( ulKey, pValue );
|
||||
pTable->pItems[ ulKey ] = hb_hashItemNew( ulKey, pKey, pValue );
|
||||
++pTable->ulUsed;
|
||||
}
|
||||
++pTable->ulCount;
|
||||
@@ -204,21 +205,21 @@ BOOL hb_hashTableAdd( HB_HASH_TABLE_PTR pTable, void *pValue )
|
||||
|
||||
/* return the pointer to item's value or NULL if not found
|
||||
*/
|
||||
void * hb_hashTableFind( HB_HASH_TABLE_PTR pTable, void *pValue )
|
||||
void * hb_hashTableFind( HB_HASH_TABLE_PTR pTable, void *pKey )
|
||||
{
|
||||
ULONG ulKey;
|
||||
HB_HASH_ITEM_PTR pItem;
|
||||
void * pFound = NULL;
|
||||
|
||||
ulKey = ( pTable->pKeyFunc )( pValue, NULL );
|
||||
ulKey = ( pTable->pKeyFunc )( pTable, pKey, NULL );
|
||||
pItem = pTable->pItems[ ulKey ];
|
||||
if( pItem )
|
||||
{
|
||||
while( pItem && (( pTable->pCompFunc )( pItem->cargo, pValue ) != 0) )
|
||||
while( pItem && (( pTable->pCompFunc )( pTable, pItem->KeyPtr, pKey ) != 0) )
|
||||
pItem = pItem->next;
|
||||
|
||||
if( pItem )
|
||||
pFound = pItem->cargo;
|
||||
pFound = pItem->ValPtr;
|
||||
}
|
||||
|
||||
return pFound;
|
||||
@@ -228,28 +229,38 @@ void * hb_hashTableFind( HB_HASH_TABLE_PTR pTable, void *pValue )
|
||||
* Returns TRUE if item was found and returns FALSE when passed item
|
||||
* is not stored in the table
|
||||
*/
|
||||
BOOL hb_hashTableDel( HB_HASH_TABLE_PTR pTable, void *pValue )
|
||||
BOOL hb_hashTableDel( HB_HASH_TABLE_PTR pTable, void *pKey )
|
||||
{
|
||||
ULONG ulKey;
|
||||
HB_HASH_ITEM_PTR pItem;
|
||||
HB_HASH_ITEM_PTR pPrev = NULL;
|
||||
BOOL bFound = FALSE;
|
||||
|
||||
ulKey = ( pTable->pKeyFunc )( pValue, NULL );
|
||||
ulKey = ( pTable->pKeyFunc )( pTable, pKey, NULL );
|
||||
if( ulKey > pTable->ulTableSize )
|
||||
return FALSE;
|
||||
|
||||
pItem = pTable->pItems[ ulKey ];
|
||||
while( pItem && !bFound )
|
||||
{
|
||||
if( ( pTable->pCompFunc )( pItem->cargo, pValue ) == 0 )
|
||||
if( ( pTable->pCompFunc )( pTable, pItem->KeyPtr, pKey ) == 0 )
|
||||
{
|
||||
if( pPrev )
|
||||
{
|
||||
pPrev->next = pItem->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTable->pItems[ ulKey ] = pItem->next;
|
||||
if( !pItem->next )
|
||||
{
|
||||
--pTable->ulUsed;
|
||||
pTable->pItems[ ulKey ] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( pTable->pDeleteItemFunc )
|
||||
( pTable->pDeleteItemFunc )( pTable, pItem->KeyPtr, pItem->ValPtr );
|
||||
hb_hashItemDelete( pItem );
|
||||
bFound = TRUE;
|
||||
--pTable->ulCount;
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
/* hbexpra.c is also included from ../macro/macro.c
|
||||
* However it produces a slighty different code if used in
|
||||
* macro compiler (there is an additional parameter passed to some functions)
|
||||
* 1.16 - ignore this magic number - this is used to force compilation
|
||||
* 1.17 - ignore this magic number - this is used to force compilation
|
||||
*/
|
||||
#include "hbexpra.c"
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
/* hbexprb.c is also included from ../macro/macro.c
|
||||
* However it produces a slighty different code if used in
|
||||
* macro compiler (there is an additional parameter passed to some functions)
|
||||
* 1.13 - ignore this magic number - this is used to force compilation
|
||||
* 1.14 - ignore this magic number - this is used to force compilation
|
||||
*/
|
||||
#include "hbexprb.c"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "hbcomp.h"
|
||||
#include "hbdate.h"
|
||||
|
||||
static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc );
|
||||
static void hb_compGenCCompact( PFUNCTION pFunc, FILE * yyc );
|
||||
@@ -1867,6 +1868,47 @@ static HB_GENC_FUNC( hb_p_enumend )
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HB_GENC_FUNC( hb_p_switch )
|
||||
{
|
||||
if( cargo->bVerbose )
|
||||
fprintf( cargo->yyc, "/* %05li */ ", lPCodePos );
|
||||
else
|
||||
fprintf( cargo->yyc, "\t" );
|
||||
|
||||
fprintf( cargo->yyc, "HB_P_SWITCH, %i, %i,", pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] );
|
||||
|
||||
if( cargo->bVerbose )
|
||||
{
|
||||
fprintf( cargo->yyc, "\t/* %i*/", HB_PCODE_MKSHORT( &( pFunc->pCode[ lPCodePos + 2 ] ) ) );
|
||||
}
|
||||
|
||||
fprintf( cargo->yyc, "\n" );
|
||||
return 3;
|
||||
}
|
||||
|
||||
static HB_GENC_FUNC( hb_p_pushdate )
|
||||
{
|
||||
|
||||
fprintf( cargo->yyc, "\tHB_P_PUSHDATE, %i, %i, %i, %i,",
|
||||
pFunc->pCode[ lPCodePos + 1 ],
|
||||
pFunc->pCode[ lPCodePos + 2 ],
|
||||
pFunc->pCode[ lPCodePos + 3 ],
|
||||
pFunc->pCode[ lPCodePos + 4 ] );
|
||||
if( cargo->bVerbose )
|
||||
{
|
||||
int year, month, day;
|
||||
char date[9];
|
||||
|
||||
hb_dateDecode( HB_PCODE_MKLONG( &( pFunc->pCode[ lPCodePos + 1 ] ) ), &year, &month, &day );
|
||||
hb_dateStrPut( date, year, month, day );
|
||||
date[8] = '\0';
|
||||
fprintf( cargo->yyc, "\t/* %s */", date );
|
||||
}
|
||||
fprintf( cargo->yyc, "\n" );
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
static HB_GENC_FUNC( hb_p_localnearaddint )
|
||||
{
|
||||
@@ -2025,7 +2067,9 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = {
|
||||
hb_p_enumstart,
|
||||
hb_p_enumnext,
|
||||
hb_p_enumprev,
|
||||
hb_p_enumend
|
||||
hb_p_enumend,
|
||||
hb_p_switch,
|
||||
hb_p_pushdate
|
||||
};
|
||||
|
||||
static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc )
|
||||
|
||||
@@ -2393,35 +2393,6 @@ void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo )
|
||||
{
|
||||
switch( pCode[ ( ULONG ) ( ulFrom - 1 ) ] )
|
||||
{
|
||||
/*
|
||||
case HB_P_JUMPNEAR :
|
||||
break;
|
||||
|
||||
case HB_P_JUMPTRUENEAR :
|
||||
break;
|
||||
|
||||
case HB_P_JUMPFALSENEAR :
|
||||
break;
|
||||
|
||||
case HB_P_JUMP :
|
||||
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPNEAR;
|
||||
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
|
||||
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
|
||||
break;
|
||||
|
||||
case HB_P_JUMPTRUE :
|
||||
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPTRUENEAR;
|
||||
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
|
||||
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
|
||||
break;
|
||||
|
||||
case HB_P_JUMPFALSE :
|
||||
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPFALSENEAR;
|
||||
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
|
||||
pCode[ ( ULONG ) ( ulFrom + 2 ) ] = HB_P_NOOP;
|
||||
break;
|
||||
*/
|
||||
|
||||
case HB_P_JUMPFAR :
|
||||
pCode[ ( ULONG ) ( ulFrom - 1 ) ] = HB_P_JUMPNEAR;
|
||||
pCode[ ( ULONG ) ( ulFrom + 1 ) ] = HB_P_NOOP;
|
||||
@@ -3211,30 +3182,59 @@ void hb_compGenPushFunCall( char * szFunName )
|
||||
/* generates the pcode to push a long number on the virtual machine stack */
|
||||
void hb_compGenPushLong( HB_LONG lNumber )
|
||||
{
|
||||
if( lNumber == 0 )
|
||||
hb_compGenPCode1( HB_P_ZERO );
|
||||
else if( lNumber == 1 )
|
||||
hb_compGenPCode1( HB_P_ONE );
|
||||
else if( HB_LIM_INT8( lNumber ) )
|
||||
hb_compGenPCode2( HB_P_PUSHBYTE, (BYTE) lNumber, TRUE );
|
||||
else if( HB_LIM_INT16( lNumber ) )
|
||||
hb_compGenPCode3( HB_P_PUSHINT, HB_LOBYTE( lNumber ), HB_HIBYTE( lNumber ), TRUE );
|
||||
else if( HB_LIM_INT32( lNumber ) )
|
||||
if( hb_comp_long_optimize )
|
||||
{
|
||||
BYTE pBuffer[ 5 ];
|
||||
pBuffer[ 0 ] = HB_P_PUSHLONG;
|
||||
HB_PUT_LE_UINT32( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
if( lNumber == 0 )
|
||||
hb_compGenPCode1( HB_P_ZERO );
|
||||
else if( lNumber == 1 )
|
||||
hb_compGenPCode1( HB_P_ONE );
|
||||
else if( HB_LIM_INT8( lNumber ) )
|
||||
hb_compGenPCode2( HB_P_PUSHBYTE, (BYTE) lNumber, TRUE );
|
||||
else if( HB_LIM_INT16( lNumber ) )
|
||||
hb_compGenPCode3( HB_P_PUSHINT, HB_LOBYTE( lNumber ), HB_HIBYTE( lNumber ), TRUE );
|
||||
else if( HB_LIM_INT32( lNumber ) )
|
||||
{
|
||||
BYTE pBuffer[ 5 ];
|
||||
pBuffer[ 0 ] = HB_P_PUSHLONG;
|
||||
HB_PUT_LE_UINT32( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE pBuffer[ 9 ];
|
||||
pBuffer[ 0 ] = HB_P_PUSHLONGLONG;
|
||||
HB_PUT_LE_UINT64( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE pBuffer[ 9 ];
|
||||
pBuffer[ 0 ] = HB_P_PUSHLONGLONG;
|
||||
HB_PUT_LE_UINT64( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
if( HB_LIM_INT32( lNumber ) )
|
||||
{
|
||||
BYTE pBuffer[ 5 ];
|
||||
pBuffer[ 0 ] = HB_P_PUSHLONG;
|
||||
HB_PUT_LE_UINT32( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE pBuffer[ 9 ];
|
||||
pBuffer[ 0 ] = HB_P_PUSHLONGLONG;
|
||||
HB_PUT_LE_UINT64( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hb_compGenPushDate( HB_LONG lNumber )
|
||||
{
|
||||
BYTE pBuffer[ 5 ];
|
||||
|
||||
pBuffer[ 0 ] = HB_P_PUSHDATE;
|
||||
HB_PUT_LE_UINT32( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), TRUE );
|
||||
}
|
||||
|
||||
/* generates the pcode to push a string on the virtual machine stack */
|
||||
void hb_compGenPushString( char * szText, ULONG ulStrLen )
|
||||
{
|
||||
|
||||
@@ -41,9 +41,11 @@
|
||||
#include "hbsetup.h" /* main configuration file */
|
||||
#include "hberrors.h"
|
||||
#include "hbdefs.h"
|
||||
#include "hbdate.h"
|
||||
|
||||
/* helper functions */
|
||||
static int yy_ConvertNumber( char * szBuffer );
|
||||
static int yy_ConvertDate( char * szBuffer );
|
||||
extern int hb_ppInsideTextBlock;
|
||||
extern BOOL hb_ppNestedLiteralString;
|
||||
|
||||
@@ -102,6 +104,7 @@ SpaceTab [ \t]+
|
||||
Number ([0-9]+)|([0-9]*\.[0-9]+)|(0x[0-9A-Fa-f]+)
|
||||
InvalidNumber [0-9]+\.
|
||||
Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+))
|
||||
Date 0d[0-9]{8}
|
||||
|
||||
MacroVar \&{Identifier}[\.]?
|
||||
MacroEnd \&{Identifier}\.([_a-zA-Z0-9]*)
|
||||
@@ -122,6 +125,7 @@ Separator {SpaceTab}
|
||||
%x NEXT_ BREAK_ CASE_ DO_ DOIDENT_ WHILE_ WITH_ END_ FIELD_
|
||||
%x FOR_ FOREACH_ FUNCTION_ IIF_ IF_ IN_ INIT_
|
||||
%x RETURN_ RECOVER_
|
||||
%x SWITCH_
|
||||
%x INVALIDNUM_ OTHERWISE_ PROCEDURE_
|
||||
%x DECLARE_ DECLARE_ID_
|
||||
|
||||
@@ -465,7 +469,7 @@ Separator {SpaceTab}
|
||||
BEGIN 0;
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
unput( yytext[ yyleng-2 ] );
|
||||
if( hb_comp_wCaseCounter == 0 )
|
||||
if( hb_comp_wCaseCounter == 0 && hb_comp_wSwitchCounter == 0 )
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_CASE, NULL, NULL );
|
||||
hb_comp_iState =CASE;
|
||||
return CASE;
|
||||
@@ -475,7 +479,7 @@ Separator {SpaceTab}
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
if( hb_comp_iState == LOOKUP )
|
||||
{ /* it is first item in the line */
|
||||
if( hb_comp_wCaseCounter == 0 )
|
||||
if( hb_comp_wCaseCounter == 0 && hb_comp_wSwitchCounter == 0 )
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_CASE, NULL, NULL );
|
||||
hb_comp_iState =CASE;
|
||||
return CASE;
|
||||
@@ -1208,7 +1212,7 @@ Separator {SpaceTab}
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
if( hb_comp_iState == LOOKUP )
|
||||
{ /* it is the first item in the line */
|
||||
if( hb_comp_wCaseCounter == 0 )
|
||||
if( hb_comp_wCaseCounter == 0 && hb_comp_wSwitchCounter == 0 )
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_CASE, NULL, NULL );
|
||||
hb_comp_iState = OTHERWISE;
|
||||
return OTHERWISE;
|
||||
@@ -1384,6 +1388,51 @@ Separator {SpaceTab}
|
||||
/* ************************************************************************ */
|
||||
%}
|
||||
"step" { hb_comp_iState = IDENTIFIER; return STEP; }
|
||||
%{
|
||||
/* ************************************************************************ */
|
||||
%}
|
||||
"switch" BEGIN SWITCH_;
|
||||
<SWITCH_>{Separator}* ;
|
||||
<SWITCH_>[\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "switch" */
|
||||
BEGIN 0;
|
||||
yylval.string = hb_compIdentifierNew( "SWITCH", TRUE );
|
||||
hb_comp_iState =IDENTIFIER;
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
return IDENTIFIER;
|
||||
}
|
||||
<SWITCH_>("+="|"-="|"->") { /* operators */
|
||||
BEGIN 0;
|
||||
yylval.string = hb_compIdentifierNew( "SWITCH", TRUE );
|
||||
hb_comp_iState =IDENTIFIER;
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
unput( yytext[ yyleng-2 ] );
|
||||
return IDENTIFIER;
|
||||
}
|
||||
<SWITCH_>("::") { /* send operators */
|
||||
BEGIN 0;
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
unput( yytext[ yyleng-2 ] );
|
||||
hb_comp_iState =DOSWITCH;
|
||||
return DOSWITCH;
|
||||
}
|
||||
<SWITCH_>(\n|.) { /* not operator */
|
||||
BEGIN 0;
|
||||
unput( yytext[ yyleng-1 ] );
|
||||
if( hb_comp_iState == LOOKUP )
|
||||
{ /* it is first item in the line */
|
||||
hb_comp_iState =DOSWITCH;
|
||||
return DOSWITCH;
|
||||
}
|
||||
else
|
||||
{ /* there is another item in line already */
|
||||
yylval.string = hb_compIdentifierNew( "SWITCH", TRUE );
|
||||
hb_comp_iState =IDENTIFIER;
|
||||
return IDENTIFIER;
|
||||
}
|
||||
}
|
||||
%{
|
||||
/* ************************************************************************ */
|
||||
%}
|
||||
"to" { hb_comp_iState = IDENTIFIER; return TO; }
|
||||
%{
|
||||
/* ************************************************************************ */
|
||||
@@ -1684,6 +1733,8 @@ Separator {SpaceTab}
|
||||
{TrueValue} { hb_comp_iState =RSEPARATOR; return TRUEVALUE; }
|
||||
{FalseValue} { hb_comp_iState =RSEPARATOR; return FALSEVALUE; }
|
||||
|
||||
{Date} { return yy_ConvertDate( yytext ); }
|
||||
|
||||
{MacroVar} {
|
||||
if( yytext[ yyleng-1 ] == '.' )
|
||||
yytext[ yyleng-1 ] = '\0';
|
||||
@@ -1765,3 +1816,14 @@ static int yy_ConvertNumber( char * szBuffer )
|
||||
return NUM_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
static int yy_ConvertDate( char * szBuffer )
|
||||
{
|
||||
int year, month, day;
|
||||
|
||||
hb_dateStrGet( szBuffer+2, &year, &month, &day );
|
||||
yylval.valLong.lNumber = hb_dateEncode( year, month, day );
|
||||
yylval.valLong.szValue = szBuffer;
|
||||
|
||||
return NUM_DATE;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ static void hb_compEnumStart( HB_EXPR_PTR pVars, HB_EXPR_PTR pExprs, int descend
|
||||
static void hb_compEnumNext( HB_EXPR_PTR pExpr, int descend );
|
||||
static void hb_compEnumEnd( HB_EXPR_PTR pExpr );
|
||||
|
||||
static void hb_compSwitchStart( void );
|
||||
static void hb_compSwitchAdd( HB_EXPR_PTR );
|
||||
static void hb_compSwitchEnd( void );
|
||||
|
||||
|
||||
#ifdef HARBOUR_YYDEBUG
|
||||
#define YYDEBUG 1 /* Parser debug information support */
|
||||
#endif
|
||||
@@ -114,6 +119,24 @@ typedef struct _LOOPEXIT
|
||||
struct _LOOPEXIT * pNext;
|
||||
} LOOPEXIT, * PTR_LOOPEXIT; /* support structure for EXIT and LOOP statements */
|
||||
|
||||
/* support structure for SWITCH statement */
|
||||
typedef struct _SWITCHCASE
|
||||
{
|
||||
ULONG ulOffset;
|
||||
HB_EXPR_PTR pExpr;
|
||||
struct _SWITCHCASE *pNext;
|
||||
} SWITCHCASE, * SWITCHCASE_PTR;
|
||||
|
||||
typedef struct _SWITCHCMD
|
||||
{
|
||||
ULONG ulOffset;
|
||||
int iCount;
|
||||
SWITCHCASE_PTR pCases;
|
||||
SWITCHCASE_PTR pLast;
|
||||
ULONG ulDefault;
|
||||
struct _SWITCHCMD *pPrev;
|
||||
} SWITCHCMD, *SWITCHCMD_PTR;
|
||||
|
||||
typedef struct HB_RTVAR_
|
||||
{
|
||||
HB_EXPR_PTR pVar;
|
||||
@@ -127,11 +150,15 @@ USHORT hb_comp_wForCounter = 0;
|
||||
USHORT hb_comp_wIfCounter = 0;
|
||||
USHORT hb_comp_wWhileCounter = 0;
|
||||
USHORT hb_comp_wCaseCounter = 0;
|
||||
USHORT hb_comp_wSwitchCounter= 0;
|
||||
BOOL hb_comp_long_optimize = TRUE;
|
||||
BOOL hb_comp_bTextSubst = TRUE;
|
||||
|
||||
char * hb_comp_buffer; /* yacc input buffer */
|
||||
|
||||
static PTR_LOOPEXIT hb_comp_pLoops = NULL;
|
||||
static HB_RTVAR_PTR hb_comp_rtvars = NULL;
|
||||
static SWITCHCMD_PTR hb_comp_pSwitch = NULL;
|
||||
|
||||
extern int hb_compLocalGetPos( char * szVarName ); /* returns the order + 1 of a local variable */
|
||||
|
||||
@@ -188,6 +215,8 @@ static void hb_compDebugStart( void ) { };
|
||||
%token PROCREQ GET
|
||||
%token CBSTART DOIDENT
|
||||
%token FOREACH DESCEND
|
||||
%token DOSWITCH
|
||||
%token NUM_DATE
|
||||
|
||||
/*the lowest precedence*/
|
||||
/*postincrement and postdecrement*/
|
||||
@@ -220,6 +249,7 @@ static void hb_compDebugStart( void ) { };
|
||||
%type <valDouble> NUM_DOUBLE
|
||||
%type <valInteger> NUM_INTEGER
|
||||
%type <valLong> NUM_LONG
|
||||
%type <valLong> NUM_DATE
|
||||
%type <iNumber> FunScope
|
||||
%type <iNumber> Params ParamList
|
||||
%type <iNumber> IfBegin VarList ExtVarList
|
||||
@@ -260,6 +290,8 @@ static void hb_compDebugStart( void ) { };
|
||||
%type <asExpr> PostOp
|
||||
%type <asExpr> ForVar ForList ForExpr
|
||||
%type <asCodeblock> CBSTART
|
||||
%type <asExpr> SwitchCases SwitchStart SwitchBegin SwitchDefault
|
||||
%type <asExpr> DateValue
|
||||
|
||||
%%
|
||||
|
||||
@@ -482,6 +514,14 @@ NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bWi
|
||||
| NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber ); }
|
||||
;
|
||||
|
||||
DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber );
|
||||
if( $1.lNumber == 0 )
|
||||
{
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_DATE, $1.szValue, NULL );
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
NumAlias : NUM_INTEGER ALIASOP { $$ = hb_compExprNewLong( $1.iNumber ); }
|
||||
| NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); }
|
||||
| NUM_DOUBLE ALIASOP { $$ = hb_compErrorAlias( hb_compExprNewDouble( $1.dNumber, $1.bWidth, $1.bDec ) ); }
|
||||
@@ -682,6 +722,7 @@ SendId : IdentName { $$ = $1; }
|
||||
|
||||
ObjectData : NumValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| NilValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| DateValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| LiteralValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| CodeBlock ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Logical ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
@@ -719,6 +760,7 @@ ObjectMethodAlias : ObjectMethod ALIASOP { $$ = $1; }
|
||||
SimpleExpression :
|
||||
NumValue
|
||||
| NilValue { $$ = $1; }
|
||||
| DateValue { $$ = $1; }
|
||||
| LiteralValue { $$ = $1; }
|
||||
| CodeBlock { $$ = $1; }
|
||||
| Logical { $$ = $1; }
|
||||
@@ -836,6 +878,7 @@ ExprAssign : NumValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $
|
||||
|
||||
ExprEqual : NumValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
||||
| NilValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
||||
| DateValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
||||
| LiteralValue '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
||||
| CodeBlock '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
||||
| Logical '=' Expression %prec INASSIGN { $$ = hb_compExprAssign( $1, $3 ); }
|
||||
@@ -1364,6 +1407,7 @@ ExecFlow : IfEndif
|
||||
| ForNext
|
||||
| BeginSeq
|
||||
| ForEach
|
||||
| DoSwitch
|
||||
;
|
||||
|
||||
IfEndif : IfBegin EndIf { hb_compGenJumpHere( $1 ); }
|
||||
@@ -1531,9 +1575,9 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */
|
||||
hb_compDebugStart();
|
||||
++hb_comp_wForCounter; /* 5 */
|
||||
$<asExpr>$ = hb_compExprGenStatement( hb_compExprAssign( $2, $4 ) );
|
||||
if( hb_compExprAsString($<asExpr>2) )
|
||||
if( hb_compExprAsSymbol($<asExpr>2) )
|
||||
{
|
||||
hb_compForStart( hb_compExprAsString($<asExpr>2), FALSE );
|
||||
hb_compForStart( hb_compExprAsSymbol($<asExpr>2), FALSE );
|
||||
}
|
||||
}
|
||||
TO Expression StepExpr /* 6 7 8 */
|
||||
@@ -1571,7 +1615,7 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */
|
||||
iStep = 1;
|
||||
}
|
||||
|
||||
if( iStep && ( iLocal = hb_compLocalGetPos( hb_compExprAsString($<asExpr>2) ) ) > 0 && iLocal < 256 )
|
||||
if( iStep && ( iLocal = hb_compLocalGetPos( hb_compExprAsSymbol($<asExpr>2) ) ) > 0 && iLocal < 256 )
|
||||
{
|
||||
hb_compGenPCode4( HB_P_LOCALNEARADDINT, ( BYTE ) iLocal, HB_LOBYTE( iStep ), HB_HIBYTE( iStep ), ( BOOL ) 0 );
|
||||
}
|
||||
@@ -1587,9 +1631,9 @@ ForNext : FOR LValue ForAssign Expression /* 1 2 3 4 */
|
||||
hb_compGenJump( $<lNumber>9 - hb_comp_functions.pLast->lPCodePos );
|
||||
hb_compGenJumpHere( $<lNumber>11 );
|
||||
hb_compLoopEnd();
|
||||
if( hb_compExprAsString($<asExpr>2) )
|
||||
if( hb_compExprAsSymbol($<asExpr>2) )
|
||||
{
|
||||
hb_compForEnd( hb_compExprAsString($<asExpr>2) );
|
||||
hb_compForEnd( hb_compExprAsSymbol($<asExpr>2) );
|
||||
}
|
||||
hb_compExprDelete( $7 );
|
||||
hb_compExprDelete( $<asExpr>5 ); /* deletes $5, $2, $4 */
|
||||
@@ -1665,6 +1709,68 @@ Descend : /* default up */ { $$ = 1; }
|
||||
| DESCEND { $$ = -1; }
|
||||
;
|
||||
|
||||
DoSwitch : SwitchBegin
|
||||
{
|
||||
hb_compLoopStart();
|
||||
hb_compSwitchStart();
|
||||
hb_compGenJump( 0 );
|
||||
}
|
||||
SwitchCases
|
||||
EndSwitch
|
||||
{
|
||||
hb_compSwitchEnd();
|
||||
hb_compLoopEnd();
|
||||
}
|
||||
|
||||
| SwitchBegin
|
||||
EndSwitch
|
||||
{
|
||||
hb_compGenPData1( HB_P_POP );
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
EndSwitch : END
|
||||
{
|
||||
--hb_comp_wSwitchCounter;
|
||||
hb_comp_functions.pLast->bFlags &= ~ ( FUN_WITH_RETURN | FUN_BREAK_CODE );
|
||||
}
|
||||
;
|
||||
|
||||
SwitchStart : DOSWITCH
|
||||
{ ++hb_comp_wSwitchCounter;
|
||||
hb_compLinePush();
|
||||
}
|
||||
Expression Crlf
|
||||
{
|
||||
hb_compExprDelete( hb_compExprGenPush( $3 ) );
|
||||
}
|
||||
;
|
||||
|
||||
SwitchBegin : SwitchStart { }
|
||||
| SwitchStart Statements {
|
||||
if( $<lNumber>2 > 0 )
|
||||
{
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_MAYHEM_IN_CASE, NULL, NULL );
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
SwitchCases : CASE Expression { hb_compSwitchAdd( $2 ); hb_compLinePush(); } Crlf
|
||||
EmptyStats
|
||||
|
||||
| SwitchCases CASE Expression { hb_compSwitchAdd( $3 ); hb_compLinePush(); }Crlf
|
||||
EmptyStats
|
||||
|
||||
| SwitchDefault
|
||||
|
||||
| SwitchCases SwitchDefault
|
||||
;
|
||||
|
||||
SwitchDefault : OTHERWISE {hb_compSwitchAdd(NULL); hb_compLinePush(); } Crlf { hb_comp_functions.pLast->bFlags &= ~ FUN_BREAK_CODE; }
|
||||
EmptyStats
|
||||
;
|
||||
|
||||
BeginSeq : BEGINSEQ { ++hb_comp_wSeqCounter; $<lNumber>$ = hb_compSequenceBegin(); } Crlf
|
||||
EmptyStats
|
||||
{
|
||||
@@ -2296,7 +2402,7 @@ static void hb_compForEnd( char *szVar )
|
||||
|
||||
static HB_CARGO2_FUNC( hb_compEnumEvalStart )
|
||||
{
|
||||
char * szName = hb_compExprAsString( (HB_EXPR_PTR)cargo );
|
||||
char * szName = hb_compExprAsSymbol( (HB_EXPR_PTR)cargo );
|
||||
if( szName )
|
||||
hb_compForStart( szName, TRUE );
|
||||
|
||||
@@ -2342,7 +2448,7 @@ static void hb_compEnumNext( HB_EXPR_PTR pExpr, int descend )
|
||||
|
||||
static HB_CARGO_FUNC( hb_compEnumEvalEnd )
|
||||
{
|
||||
char * szName = hb_compExprAsString( (HB_EXPR_PTR)cargo );
|
||||
char * szName = hb_compExprAsSymbol( (HB_EXPR_PTR)cargo );
|
||||
|
||||
if( szName )
|
||||
hb_compForEnd( szName );
|
||||
@@ -2354,3 +2460,126 @@ static void hb_compEnumEnd( HB_EXPR_PTR pExpr )
|
||||
hb_compGenPCode1( HB_P_ENUMEND );
|
||||
}
|
||||
|
||||
static void hb_compSwitchStart()
|
||||
{
|
||||
SWITCHCMD_PTR pLast = hb_comp_pSwitch;
|
||||
|
||||
hb_comp_pSwitch = (SWITCHCMD_PTR) hb_xgrab( sizeof(SWITCHCMD) );
|
||||
hb_comp_pSwitch->pPrev = pLast;
|
||||
hb_comp_pSwitch->pCases = NULL;
|
||||
hb_comp_pSwitch->pLast = NULL;
|
||||
hb_comp_pSwitch->ulDefault = 0;
|
||||
hb_comp_pSwitch->ulOffset = hb_comp_functions.pLast->lPCodePos;
|
||||
hb_comp_pSwitch->iCount = 0;
|
||||
}
|
||||
|
||||
static void hb_compSwitchAdd( HB_EXPR_PTR pExpr )
|
||||
{
|
||||
SWITCHCASE_PTR pCase;
|
||||
|
||||
if( pExpr )
|
||||
{
|
||||
/* normal CASE */
|
||||
pCase = (SWITCHCASE_PTR) hb_xgrab( sizeof(SWITCHCASE) );
|
||||
pCase->ulOffset = hb_comp_functions.pLast->lPCodePos;
|
||||
pCase->pNext = NULL;
|
||||
pExpr = hb_compExprReduce( pExpr );
|
||||
if( !(hb_compExprIsLong(pExpr) || hb_compExprIsString(pExpr)) )
|
||||
{
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NOT_LITERAL_CASE, NULL, NULL );
|
||||
}
|
||||
pCase->pExpr = pExpr;
|
||||
|
||||
if( hb_comp_pSwitch->pLast )
|
||||
{
|
||||
hb_comp_pSwitch->pLast->pNext = pCase;
|
||||
hb_comp_pSwitch->pLast = pCase;
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_comp_pSwitch->pCases = hb_comp_pSwitch->pLast = pCase;
|
||||
}
|
||||
hb_comp_pSwitch->iCount++;
|
||||
if( hb_compExprIsString( pExpr ) && hb_compExprAsStringLen(pExpr) > 255 )
|
||||
{
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_STR, NULL, NULL );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DEFAULT */
|
||||
if( hb_comp_pSwitch->ulDefault )
|
||||
{
|
||||
/* more than one default clause */
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_MAYHEM_IN_CASE, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_comp_pSwitch->ulDefault = hb_comp_functions.pLast->lPCodePos;
|
||||
hb_comp_pSwitch->iCount++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void hb_compSwitchEnd( void )
|
||||
{
|
||||
BOOL longOptimize = hb_comp_long_optimize;
|
||||
BOOL bTextSubst = hb_comp_bTextSubst;
|
||||
SWITCHCASE_PTR pCase = hb_comp_pSwitch->pCases;
|
||||
SWITCHCASE_PTR pTmp;
|
||||
SWITCHCMD_PTR pTmpSw;
|
||||
ULONG ulExitPos;
|
||||
ULONG ulDef;
|
||||
|
||||
/* skip switch pcode if there was no EXIT in the last CASE
|
||||
* or in the DEFAULT case
|
||||
*/
|
||||
ulExitPos = hb_compGenJump( 0 );
|
||||
|
||||
hb_compGenJumpHere( hb_comp_pSwitch->ulOffset + 1 );
|
||||
hb_compGenPCode3( HB_P_SWITCH, HB_LOBYTE(hb_comp_pSwitch->iCount), HB_HIBYTE(hb_comp_pSwitch->iCount), FALSE );
|
||||
hb_comp_long_optimize = FALSE;
|
||||
hb_comp_bTextSubst = FALSE;
|
||||
while( pCase )
|
||||
{
|
||||
if( pCase->pExpr )
|
||||
{
|
||||
if( hb_compExprIsLong(pCase->pExpr) || hb_compExprIsString(pCase->pExpr) )
|
||||
{
|
||||
hb_compExprDelete( hb_compExprGenPush( pCase->pExpr ) );
|
||||
hb_compGenJumpThere( hb_compGenJump( 0 ), pCase->ulOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_compExprDelete( pCase->pExpr );
|
||||
}
|
||||
}
|
||||
pCase = pCase->pNext;
|
||||
}
|
||||
hb_compGenPData1( HB_P_PUSHNIL ); /* end of cases */
|
||||
ulDef = hb_compGenJump( 0 );
|
||||
|
||||
if( hb_comp_pSwitch->ulDefault )
|
||||
{
|
||||
hb_compGenJumpThere( ulDef, hb_comp_pSwitch->ulDefault );
|
||||
}
|
||||
else
|
||||
hb_compGenJumpHere( ulDef );
|
||||
|
||||
hb_comp_long_optimize = longOptimize;
|
||||
hb_comp_bTextSubst = bTextSubst;
|
||||
|
||||
hb_compGenJumpHere( ulExitPos );
|
||||
|
||||
pCase = hb_comp_pSwitch->pCases;
|
||||
while( pCase )
|
||||
{
|
||||
pTmp = pCase->pNext;
|
||||
hb_xfree( (void *)pCase );
|
||||
pCase = pTmp;
|
||||
}
|
||||
pTmpSw = hb_comp_pSwitch;
|
||||
hb_comp_pSwitch = hb_comp_pSwitch->pPrev;
|
||||
hb_xfree( pTmpSw );
|
||||
}
|
||||
|
||||
@@ -432,7 +432,9 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] =
|
||||
NULL, /* HB_P_ENUMSTART */
|
||||
NULL, /* HB_P_ENUMNEXT */
|
||||
NULL, /* HB_P_ENUMPREV */
|
||||
NULL /* HB_P_ENUMEND */
|
||||
NULL, /* HB_P_ENUMEND */
|
||||
NULL, /* HB_P_SWITCH */
|
||||
NULL /* HB_P_PUSHDATE */
|
||||
};
|
||||
|
||||
void hb_compFixFuncPCode( PFUNCTION pFunc )
|
||||
|
||||
@@ -86,7 +86,10 @@ char * hb_comp_szErrors[] =
|
||||
"Inline C requires C output generation, use -gc[n]",
|
||||
"Too many local variables [%s] or parameters [%s]",
|
||||
"Too many enumerate variables in FOR EACH loop",
|
||||
"Incorrect number of enumerate variables"
|
||||
"Incorrect number of enumerate variables",
|
||||
"CASE requires either numeric or string constant",
|
||||
"String too long for SWITCH",
|
||||
"Invalid date constant \'%s\'"
|
||||
};
|
||||
|
||||
/* Table with parse warnings */
|
||||
|
||||
@@ -49,7 +49,7 @@ char * hb_compIdentifierNew( char * szName, BOOL bCopy )
|
||||
else
|
||||
szIdent = szName;
|
||||
|
||||
hb_hashTableAdd( s_comp_Identifiers, (void *)szIdent );
|
||||
hb_hashTableAdd( s_comp_Identifiers, (void *)szIdent, (void *)szIdent );
|
||||
}
|
||||
|
||||
return szIdent;
|
||||
@@ -64,6 +64,7 @@ HB_HASH_FUNC( hb_comp_IdentKey ) /* ULONG func (void *Value, void *Cargo) */
|
||||
while( *szName )
|
||||
ulSum += *szName++;
|
||||
|
||||
HB_SYMBOL_UNUSED( HashPtr );
|
||||
HB_SYMBOL_UNUSED( Cargo );
|
||||
|
||||
return ulSum % HB_IDENT_TABLE_SIZE;
|
||||
@@ -73,6 +74,7 @@ HB_HASH_FUNC( hb_comp_IdentKey ) /* ULONG func (void *Value, void *Cargo) */
|
||||
HB_HASH_FUNC( hb_comp_IdentDel )
|
||||
{
|
||||
hb_xfree( Value );
|
||||
HB_SYMBOL_UNUSED( HashPtr );
|
||||
HB_SYMBOL_UNUSED( Cargo );
|
||||
return 1;
|
||||
}
|
||||
@@ -80,6 +82,7 @@ HB_HASH_FUNC( hb_comp_IdentDel )
|
||||
/* compares two identifiers */
|
||||
HB_HASH_FUNC( hb_comp_IdentComp )
|
||||
{
|
||||
HB_SYMBOL_UNUSED( HashPtr );
|
||||
return strcmp( (char *)Value, (char *)Cargo );
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,9 @@ static BYTE s_pcode_len[] = {
|
||||
3, /* HB_P_ENUMSTART */
|
||||
1, /* HB_P_ENUMNEXT */
|
||||
1, /* HB_P_ENUMPREV */
|
||||
1 /* HB_P_ENUMEND */
|
||||
1, /* HB_P_ENUMEND */
|
||||
3, /* HB_P_SWITCH */
|
||||
5 /* HB_P_PUSHDATE, */
|
||||
};
|
||||
|
||||
#if defined(HB_COMP_STRONG_TYPES)
|
||||
|
||||
@@ -73,6 +73,7 @@ NOTE: -C controls the speed/size ratio of generated scanner
|
||||
|
||||
#include "hbmacro.h"
|
||||
#include "hbcomp.h"
|
||||
#include "hbdate.h"
|
||||
|
||||
#include "macroy.h"
|
||||
#include "hbsetup.h" /* main configuration file */
|
||||
@@ -117,6 +118,7 @@ SpaceTab [ \t]+
|
||||
Number ([0-9]+)|([0-9]*\.[0-9]+)|(0x[0-9A-Fa-f]+)
|
||||
InvalidNumber [0-9]+\.
|
||||
Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+))
|
||||
Date 0d[0-9]{8}
|
||||
|
||||
MacroVar \&{Identifier}[\.]?
|
||||
MacroEnd \&{Identifier}\.({Identifier})|([0-9]+)
|
||||
@@ -268,6 +270,15 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+
|
||||
}
|
||||
}
|
||||
|
||||
{Date} {
|
||||
int year, month, day;
|
||||
|
||||
hb_dateStrGet( yytext+2, &year, &month, &day );
|
||||
yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day );
|
||||
|
||||
return NUM_DATE;
|
||||
}
|
||||
|
||||
{MacroVar} {
|
||||
HB_TRACE(HB_TR_DEBUG, ("{MacroVar}(%s)", yytext));
|
||||
if( yytext[ yyleng-1 ] == '.' )
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
|
||||
#include "hbmacro.h"
|
||||
#include "hbcomp.h"
|
||||
#include "hbdate.h"
|
||||
|
||||
/* Compile using: bison -d -p hb_comp macro.y */
|
||||
|
||||
@@ -159,7 +160,7 @@ int yylex( YYSTYPE *, HB_MACRO_PTR );
|
||||
#endif
|
||||
%}
|
||||
|
||||
%token IDENTIFIER NIL NUM_DOUBLE INASSIGN NUM_LONG
|
||||
%token IDENTIFIER NIL NUM_DOUBLE INASSIGN NUM_LONG NUM_DATE
|
||||
%token IIF IF LITERAL TRUEVALUE FALSEVALUE
|
||||
%token AND OR NOT EQ NE1 NE2 INC DEC ALIASOP SELF
|
||||
%token LE GE FIELD MACROVAR MACROTEXT
|
||||
@@ -194,6 +195,7 @@ int yylex( YYSTYPE *, HB_MACRO_PTR );
|
||||
%type <string> IDENTIFIER LITERAL MACROVAR MACROTEXT
|
||||
%type <valDouble> NUM_DOUBLE
|
||||
%type <valLong> NUM_LONG
|
||||
%type <valLong> NUM_DATE
|
||||
%type <asExpr> Argument ArgList ElemList BlockExpList BlockVarList BlockNoVar
|
||||
%type <asExpr> NumValue NumAlias
|
||||
%type <asExpr> NilValue
|
||||
@@ -221,6 +223,7 @@ int yylex( YYSTYPE *, HB_MACRO_PTR );
|
||||
%type <asExpr> ArrayIndex IndexList
|
||||
%type <asExpr> FieldAlias FieldVarAlias
|
||||
%type <asExpr> PostOp
|
||||
%type <asExpr> DateValue
|
||||
|
||||
%%
|
||||
|
||||
@@ -267,6 +270,9 @@ NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bWidth,
|
||||
| NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber ); }
|
||||
;
|
||||
|
||||
DateValue : NUM_DATE { $$ = hb_compExprNewDate( $1.lNumber ); }
|
||||
;
|
||||
|
||||
NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); }
|
||||
;
|
||||
|
||||
@@ -431,6 +437,7 @@ Argument : EmptyExpression { $$ = $1; }
|
||||
*/
|
||||
ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| NilValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| DateValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| LiteralValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| CodeBlock ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Logical ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
@@ -458,6 +465,7 @@ ObjectMethod : ObjectData '(' ArgList ')' { $$ = hb_compExprNewMethodCall( $1
|
||||
SimpleExpression :
|
||||
NumValue
|
||||
| NilValue { $$ = $1; }
|
||||
| DateValue { $$ = $1; }
|
||||
| LiteralValue { $$ = $1; }
|
||||
| CodeBlock { $$ = $1; }
|
||||
| Logical { $$ = $1; }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* hbexpra.c is also included from ../compiler/expropta.c
|
||||
* However it produces a slighty different code if used in
|
||||
* macro compiler (there is an additional parameter passed to some functions)
|
||||
* 1.16 - ignore this magic number - this is used to force compilation
|
||||
* 1.17 - ignore this magic number - this is used to force compilation
|
||||
*/
|
||||
|
||||
#define HB_MACRO_SUPPORT
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* hbexprb.c is also included from ../compiler/exproptb.c
|
||||
* However it produces a slighty different code if used in
|
||||
* macro compiler (there is an additional parameter passed to some functions)
|
||||
* 1.12 - ignore this magic number - this is used to force compilation
|
||||
* 1.13 - ignore this magic number - this is used to force compilation
|
||||
*/
|
||||
|
||||
#define HB_MACRO_SUPPORT
|
||||
|
||||
@@ -78,115 +78,6 @@
|
||||
#include "hbapi.h"
|
||||
#include "hbdate.h"
|
||||
|
||||
#ifdef HB_C52_STRICT
|
||||
#define HB_DATE_YEAR_LIMIT 2999
|
||||
#else
|
||||
#define HB_DATE_YEAR_LIMIT 9999
|
||||
#endif
|
||||
|
||||
LONG HB_EXPORT hb_dateEncode( int iYear, int iMonth, int iDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateEncode(%d, %d, %d)", iYear, iMonth, iDay));
|
||||
|
||||
/* Perform date validation */
|
||||
if( iYear >= 1 && iYear <= HB_DATE_YEAR_LIMIT &&
|
||||
iMonth >= 1 && iMonth <= 12 &&
|
||||
iDay >= 1 )
|
||||
{
|
||||
/* Month, year, and lower day limits are simple,
|
||||
but upper day limit is dependent upon month and leap year */
|
||||
int auiDayLimit[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
if( ( ( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 ) )
|
||||
auiDayLimit[ 1 ] = 29;
|
||||
|
||||
if( iDay <= auiDayLimit[ iMonth - 1 ] )
|
||||
{
|
||||
int iFactor = ( iMonth < 3 ) ? -1 : 0;
|
||||
|
||||
return ( ( LONG )( iFactor + 4800 + iYear ) * 1461 / 4 ) +
|
||||
( ( LONG )( iMonth - 2 - ( iFactor * 12 ) ) * 367 ) / 12 -
|
||||
( ( LONG )( ( iFactor + 4900 + iYear ) / 100 ) * 3 / 4 ) +
|
||||
( LONG ) iDay - 32075;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HB_EXPORT hb_dateDecode( LONG lJulian, int *piYear, int *piMonth, int *piDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateDecode(%ld, %p, %p, %p)", lJulian, piYear, piMonth, piDay));
|
||||
|
||||
if( lJulian > 0 )
|
||||
{
|
||||
LONG U, V, W, X;
|
||||
|
||||
lJulian += 68569;
|
||||
W = ( lJulian * 4 ) / 146097;
|
||||
lJulian -= ( ( 146097 * W ) + 3 ) / 4;
|
||||
X = 4000 * ( lJulian + 1 ) / 1461001;
|
||||
lJulian -= ( ( 1461 * X ) / 4 ) - 31;
|
||||
V = 80 * lJulian / 2447;
|
||||
U = V / 11;
|
||||
|
||||
*piYear = (int) ( X + U + ( W - 49 ) * 100 );
|
||||
*piMonth = (int) ( V + 2 - ( U * 12 ) );
|
||||
*piDay = (int) ( lJulian - ( 2447 * V / 80 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
*piYear =
|
||||
*piMonth =
|
||||
*piDay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HB_EXPORT hb_dateStrPut( char * szDate, int iYear, int iMonth, int iDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateStrPut(%p, %d, %d, %d)", szDate, iYear, iMonth, iDay));
|
||||
|
||||
if( iYear >= 0 && iMonth && iDay )
|
||||
{
|
||||
szDate[ 0 ] = ( ( iYear % 10000 ) / 1000 ) + '0';
|
||||
szDate[ 1 ] = ( ( iYear % 1000 ) / 100 ) + '0';
|
||||
szDate[ 2 ] = ( ( iYear % 100 ) / 10 ) + '0';
|
||||
szDate[ 3 ] = ( iYear % 10 ) + '0';
|
||||
|
||||
szDate[ 4 ] = ( iMonth / 10 ) + '0';
|
||||
szDate[ 5 ] = ( iMonth % 10 ) + '0';
|
||||
|
||||
szDate[ 6 ] = ( iDay / 10 ) + '0';
|
||||
szDate[ 7 ] = ( iDay % 10 ) + '0';
|
||||
}
|
||||
else if ( iYear || iMonth || iDay )
|
||||
memset( szDate, '0', 8 );
|
||||
else
|
||||
memset( szDate, ' ', 8 );
|
||||
}
|
||||
|
||||
void HB_EXPORT hb_dateStrGet( const char * szDate, int * piYear, int * piMonth, int * piDay )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_dateStrGet(%s, %p, %p, %p)", szDate, piYear, piMonth, piDay));
|
||||
|
||||
if( szDate && szDate[ 8 ] == '\0' )
|
||||
{
|
||||
/* Date string has correct length, so attempt to convert */
|
||||
*piYear = ( ( USHORT ) ( szDate[ 0 ] - '0' ) * 1000 ) +
|
||||
( ( USHORT ) ( szDate[ 1 ] - '0' ) * 100 ) +
|
||||
( ( USHORT ) ( szDate[ 2 ] - '0' ) * 10 ) +
|
||||
( USHORT ) ( szDate[ 3 ] - '0' );
|
||||
*piMonth = ( ( szDate[ 4 ] - '0' ) * 10 ) + ( szDate[ 5 ] - '0' );
|
||||
*piDay = ( ( szDate[ 6 ] - '0' ) * 10 ) + ( szDate[ 7 ] - '0' );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Date string missing or bad length, so force an empty date */
|
||||
*piYear =
|
||||
*piMonth =
|
||||
*piDay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function always closes the date with a zero byte, so it needs a
|
||||
9 character long buffer. */
|
||||
|
||||
@@ -131,6 +131,7 @@ static LONG hb_vmEnumStart( BYTE, BYTE, LONG ); /* prepare FOR EACH loop */
|
||||
static void hb_vmEnumNext( void ); /* increment FOR EACH loop counter */
|
||||
static void hb_vmEnumPrev( void ); /* decrement FOR EACH loop counter */
|
||||
static LONG hb_vmEnumEnd( void ); /* rewind the stack after FOR EACH loop counter */
|
||||
static LONG hb_vmSwitch( const BYTE * pCode, LONG, USHORT ); /* make a SWITCH statement */
|
||||
|
||||
/* Operators (logical) */
|
||||
static void hb_vmNot( void ); /* changes the latest logical value on the stack */
|
||||
@@ -628,7 +629,7 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
|
||||
if( ! --uiPolls )
|
||||
{
|
||||
hb_inkeyPoll();
|
||||
//uiPolls = 255;
|
||||
uiPolls = 255;
|
||||
/* IMHO we should have a _SET_ controlled by user
|
||||
* sth like:
|
||||
|
||||
@@ -770,6 +771,10 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
|
||||
w++;
|
||||
break;
|
||||
|
||||
case HB_P_SWITCH:
|
||||
w = hb_vmSwitch( pCode, w+3, HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) );
|
||||
break;
|
||||
|
||||
/* Operators (logical) */
|
||||
|
||||
case HB_P_NOT:
|
||||
@@ -1251,6 +1256,12 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
|
||||
w += ( 2 + pCode[ w + 1 ] );
|
||||
break;
|
||||
|
||||
case HB_P_PUSHDATE:
|
||||
HB_TRACE( HB_TR_DEBUG, ("(HB_P_PUSHDATE)") );
|
||||
hb_vmPushDate( ( long ) HB_PCODE_MKLONG( &pCode[ w + 1 ] ) );
|
||||
w += 5;
|
||||
break;
|
||||
|
||||
case HB_P_PUSHBLOCK:
|
||||
/* +0 -> _pushblock
|
||||
* +1 +2 -> size of codeblock
|
||||
@@ -3263,6 +3274,85 @@ static LONG hb_vmEnumEnd( void )
|
||||
return lOldBase;
|
||||
}
|
||||
|
||||
static LONG hb_vmSwitch( const BYTE * pCode, LONG offset, USHORT casesCnt )
|
||||
{
|
||||
HB_ITEM_PTR pSwitch = hb_stackItemFromTop( -1 );
|
||||
|
||||
if( !(HB_IS_NUMINT(pSwitch) || HB_IS_STRING(pSwitch)) )
|
||||
{
|
||||
HB_ITEM_PTR pResult = hb_errRT_BASE_Subst( EG_ARG, 3104, NULL, "SWITCH", 1, pSwitch );
|
||||
|
||||
if( pResult )
|
||||
{
|
||||
hb_stackPop();
|
||||
hb_vmPush( pResult );
|
||||
hb_itemRelease( pResult );
|
||||
pSwitch = hb_stackItemFromTop( -1 );
|
||||
}
|
||||
else
|
||||
return offset;
|
||||
}
|
||||
|
||||
while( casesCnt-- )
|
||||
{
|
||||
switch( pCode[ offset ] )
|
||||
{
|
||||
case HB_P_PUSHLONG:
|
||||
{
|
||||
if( HB_IS_NUMINT(pSwitch) )
|
||||
{
|
||||
if( HB_ITEM_GET_NUMINTRAW(pSwitch) == HB_PCODE_MKLONG( &pCode[ offset + 1 ] ) )
|
||||
{
|
||||
hb_stackPop();
|
||||
return offset + 5;
|
||||
}
|
||||
}
|
||||
offset += 5;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_PUSHSTRSHORT:
|
||||
{
|
||||
if( HB_IS_STRING(pSwitch) )
|
||||
{
|
||||
// int i = hb_itemStrCmp( pItem1, pItem2, bExact );
|
||||
|
||||
if( strcmp( pSwitch->item.asString.value, ( char * ) pCode + offset + 2 ) == 0 )
|
||||
{
|
||||
hb_stackPop();
|
||||
return offset + 2 + pCode[ offset + 1 ];
|
||||
}
|
||||
}
|
||||
offset += ( 2 + pCode[ offset + 1 ] );
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_P_PUSHNIL:
|
||||
{
|
||||
/* default clause */
|
||||
hb_stackPop();
|
||||
return offset + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch( pCode[ offset ] )
|
||||
{
|
||||
case HB_P_JUMP:
|
||||
offset += 3;
|
||||
break;
|
||||
case HB_P_JUMPNEAR:
|
||||
offset += 2;
|
||||
break;
|
||||
default:
|
||||
offset += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hb_stackPop();
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* Operators (logical) */
|
||||
/* ------------------------------- */
|
||||
|
||||
@@ -1284,6 +1284,15 @@ void hb_compGenPushLong( HB_LONG lNumber, HB_MACRO_DECL )
|
||||
}
|
||||
}
|
||||
|
||||
/* generates the pcode to push a date on the virtual machine stack */
|
||||
void hb_compGenPushDate( HB_LONG lNumber, HB_MACRO_DECL )
|
||||
{
|
||||
BYTE pBuffer[ 5 ];
|
||||
|
||||
pBuffer[ 0 ] = HB_P_PUSHDATE;
|
||||
HB_PUT_LE_UINT32( pBuffer + 1, lNumber );
|
||||
hb_compGenPCodeN( pBuffer, sizeof( pBuffer ), HB_MACRO_PARAM );
|
||||
}
|
||||
|
||||
/* sends a message to an object */
|
||||
void hb_compGenMessage( char * szMsgName, HB_MACRO_DECL )
|
||||
|
||||
31
harbour/tests/ddate.prg
Normal file
31
harbour/tests/ddate.prg
Normal file
@@ -0,0 +1,31 @@
|
||||
PROCEDURE MAIN()
|
||||
LOCAL dDate
|
||||
LOCAL A
|
||||
|
||||
SET DATE FORMAT TO "YYYY.MM.DD"
|
||||
SET CENTURY ON
|
||||
|
||||
dDate = 0d20051112
|
||||
? "Should be '2005.11.12' :", dDate
|
||||
|
||||
dDate = 0d18341112
|
||||
? "Should be '1834.11.12' :", dDate
|
||||
|
||||
dDate = 0d20040229 + 1
|
||||
? "Should be '2004.03.01' :", dDate
|
||||
|
||||
dDate = 0d20040229 - 1
|
||||
? "Should be '2004.02.28' :", dDate
|
||||
|
||||
? "Should be '4' :", 0d20040229 - 0d20040225
|
||||
? "Should be '0' :", 0d20040229 - 0d20040229
|
||||
|
||||
dDate = 0d20000229
|
||||
? "Should be '2000.02.29' :", dDate
|
||||
|
||||
a := '0d20040229+1'
|
||||
? "Should be '2004.03.01' :", &a
|
||||
|
||||
a :="DATE() - 0d20051112"
|
||||
? "Number of days from 2005.11.12:", &a
|
||||
|
||||
116
harbour/tests/switch.prg
Normal file
116
harbour/tests/switch.prg
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifdef __XHARBOUR__
|
||||
#define OTHERWISE DEFAULT
|
||||
#endif
|
||||
|
||||
PROCEDURE MAIN
|
||||
LOCAL a:=1
|
||||
PRIVATE b:="b"
|
||||
|
||||
#ifndef __XHARBOUR__
|
||||
SWITCH a
|
||||
END
|
||||
#endif
|
||||
|
||||
?
|
||||
? "1111111111111111111111111111111"
|
||||
SWITCH a
|
||||
CASE 1
|
||||
? "FOUND: 1"
|
||||
END
|
||||
|
||||
?
|
||||
? "2222222222222222222222222222222"
|
||||
SWITCH a
|
||||
CASE 1
|
||||
? "FOUND: 1"
|
||||
EXIT
|
||||
CASE "2"
|
||||
? a
|
||||
END
|
||||
|
||||
?
|
||||
? "3333333333333333333333333333333"
|
||||
SWITCH a
|
||||
CASE 1
|
||||
? "FOUND: 1"
|
||||
CASE "2"
|
||||
? "FOUND: 2"
|
||||
OTHERWISE
|
||||
? "other"
|
||||
END
|
||||
|
||||
#ifndef __XHARBOUR__
|
||||
?
|
||||
? "44444444444444444444444444444444444"
|
||||
SWITCH a
|
||||
OTHERWISE
|
||||
? "OTHERWISE"
|
||||
END
|
||||
#endif
|
||||
|
||||
?
|
||||
? "55555555555555555555555555555555555"
|
||||
a := 'EE'
|
||||
#ifndef __XHARBOUR__
|
||||
SWITCH a
|
||||
CASE 11
|
||||
? "11"
|
||||
exit
|
||||
|
||||
CASE 'CCCC'+'DDDD'
|
||||
? a+a
|
||||
EXIT
|
||||
|
||||
CASE "a&b"
|
||||
CASE 1+1
|
||||
CASE {11111111,22222222222}[1]
|
||||
CASE 1+1+1
|
||||
? "3"
|
||||
EXIT
|
||||
|
||||
CASE 1+1*3
|
||||
CASE 123+12*4-1*4+2
|
||||
CASE 1-4
|
||||
? "4"
|
||||
EXIT
|
||||
CASE 123456789
|
||||
CASE 0
|
||||
EXIT
|
||||
CASE 'AAAA'
|
||||
CASE 'BBBBB'
|
||||
? a
|
||||
EXIT
|
||||
CASE CHR(12)+CHR(15)
|
||||
? "CHR()"
|
||||
EXIT
|
||||
OTHERWISE
|
||||
? "NOT FOUND: running OTHER"
|
||||
END
|
||||
#endif
|
||||
|
||||
?
|
||||
? "666666666666666666666666666666666666666666"
|
||||
a := "2"
|
||||
SWITCH a
|
||||
CASE 1
|
||||
? "FOUND: 1"
|
||||
? a
|
||||
EXIT
|
||||
CASE "2"
|
||||
SWITCH a+a
|
||||
CASE 1
|
||||
? "Nested FOUND 1"
|
||||
EXIT
|
||||
CASE "22"
|
||||
? "Nested FOUND: 22"
|
||||
EXIT
|
||||
OTHERWISE
|
||||
? "Nested OTHERWISE"
|
||||
END
|
||||
?? "In CASE 1"
|
||||
? a
|
||||
END
|
||||
|
||||
? "========================================="
|
||||
|
||||
RETURN
|
||||
Reference in New Issue
Block a user