harbour hb_ functions
Moderator: Rathinagiri
- AUGE_OHR
- Posts: 2065
- Joined: Sun Aug 25, 2019 3:12 pm
- DBs Used: DBF, PostgreSQL, MySQL, SQLite
- Location: Hamburg, Germany
Re: harbour hb_ functions
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)
Last edited by AUGE_OHR on Tue Jan 07, 2020 12:01 am, edited 2 times in total.
have fun
Jimmy
Jimmy
Re: harbour hb_ functions
Hi Jimmy
This topic applies to Harbour functions and not HMG functions.
So please move your post to another location.
And long text you can put between tags: [code][/code]
This topic applies to Harbour functions and not HMG functions.
So please move your post to another location.
And long text you can put between tags: [code][/code]
- AUGE_OHR
- Posts: 2065
- Joined: Sun Aug 25, 2019 3:12 pm
- DBs Used: DBF, PostgreSQL, MySQL, SQLite
- Location: Hamburg, Germany
Re: harbour hb_ functions
hi,
that why i make those List too where i can search so i think it belong to this Thread
from MiniGUI Source as ZIP
hm ... if i search for a Function i did not know if it is a Harbour or HMG / MiniGUI HB_Func
that why i make those List too where i can search so i think it belong to this Thread
Yes, sorryKDJ wrote:And long text you can put between tags:Code: Select all
from MiniGUI Source as ZIP
have fun
Jimmy
Jimmy
Re: harbour hb_ functions
Hi,
I think it is a "feature", which means, it is so by design.
(well, not very efficient design, perhaps, but not exactly a bug.)
The truth is that this behavior should be documented, so, thank you for pointing it out!
By the way, another more severe issue can arise by `nStep` argument,
which must never (!) be assigned a negative value, otherwise an (uninterruptible)
infinite loop will be produced!
these lines of code:
Code: Select all
LOCAL nStep := -1
hb_ForNext( 1, 10, {|i| QQout(i)}, nStep )
be somehow "killed" or the CPU be burned.
regards,
Pete
Re: harbour hb_ functions
Hi Pete
I do not think it was intentional.
What sense would introduce a function which performs only half of what traditional loop FOR...NEXT?
This is a piece of function code from source (eval.c):
This can do somehow like as below:
I do not think it was intentional.
What sense would introduce a function which performs only half of what traditional loop FOR...NEXT?
This is a piece of function code from source (eval.c):
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;
}
}
}
Re: harbour hb_ functions
Hi KDJ
I remember, when I tried to create some documentation for this function, I had
also examined the sources (and I did it again now).
My impression is the code is a little "quick and (if not dirty) incomplete".
- it is error prone, since it has no error detection (neither during compile-time nor run-time),
- it returns inconsistent value and , as you correctly saying,
- "performs only half of what traditional loop..."
I cannot guess the intention of the developer who created the function but I can imagine an excuse:
this function mimics the `for(...)` loop of C-language and mimics it very well, in the sense,
that just like in C, the programmer is equally responsible and free either to create good,
bug-free code or to "shoot his foot!"
Besides, the open source code is open not only for use but also open to improvements!
Certainly, the code you suggest is in this direction and, if you wish, please integrate it
in the initial function and post the final result.
regards,
Pete
I remember, when I tried to create some documentation for this function, I had
also examined the sources (and I did it again now).
My impression is the code is a little "quick and (if not dirty) incomplete".
- it is error prone, since it has no error detection (neither during compile-time nor run-time),
- it returns inconsistent value and , as you correctly saying,
- "performs only half of what traditional loop..."
I cannot guess the intention of the developer who created the function but I can imagine an excuse:
this function mimics the `for(...)` loop of C-language and mimics it very well, in the sense,
that just like in C, the programmer is equally responsible and free either to create good,
bug-free code or to "shoot his foot!"
Besides, the open source code is open not only for use but also open to improvements!
Certainly, the code you suggest is in this direction and, if you wish, please integrate it
in the initial function and post the final result.
regards,
Pete
Re: harbour hb_ functions
Hi, Pete
Yes, I agree with you, code of this function looks "quick and ... incomplete".
Below is my implementation of a function that should work like "for loop" in C (coded in Harbour).
This code is also "quick" and only a little tested.
Syntax "for loop" in C:
hb_ForLikeC() function:
Example of use:
Best regards
Krzysztof (aka KDJ)
PS:
Thank you very much for the excellent documentation: https://github.com/Petewg/harbour-core/wiki
Yes, I agree with you, code of this function looks "quick and ... incomplete".
Below is my implementation of a function that should work like "for loop" in C (coded in Harbour).
This code is also "quick" and only a little tested.
Syntax "for loop" in C:
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
Krzysztof (aka KDJ)
PS:
Thank you very much for the excellent documentation: https://github.com/Petewg/harbour-core/wiki
Re: harbour hb_ functions
Hi Krzysztof,
Though not heavily tested, your code works as expected. (btw, you must be a fan of code-blocks )
Good Harbour-code! I won't stop saying that this language/compiler is an ideal tool
for general purpose programming (particularly for desktop appls and data processing;
you can write excellent code with it.)
My approach regarding the initial hb_ForNex() was to modify the code in C-level
(aiming better speed, but mainly for learning and fun.. -- C is really fun!).
Is not so much sophisticated but hope it's more closer than the original to C `for()` loop
and that it works ok! (please see/try attached source file). Anyhow, since this function is not in a great demand and/or widely used,
I don't know how much useful for users could it be.
regards,
Pete
Though not heavily tested, your code works as expected. (btw, you must be a fan of code-blocks )
Good Harbour-code! I won't stop saying that this language/compiler is an ideal tool
for general purpose programming (particularly for desktop appls and data processing;
you can write excellent code with it.)
My approach regarding the initial hb_ForNex() was to modify the code in C-level
(aiming better speed, but mainly for learning and fun.. -- C is really fun!).
Is not so much sophisticated but hope it's more closer than the original to C `for()` loop
and that it works ok! (please see/try attached source file). Anyhow, since this function is not in a great demand and/or widely used,
I don't know how much useful for users could it be.
regards,
Pete
Re: harbour hb_ functions
I guess I'm not a fan of code blocks.
Simply, in this case code blocks are needed to emulate for() loop of C language.
I created hb_ForLoop() function (in C) that can emulate FOR...NEXT HARBOUR statement or for() loop of C:
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();
}
}
Re: harbour hb_ functions
Very good implementation!I created hb_ForLoop() function (in C) that can emulate FOR...NEXT HARBOUR statement or for() loop of C:
You might consider to push your code to Harbour repository and if so,
you could start by creating an issue in GitHub
BTW, an alternative way to measure time of code execution
is to use relevant hbwin functions (see below):
Code: Select all
wapi_QueryPerformanceCounter( @nCounterStart )
hb_ForNext(nStart, nEnd, bCodeH, nStep)
wapi_QueryPerformanceCounter( @nCounterEnd )
? "Execution time elapsed: ", win_QPCounter2Sec( nCounterEnd - nCounterStart ), " sec."
Pete