diff --git a/harbour/ChangeLog b/harbour/ChangeLog index f36e4e26be..5221946f27 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,49 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-03-01 00:50 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbpcode.h + * harbour/include/hbxvm.h + * harbour/src/compiler/hbfix.c + * harbour/src/compiler/hbpcode.c + * harbour/src/compiler/hbdead.c + * harbour/src/compiler/genc.c + * harbour/src/compiler/hbopt.c + * harbour/src/compiler/gencc.c + * harbour/src/compiler/hblbl.c + * harbour/src/compiler/hbstripl.c + * harbour/src/vm/hvm.c + + added new PCODE HB_P_PUSHAPARAMS and -gc3 function with corresponding + action hb_xvmPushAParams + + * harbour/include/hbexprb.c + * harbour/src/common/expropt1.c + * harbour/src/vm/hvm.c + + added support for special PRG function: + HB_ARRAYTOPARAMS( ) -> [ 1 ] [, [ N ] ] + It can be used in the same context as multivalue macros + or ... operator and converts array to list of parameters, i.e.: + proc main + local aValue, aIndexes + + aValue := { 1, { 2, 3, "abcde" } } + aIndexes := { 2, 3 } + ? "array:", hb_valToExp( aValue ) + ? "indexes:", hb_arrayToParams( aIndexes ) + + ? "array[", hb_arrayToParams( aIndexes ), "] =>", ; + aValue[ hb_arrayToParams( aIndexes ) ] + aValue[ hb_arrayToParams( aIndexes ) ] += ":add" + ? "array:", hb_valToExp( aValue ) + + aValue := { "test", aValue } + aIndexes := { 2, hb_arrayToParams( aIndexes ) } + ? "array:", hb_valToExp( aValue ) + ? "indexes:", hb_arrayToParams( aIndexes ) + ? "array[", hb_arrayToParams( aIndexes ), "] =>", ; + aValue[ hb_arrayToParams( aIndexes ) ] + return + 2010-02-28 20:05 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/rddsql/sddsqlt3/Makefile - contrib/rddsql/sddsqlt3/sddsq3.c diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 7d2951d8b7..00b2890677 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -79,9 +79,9 @@ static HB_EXPR_FUNC( hb_compExprUseLogical ); static HB_EXPR_FUNC( hb_compExprUseSelf ); static HB_EXPR_FUNC( hb_compExprUseArray ); static HB_EXPR_FUNC( hb_compExprUseHash ); +static HB_EXPR_FUNC( hb_compExprUseFunRef ); static HB_EXPR_FUNC( hb_compExprUseVarRef ); static HB_EXPR_FUNC( hb_compExprUseRef ); -static HB_EXPR_FUNC( hb_compExprUseFunRef ); static HB_EXPR_FUNC( hb_compExprUseIIF ); static HB_EXPR_FUNC( hb_compExprUseList ); static HB_EXPR_FUNC( hb_compExprUseArgList ); @@ -1226,7 +1226,11 @@ static HB_EXPR_FUNC( hb_compExprUseMacroArgList ) if( ( pExpr->ExprType == HB_ET_MACRO && ( pExpr->value.asMacro.SubType & HB_ET_MACRO_LIST ) ) || ( pExpr->ExprType == HB_ET_ARGLIST && - pExpr->value.asList.reference ) ) + pExpr->value.asList.reference ) || + ( pExpr->ExprType == HB_ET_FUNCALL && + pExpr->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME && + pExpr->value.asFunCall.pFunName->value.asSymbol.funcid == + HB_F_ARRAYTOPARAMS ) ) { if( usItems ) { @@ -1399,7 +1403,12 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) { fMacroIndex = pSelf->value.asList.pIndex->value.asList.reference; } - + else if( pSelf->value.asList.pIndex->ExprType == HB_ET_FUNCALL && + pSelf->value.asList.pIndex->value.asFunCall.pFunName-> + value.asSymbol.funcid == HB_F_ARRAYTOPARAMS ) + { + fMacroIndex = HB_TRUE; + } if( pSelf->value.asList.reference && HB_SUPPORT_ARRSTR ) { HB_EXPR_PTR pList = pSelf->value.asList.pExprList; @@ -1471,6 +1480,12 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) { fMacroIndex = pSelf->value.asList.pIndex->value.asList.reference; } + else if( pSelf->value.asList.pIndex->ExprType == HB_ET_FUNCALL && + pSelf->value.asList.pIndex->value.asFunCall.pFunName-> + value.asSymbol.funcid == HB_F_ARRAYTOPARAMS ) + { + fMacroIndex = HB_TRUE; + } /* to manage strings as bytes arrays, they must be pushed by reference */ /* arrays also are passed by reference */ if( HB_SUPPORT_ARRSTR ) @@ -2070,6 +2085,17 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall ) if( pSelf->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME ) { + if( pSelf->value.asFunCall.pFunName->value.asSymbol.funcid == + HB_F_ARRAYTOPARAMS ) + { + usCount = ( HB_USHORT ) hb_compExprParamListCheck( HB_COMP_PARAM, pSelf->value.asFunCall.pParms ); + if( usCount == 1 && pSelf->value.asFunCall.pParms->ExprType != HB_ET_MACROARGLIST ) + { + HB_EXPR_USE( pSelf->value.asFunCall.pParms, HB_EA_PUSH_PCODE ); + HB_GEN_FUNC1( PCode1, HB_P_PUSHAPARAMS ); + break; + } + } HB_GEN_FUNC2( PushFunCall, pSelf->value.asFunCall.pFunName->value.asSymbol.name, pSelf->value.asFunCall.pFunName->value.asSymbol.flags ); } diff --git a/harbour/include/hbpcode.h b/harbour/include/hbpcode.h index 45582e079d..086d25b85b 100644 --- a/harbour/include/hbpcode.h +++ b/harbour/include/hbpcode.h @@ -251,7 +251,8 @@ typedef enum HB_P_HASHGEN, /* 177 instructs the virtual machine to build a hash and load element from the stack */ HB_P_SEQBLOCK, /* 178 set BEQIN SEQUENCE WITH block */ HB_P_THREADSTATICS, /* 179 mark thread static variables */ - HB_P_LAST_PCODE /* 180 this defines the number of defined pcodes */ + HB_P_PUSHAPARAMS, /* 180 push array items on HVM stack */ + HB_P_LAST_PCODE /* 181 this defines the number of defined pcodes */ } HB_PCODE; #endif /* HB_PCODE_H_ */ diff --git a/harbour/include/hbxvm.h b/harbour/include/hbxvm.h index 79f309c69e..f5d60997f1 100644 --- a/harbour/include/hbxvm.h +++ b/harbour/include/hbxvm.h @@ -118,6 +118,7 @@ extern HB_EXPORT void hb_xvmPushBlockShort( const HB_BYTE * pCode, PHB_SYMB p extern HB_EXPORT void hb_xvmPushBlockLarge( const HB_BYTE * pCode, PHB_SYMB pSymbols ); /* creates a codeblock */ extern HB_EXPORT void hb_xvmPushSelf( void ); extern HB_EXPORT void hb_xvmPushVParams( void ); +extern HB_EXPORT void hb_xvmPushAParams( void ); extern HB_EXPORT void hb_xvmPushLocal( HB_SHORT iLocal ); /* pushes the containts of a local onto the stack */ extern HB_EXPORT void hb_xvmPushLocalByRef( HB_SHORT iLocal ); /* pushes a local by refrence onto the stack */ extern HB_EXPORT void hb_xvmPopLocal( HB_SHORT iLocal ); /* pops the stack latest value onto a local */ diff --git a/harbour/src/common/expropt1.c b/harbour/src/common/expropt1.c index b0a498b283..0dd3660994 100644 --- a/harbour/src/common/expropt1.c +++ b/harbour/src/common/expropt1.c @@ -1372,10 +1372,15 @@ HB_ULONG hb_compExprParamListCheck( HB_COMP_DECL, HB_EXPR_PTR pExpr ) pElem->value.asMacro.SubType != HB_ET_MACRO_REFER && pElem->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) || ( pElem->ExprType == HB_ET_ARGLIST && - pElem->value.asList.reference ) ) + pElem->value.asList.reference ) || + ( pElem->ExprType == HB_ET_FUNCALL && + pElem->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME && + pElem->value.asFunCall.pFunName->value.asSymbol.funcid == + HB_F_ARRAYTOPARAMS ) ) { /* ¯o was passed or optional parameters list passed, f.e.: f(a,b,...) + or hb_arrayToParams( aParams ) - handle it differently then in a normal statement */ if( pElem->ExprType == HB_ET_MACRO ) pElem->value.asMacro.SubType |= HB_ET_MACRO_LIST; diff --git a/harbour/src/compiler/genc.c b/harbour/src/compiler/genc.c index a8a52e26ba..46c9f1e03d 100644 --- a/harbour/src/compiler/genc.c +++ b/harbour/src/compiler/genc.c @@ -2465,6 +2465,15 @@ static HB_GENC_FUNC( hb_p_pushvparams ) return 1; } +static HB_GENC_FUNC( hb_p_pushaparams ) +{ + HB_SYMBOL_UNUSED( pFunc ); + HB_SYMBOL_UNUSED( lPCodePos ); + + fprintf( cargo->yyc, "\tHB_P_PUSHAPARAMS,\n" ); + return 1; +} + /* NOTE: The order of functions have to match the order of opcodes * mnemonics */ @@ -2653,7 +2662,8 @@ static const HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_pushfuncsym, hb_p_hashgen, hb_p_seqblock, - hb_p_threadstatics + hb_p_threadstatics, + hb_p_pushaparams }; static void hb_compGenCReadable( HB_COMP_DECL, PFUNCTION pFunc, FILE * yyc ) diff --git a/harbour/src/compiler/gencc.c b/harbour/src/compiler/gencc.c index d19c20caa4..b985359f73 100644 --- a/harbour/src/compiler/gencc.c +++ b/harbour/src/compiler/gencc.c @@ -2065,6 +2065,14 @@ static HB_GENC_FUNC( hb_p_pushvparams ) return 1; } +static HB_GENC_FUNC( hb_p_pushaparams ) +{ + HB_GENC_LABEL(); + + fprintf( cargo->yyc, "\thb_xvmPushAParams();\n" ); + return 1; +} + /* NOTE: The order of functions have to match the order of opcodes * mnemonics @@ -2254,7 +2262,8 @@ static const HB_GENC_FUNC_PTR s_verbose_table[] = { hb_p_pushfuncsym, hb_p_hashgen, hb_p_seqblock, - hb_p_threadstatics + hb_p_threadstatics, + hb_p_pushaparams }; void hb_compGenCRealCode( HB_COMP_DECL, PFUNCTION pFunc, FILE * yyc ) diff --git a/harbour/src/compiler/hbdead.c b/harbour/src/compiler/hbdead.c index 69fbd79b8e..67a4995452 100644 --- a/harbour/src/compiler/hbdead.c +++ b/harbour/src/compiler/hbdead.c @@ -542,7 +542,8 @@ static const PHB_CODETRACE_FUNC s_codeTraceFuncTable[] = hb_p_default, /* HB_P_PUSHFUNCSYM */ hb_p_default, /* HB_P_HASHGEN */ hb_p_default, /* HB_P_SEQBLOCK */ - hb_p_default /* HB_P_THREADSTATICS */ + hb_p_default, /* HB_P_THREADSTATICS */ + hb_p_default /* HB_P_PUSHAPARAMS */ }; void hb_compCodeTraceMarkDead( HB_COMP_DECL, PFUNCTION pFunc ) diff --git a/harbour/src/compiler/hbfix.c b/harbour/src/compiler/hbfix.c index fc58080112..56aa196814 100644 --- a/harbour/src/compiler/hbfix.c +++ b/harbour/src/compiler/hbfix.c @@ -328,7 +328,8 @@ static const HB_FIX_FUNC_PTR s_fixlocals_table[] = NULL, /* HB_P_PUSHFUNCSYM */ NULL, /* HB_P_HASHGEN */ NULL, /* HB_P_SEQBLOCK */ - NULL /* HB_P_THREADSTATICS */ + NULL, /* HB_P_THREADSTATICS */ + NULL /* HB_P_PUSHAPARAMS */ }; void hb_compFixFuncPCode( HB_COMP_DECL, PFUNCTION pFunc ) diff --git a/harbour/src/compiler/hblbl.c b/harbour/src/compiler/hblbl.c index 710022d571..1756885a5e 100644 --- a/harbour/src/compiler/hblbl.c +++ b/harbour/src/compiler/hblbl.c @@ -372,7 +372,8 @@ static const PHB_LABEL_FUNC s_GenLabelFuncTable[] = NULL, /* HB_P_PUSHFUNCSYM */ NULL, /* HB_P_HASHGEN */ NULL, /* HB_P_SEQBLOCK */ - NULL /* HB_P_THREADSTATICS */ + NULL, /* HB_P_THREADSTATICS */ + NULL /* HB_P_PUSHAPARAMS */ }; void hb_compGenLabelTable( PFUNCTION pFunc, PHB_LABEL_INFO label_info ) diff --git a/harbour/src/compiler/hbopt.c b/harbour/src/compiler/hbopt.c index 0c5c08a669..a7b440514e 100644 --- a/harbour/src/compiler/hbopt.c +++ b/harbour/src/compiler/hbopt.c @@ -923,7 +923,8 @@ static const HB_OPT_FUNC_PTR s_opt_table[] = NULL, /* HB_P_PUSHFUNCSYM */ NULL, /* HB_P_HASHGEN */ NULL, /* HB_P_SEQBLOCK */ - NULL /* HB_P_THREADSTATICS */ + NULL, /* HB_P_THREADSTATICS */ + NULL /* HB_P_PUSHAPARAMS */ }; void hb_compOptimizePCode( HB_COMP_DECL, PFUNCTION pFunc ) @@ -1548,7 +1549,7 @@ void hb_compPCodeTraceOptimizer( HB_COMP_DECL ) Special attention should be paid, if new pcode introduces branching, codeblocks, or are related to parameters, local variables. [Mindaugas] */ - assert( HB_P_LAST_PCODE == 180 ); + assert( HB_P_LAST_PCODE == 181 ); usLocalCount = 0; pVar = pFunc->pLocals; diff --git a/harbour/src/compiler/hbpcode.c b/harbour/src/compiler/hbpcode.c index 6f7f1d800f..a01de39556 100644 --- a/harbour/src/compiler/hbpcode.c +++ b/harbour/src/compiler/hbpcode.c @@ -299,7 +299,8 @@ const HB_BYTE hb_comp_pcode_len[] = { 3, /* HB_P_PUSHFUNCSYM */ 3, /* HB_P_HASHGEN */ 1, /* HB_P_SEQBLOCK */ - 0 /* HB_P_THREADSTATICS */ + 0, /* HB_P_THREADSTATICS */ + 1 /* HB_P_PUSHAPARAMS */ }; /* @@ -490,7 +491,8 @@ static HB_PCODE_FUNC_PTR s_psize_table[] = NULL, /* HB_P_PUSHFUNCSYM */ NULL, /* HB_P_HASHGEN */ NULL, /* HB_P_SEQBLOCK */ - hb_p_threadstatics /* HB_P_THREADSTATICS */ + hb_p_threadstatics, /* HB_P_THREADSTATICS */ + NULL /* HB_P_PUSHAPARAMS */ }; HB_LONG hb_compPCodeSize( PFUNCTION pFunc, HB_ULONG ulOffset ) diff --git a/harbour/src/compiler/hbstripl.c b/harbour/src/compiler/hbstripl.c index effbb2f74e..e7d258ebe2 100644 --- a/harbour/src/compiler/hbstripl.c +++ b/harbour/src/compiler/hbstripl.c @@ -262,7 +262,8 @@ static const PHB_STRIP_FUNC s_stripLines_table[] = NULL, /* HB_P_PUSHFUNCSYM */ NULL, /* HB_P_HASHGEN */ NULL, /* HB_P_SEQBLOCK */ - NULL /* HB_P_THREADSTATICS */ + NULL, /* HB_P_THREADSTATICS */ + NULL /* HB_P_PUSHAPARAMS */ }; void hb_compStripFuncLines( PFUNCTION pFunc ) diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 5876b56229..e899331a9f 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -189,7 +189,8 @@ static void hb_vmPushStatic( HB_USHORT uiStatic ); /* pushes the containt static void hb_vmPushStaticByRef( HB_USHORT uiStatic ); /* pushes a static by refrence onto the stack */ static void hb_vmPushVariable( PHB_SYMB pVarSymb ); /* pushes undeclared variable */ static void hb_vmPushObjectVarRef( void ); /* pushes reference to object variable */ -static void hb_vmPushVParams( void ); /* pusges variable parameters */ +static void hb_vmPushVParams( void ); /* pushes variable parameters */ +static void hb_vmPushAParams( void ); /* pushes array items */ static void hb_vmPushUnRef( void ); /* push the unreferenced latest value on the stack */ static void hb_vmDuplicate( void ); /* duplicates the latest value on the stack */ static void hb_vmDuplUnRef( void ); /* duplicates the latest value on the stack and unref the source one */ @@ -2339,6 +2340,11 @@ void hb_vmExecute( const HB_BYTE * pCode, PHB_SYMB pSymbols ) pCode++; break; + case HB_P_PUSHAPARAMS: + hb_vmPushAParams(); + pCode++; + break; + case HB_P_SWAP: hb_vmSwap( ( unsigned char ) pCode[ 1 ] ); pCode += 2; @@ -5436,7 +5442,11 @@ static void hb_vmMacroPushIndex( void ) /* First index is still on stack.*/ do { - hb_vmArrayPush(); + PHB_ITEM pArray = hb_stackItemFromTop( -2 ); + if( HB_IS_BYREF( pArray ) ) + hb_vmArrayPushRef(); + else + hb_vmArrayPush(); /* RT error? */ if( hb_stackGetActionRequest() != 0 ) break; @@ -5560,6 +5570,29 @@ static void hb_vmPushVParams( void ) hb_vmPushInteger( i ); } +static void hb_vmPushAParams( void ) +{ + HB_STACK_TLS_PRELOAD + PHB_ITEM pArray, pCount; + + HB_TRACE(HB_TR_DEBUG, ("hb_vmPushAParams()")); + + pArray = hb_stackItemFromTop( -1 ); + if( HB_IS_ARRAY( pArray ) ) + { + HB_SIZE ulLen = pArray->item.asArray.value->ulLen, ul; + + for( ul = 1; ul < ulLen; ++ul ) + hb_vmPush( pArray->item.asArray.value->pItems + ul ); + hb_vmPush( pArray->item.asArray.value->pItems ); + pCount = hb_stackItemFromTop( -1 ); + hb_itemMove( pArray, pCount ); + hb_itemPutNL( pCount, ulLen ); + } + else + hb_errRT_BASE( EG_ARG, 1068, NULL, hb_langDGetErrorDesc( EG_ARRACCESS ), 1, pArray ); +} + /* ------------------------------- */ /* Database */ /* ------------------------------- */ @@ -11179,6 +11212,14 @@ void hb_xvmPushVParams( void ) hb_vmPushVParams(); } + +void hb_xvmPushAParams( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_xvmPushAParams()")); + + hb_vmPushAParams(); +} + void hb_xvmWithObjectStart( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_xvmWithObjectStart()")); @@ -11559,6 +11600,11 @@ HB_FUNC( __QUITCANCEL ) } } +HB_FUNC( HB_ARRAYTOPARAMS ) +{ + hb_retni( 0 ); +} + HB_FUNC( ERRORLEVEL ) { HB_STACK_TLS_PRELOAD