Page 1 of 2
... Operator
Posted: Sun May 03, 2020 3:21 pm
by FlatEarth
One of my dreams:
the
... operator is useful and with a little change if needed, it can increase pb syntax power.
you can see how this operator works in the following codes.
Code: Select all
Procedure max(...)
Protected Dim var_args(...)
Protected mx = var_args(0)
For i=0 To ArraySize(var_args())
If (var_args(i) > mx) : mx = var_args(i) : EndIf
Next
ProcedureReturn mx
EndProcedure
Debug max(22,133,45) ; result --> 133
Debug max(90,88,12,45,677,211) ; result --> 677
Debug max(33,25,233,85,11,231,34,64) ; result --> 233
Of course, I know that we can implement the (Max) algorithm in different ways.
Re: ... Operator
Posted: Mon Jun 08, 2020 12:27 pm
by Olli
; '___' instead of '...'
; array name is Arg()
; be careful to ArgCount which has been defined as a local integer
; -9223372036854775808 for X64
; 2147483648 for X86
; this is a reserved argument value
; only for integers and pointors
; 16 arguments maximum
Code: Select all
;*************************************************************************************
#None = 1 << 63
Macro Ar_
Argument# MacroExpandedCount = #None
EndMacro
Macro ___
Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_, Ar_
For ArgCount = 0 To 15
If PeekI(@Argument1 + ArgCount * SizeOf(Integer) ) = #None
Break
EndIf
Next
Dim Arg.I(ArgCount)
Arg(0) = ArgCount
For ArgCount = 1 To Arg(0)
Arg(ArgCount) = PeekI(@Argument1 + (ArgCount - 1) * SizeOf(Integer) )
Next
ArgCount ! (0
EndMacro
;- Syntax example
Procedure Test(___)
For I = 1 To Arg(0)
Debug Arg(I)
Next
EndProcedure
Test(1,2,5,10,20)
Re: ... Operator
Posted: Mon Jun 08, 2020 2:26 pm
by Derren
I have never seen a "..." operator used in such a way.
I think it's confusing. In other languages "..." can be used to ommitt redundant data, for example if you want the 1st, 4th, 5th, 6th, 7th and 11th element, you can write something like "1, 4...7, 11"
Implicit Array creation and population would be more verstatile and can achieve the same.
Code: Select all
Procedure Max( Array args(1) )
For i = 0 to ArraySize(args())-1
;..
Next
EndProcedure
Debug Max( [1, 2, 5, 12])
As much as I love PB, this kind of ineffienct code is what annoys me beyond belief.
Re: ... Operator
Posted: Mon Jun 08, 2020 3:34 pm
by Olli
Added to
trick and tips
I did not understand the link but we could find this :
Code: Select all
For i = 0 To 2
j = 1 << i - 1
k = 1 << j + Bool(j & 2)
Next
For the rest of you request, it seems that mk-soft made something for trick and tips (just no nested in a arguments set, but from directly to arrays).
Re: ... Operator
Posted: Tue Jun 09, 2020 1:42 am
by Rinzwind
Yes inline array initialization is a must have and severely missing from pb. Some api’s depend on null terminated string arrays which are a pain to pass with pb. Some c code looks so ugly and lengthy when converted to pb because of this. What about array lookup tables defined in source? Also helps with procedures indeed because we dont have varargs too.
Re: ... Operator
Posted: Tue Jun 09, 2020 8:12 pm
by Olli
Rinzwind wrote:What about array lookup tables defined in source?
Did you try this ?
Strings table
Re: ... Operator
Posted: Fri Jun 12, 2020 5:32 pm
by mk-soft
PB copy the parameter to the stack in right order.
Code: Select all
;-TOP
#None = 1 << (SizeOf(integer) -1)
; Max 8 parameters
Macro iArgs
Arg1=#None,Arg2=#None,Arg3=#None,Arg4=#None,Arg5=#None,Arg6=#None,Arg7=#None,Arg8=#None, ArgEnd=#None
EndMacro
;- Syntax example
Procedure Sum(iArgs)
Protected *arg.integer = @Arg1 ; Get pointer to the first parameter
Protected r1
While *arg\i <> #None
r1 + *arg\i
*arg + SizeOf(integer) ; Set pointer to the next parameter (Allways size of integer)
Wend
ProcedureReturn r1
EndProcedure
sum = Sum(1,2,5,10,20)
Debug sum
Re: ... Operator
Posted: Fri Jun 12, 2020 8:49 pm
by Olli
Deutsch Qualität

Re: ... Operator
Posted: Sun Jun 21, 2020 10:20 am
by User_Russian
Code: Select all
Structure ArrI
i.i[0]
EndStructure
ProcedureC Test(Count)
Protected *Param.ArrI=@Count+SizeOf(Count)
Protected i
PrintN("Count = "+Count)
Print("Parameters: ")
For i=0 To Count-1
Print(Str(*Param\i[i])+" ")
Next
PrintN(#CRLF$+"----")
EndProcedure
OpenConsole()
CallCFunctionFast(@Test(), 2, 1, 2)
CallCFunctionFast(@Test(), 10, 2, 8, 20, 100, 4, 1234, 10000, 10, 16, 80)
Input()
Re: ... Operator
Posted: Mon Jun 22, 2020 12:44 am
by Demivec
User_Russian wrote:Code: Select all
Structure ArrI
i.i[0]
EndStructure
ProcedureC Test(Count)
Protected *Param.ArrI=@Count+SizeOf(Count)
Protected i
PrintN("Count = "+Count)
Print("Parameters: ")
For i=0 To Count-1
Print(Str(*Param\i[i])+" ")
Next
PrintN(#CRLF$+"----")
EndProcedure
OpenConsole()
CallCFunctionFast(@Test(), 2, 1, 2)
CallCFunctionFast(@Test(), 10, 2, 8, 20, 100, 4, 1234, 10000, 10, 16, 80)
Input()
Nice to see some undocumented behavior (at least to my knowledge).
But try your method without any parameters.
Re: ... Operator
Posted: Mon Jun 22, 2020 4:06 am
by Josh
Demivec wrote:But try your method without any parameters.
If you try to understand the code from
User_Russian, the two given examples result in a rule according to which a
CallCFunctionFast(@Test()) is not allowed, but only a
CallCFunctionFast(@Test(),0).
Re: ... Operator
Posted: Mon Jun 22, 2020 4:51 am
by Demivec
Josh wrote:Demivec wrote:But try your method without any parameters.
If you try to understand the code from
User_Russian, the two given examples result in a rule according to which a
CallCFunctionFast(@Test()) is not allowed, but only a
CallCFunctionFast(@Test(),0).
The rule is implied but is neither stated nor enforced.
The documentation for CallCFunctionFast() dictates that all other parameters after the function address are optional.
Since I was unaware that the number of parameters was passed at all I would invite the sharing of any other details as to what is being passed. Apparently the number of parameters being passed is not pushed on the stack if the number is zero. I would appreciate any additional information or reference that I can look to to dig up any other info that doesn't want to be shared here.
Re: ... Operator
Posted: Mon Jun 22, 2020 6:44 am
by Josh
I'm not quite sure if it is because of my lack of English skills or if it is actually possible that the rule resulting from the two examples cannot be recognized.
Yes, the rule is implicit, is not stated, but is enforced and should be recognizable at a glance. In any case, it has absolutely nothing to do with the fact that for CallFunctionFast() all parameters are optional, it has only to do with how the procedure Test() has to be called. If you look at the procedure, you will see that the first parameter is used as number of following parameters. This can also be seen in the procedure call. So it should be self-explanatory that a 0 is to be passed as a parameter for zero following parameters.
You don't have to suspect a big miracle behind every code, just read what is written there and the miracle becomes a simple code as if by a miracle.
Re: ... Operator
Posted: Mon Jun 22, 2020 7:24 am
by Demivec
Josh wrote:I'm not quite sure if it is because of my lack of English skills or if it is actually possible that the rule resulting from the two examples cannot be recognized.
Yes, the rule is implicit, is not stated, but is enforced and should be recognizable at a glance. In any case, it has absolutely nothing to do with the fact that for CallFunctionFast() all parameters are optional, it has only to do with how the procedure Test() has to be called. If you look at the procedure, you will see that the first parameter is used as number of following parameters. This can also be seen in the procedure call. So it should be self-explanatory that a 0 is to be passed as a parameter for zero following parameters.
You don't have to suspect a big miracle behind every code, just read what is written there and the miracle becomes a simple code as if by a miracle.
Thanks for your explanation. I have a high opinion of your comprehension and use of the English language and do not believe that enters into things at all here.
I tested the sample code by not passing any optional parameters to discern if a count of zero would be passed as it did with any number of other optional parameters. It did not. I am not familiar with this aspect of things when using the CallCFunctionFast() procedure or that one could take advantage of it as User_Russian did. I do understand the procedure's function and what it is trying to accomplish and that was never a part of my question.
I am still wondering about any documentation for the 'count for the optional parameters' being passed as the first parameter on the stack or not, followed by the optional parameters. Do you have any information on this or any other aspect of the CallCFunctionFast() that is not in the PureBasic Help?
Re: ... Operator
Posted: Mon Jun 22, 2020 7:53 am
by Josh
Demivec wrote:Do you have any information on this or any other aspect of the CallCFunctionFast() that is not in the PureBasic Help?
Don't think so complicated. User_Russian passes the number of following parameters as the first parameter when calling the procedure
Test() and the procedure evaluates this again. There is no miracle behind this.
CallCFunctionFast(@Test(),
2, 1, 2)
CallCFunctionFast(@Test(),
10, 2, 8, 20, 100, 4, 1234, 10000, 10, 16, 80)