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( <aValue> ) -> <aValue>[ 1 ] [, <aValue>[ 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
This commit is contained in:
Przemyslaw Czerpak
2010-02-28 23:52:05 +00:00
parent 4b455a03b1
commit bb86055fe6
14 changed files with 165 additions and 17 deletions

View File

@@ -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( <aValue> ) -> <aValue>[ 1 ] [, <aValue>[ 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

View File

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

View File

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

View File

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

View File

@@ -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 ) )
{
/* &macro 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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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