Re: harbour hb_ functions
Posted: Mon Jan 06, 2020 10:07 pm
hi,
i wrote a small App to "extract" HB_FUNC
from HMG Source and got this (now as ZIP)
i wrote a small App to "extract" HB_FUNC
from HMG Source and got this (now as ZIP)
Exclusive forum for HMG, a Free / Open Source xBase WIN32/64 Bits / GUI Development System
http://hmgforum.com/
hm ... if i search for a Function i did not know if it is a Harbour or HMG / MiniGUI HB_Func
Yes, sorryKDJ wrote:And long text you can put between tags:Code: Select all
Hi,
Code: Select all
LOCAL nStep := -1
hb_ForNext( 1, 10, {|i| QQout(i)}, nStep )
Code: Select all
while( nStart <= nEnd )
{
hb_vmPushEvalSym();
hb_vmPush( pCodeBlock );
hb_vmPushNumInt( nStart );
hb_vmSend( 1 );
nStart += nStep;
}
Code: Select all
if (nStep != 0)
{
if (nStep > 0)
{
while( nStart <= nEnd )
{
hb_vmPushEvalSym();
hb_vmPush( pCodeBlock );
hb_vmPushNumInt( nStart );
hb_vmSend( 1 );
nStart += nStep;
}
}
else
{
while( nStart >= nEnd )
{
hb_vmPushEvalSym();
hb_vmPush( pCodeBlock );
hb_vmPushNumInt( nStart );
hb_vmSend( 1 );
nStart += nStep;
}
}
}
Code: Select all
for ( [Init] ; [Condition] ; [Update] )
{
[Code]
[continue;]
[Code]
[break;]
[Code]
}
Code: Select all
/*
hb_ForLikeC([bInit], [bCondition], [bUpdate], [bCode]) --> NIL
- if bCondition or bCode return .F. -> EXIT loop, otherwise loop is continued
*/
FUNCTION hb_ForLikeC(bInit, bCondition, bUpdate, bCode)
LOCAL lCondition := .T.
LOCAL lContinue
IF hb_IsBlock(bInit)
Eval(bInit)
ENDIF
IF hb_IsBlock(bCondition)
lCondition := Eval(bCondition)
IF ! hb_IsLogical(lCondition)
lCondition := .T.
ENDIF
ENDIF
DO WHILE lCondition
IF hb_IsBlock(bCode)
lContinue := Eval(bCode)
IF hb_IsLogical(lContinue) .and. (! lContinue)
EXIT
ENDIF
ENDIF
IF hb_IsBlock(bUpdate)
Eval(bUpdate)
ENDIF
IF hb_IsBlock(bCondition)
lCondition := Eval(bCondition)
IF ! hb_IsLogical(lCondition)
lCondition := .T.
ENDIF
ENDIF
ENDDO
RETURN NIL
Code: Select all
FUNCTION Main()
LOCAL aArr[10]
LOCAL n
hb_ForLikeC({ || n := 1 }, { || n <= Len(aArr) }, { || ++n }, { || aArr[n] := n })
MsgBox(n)
MsgBox(aArr)
hb_ForLikeC({ || n := Len(aArr) }, { || n >= 5 }, { || --n }, { || aArr[n] *= 10 })
MsgBox(n)
MsgBox(aArr)
RETURN NIL
I guess I'm not a fan of code blocks.
Code: Select all
/*
hb_ForLoop()
2020-01-11 Krzysztof Janicki (aka KDJ)
*/
#include "hbapi.h"
#include "hbapiitm.h"
#include "hbvm.h"
/*
if first and second parameters are numbers:
works like FOR...NEXT loop in HARBOUR:
hb_ForLoop(nStart, nEnd, [nStep], [bCode]) --> nCounter
- to bCode block is passed loop counter as parameter: { |nCounter| ... }
- if bCode return .F. -> EXIT loop, otherwise loop is continued
else:
works like for() loop in C:
hb_ForLoop([bInit], [bCondition], [bUpdate], [bCode]) --> NIL
- if bCondition or bCode return .F. -> EXIT loop, otherwise loop is continued
*/
HB_FUNC( HB_FORLOOP )
{
PHB_ITEM pCode = hb_param(4, HB_IT_BLOCK);
if (HB_ISNUM(1) && HB_ISNUM(2))
{
HB_MAXINT nStart = hb_parnint(1);
HB_MAXINT nEnd = hb_parnint(2);
HB_MAXINT nStep = hb_parnintdef(3, 1);
while ((nStep < 0) ? (nStart >= nEnd) : (nStart <= nEnd))
{
if (pCode)
{
hb_vmPushEvalSym();
hb_vmPush(pCode);
hb_vmPushNumInt(nStart);
hb_vmSend(1);
if (HB_ISLOG(-1) && (! hb_parl(-1)))
break;
}
nStart += nStep;
}
hb_retnint(nStart);
}
else
{
PHB_ITEM pInit = hb_param(1, HB_IT_BLOCK);
PHB_ITEM pCondition = hb_param(2, HB_IT_BLOCK);
PHB_ITEM pUpdate = hb_param(3, HB_IT_BLOCK);
HB_BOOL Condition = HB_TRUE;
if (pInit)
hb_evalBlock0(pInit);
if (pCondition)
{
hb_evalBlock0(pCondition);
if (HB_ISLOG(-1))
Condition = hb_parl(-1);
}
while (Condition)
{
if (pCode)
{
hb_evalBlock0(pCode);
if (HB_ISLOG(-1) && (! hb_parl(-1)))
break;
}
if (pUpdate)
hb_evalBlock0(pUpdate);
if (pCondition)
{
hb_evalBlock0(pCondition);
if (HB_ISLOG(-1))
Condition = hb_parl(-1);
}
}
hb_ret();
}
}
Very good implementation!I created hb_ForLoop() function (in C) that can emulate FOR...NEXT HARBOUR statement or for() loop of C:
Code: Select all
wapi_QueryPerformanceCounter( @nCounterStart )
hb_ForNext(nStart, nEnd, bCodeH, nStep)
wapi_QueryPerformanceCounter( @nCounterEnd )
? "Execution time elapsed: ", win_QPCounter2Sec( nCounterEnd - nCounterStart ), " sec."