Page 1 of 3
[Resolved] Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 1:37 pm
by Kwai chang caine
Hello at all
I try to call procedure by name without examine before the number of parameters to send
It's really difficult for me, i have search to do it under this format without succes
Code: Select all
CallProcedure(NameOfProcedure$, Param1$, Param2$)
then the best method i have found is sending all the parameters in one variable
Code: Select all
AllParametersInOneVariable$ = "Param1, Param2"
CallProcedure(NameOfProcedure$, AllParametersInOneVariable$)
And i don't understand why...i have an error when the array is freeing
Code: Select all
Prototype AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")
Runtime Procedure MessageOneParameter(Text.s)
MessageRequester("Only one Parameter", Text)
EndProcedure
Runtime Procedure MessageTwoParameters(Text1.s, Text2.s)
MessageRequester("Two parameters", Text1 + Text2)
EndProcedure
Runtime Procedure MessageThreeParameters(Text1.s, Text2.s, Text3.s)
MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure
Procedure CallProcedure(NomProcedure.s, Parameter$)
*PtrProc = GetRuntimeInteger(NomProcedure + "()")
Call.AllMessages = *PtrProc
MaxParam = CountString(Parametre$, ",") + 1
Protected Dim ArrayParams.s(MaxParam)
For i = 1 To MaxParam
ArrayParams(i) = StringField(Parameter$, i, ",")
Next
Select MaxParam
Case 1
Call(ArrayParams(1))
Case 2
Call(ArrayParams(1), ArrayParams(2))
Case 3
Call(ArrayParams(1), ArrayParams(2), ArrayParams(3))
EndSelect
FreeArray(ArrayParams())
EndProcedure
CallProcedure("MessageOneParameter", "Hello it's KCC")
CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
If someone understand why
Have a good day
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 1:47 pm
by NicTheQuick
What is your main reason to do this? It doesn't sound well thought out.
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 2:41 pm
by Kwai chang caine
Hello NICKTHEQUICK
Thanks to your answer
It doesn't sound well thought out.
Not good thinking = KCC
I fact i try to do a type of Script langage, i want to call my procedures, but with text
Sure i can analyse the command, and do like this :
Code: Select all
Command$ = "CallProcedure('MessageOneParameter', 'Hello it\'s KCC')
Param1$ = StringField(Command$, 1, etc ...)
Param2$ = StringField(Command$, 2, etc ...)
Param3$ = StringField(Command$, 3, etc ...)
Select StringField(Command$, 1, "(")
Case "MessageOneParameter"
MessageRequester("Only one Parameter", Param1$)
Case "MessageTwoParameters"
MessageRequester("Two parameters", Param1$ + Param2$)
Case "MessageThreeParameters"
MessageRequester("Three parameters", Param1$ + Param2$ + Param3$)
Case etc ...
etc ...
....
....
EndSelect
But i have thinking it's more simple, furthermore readable, to create one procedure by function and call each procedure by is name

It's simple to do if the command not have parameters
Code: Select all
Runtime Procedure Message1(Texte.s)
MessageRequester("Premiere commande", Texte)
EndProcedure
Runtime Procedure Message2(Texte.s)
MessageRequester("Deuxieme commande", Texte)
EndProcedure
Procedure AppelProcedure(NomProcedure.s, Param$)
*PtrProc = GetRuntimeInteger(NomProcedure + "()")
CallFunctionFast(*PtrProc, @Param$)
EndProcedure
AppelProcedure("Message1", "A que le premier coucou")
AppelProcedure("Message2", "A que le second coucou")
But like i don't know the numbers of parameters, and like all my procedure not have the same number of parameters, it's really more hard to do
And i don't really understand, all this history of MACRO/Prototype

Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 2:44 pm
by Papala
Code: Select all
Structure info
FonctionName.s
info1.s
info2.s
EndStructure
Prototype Function(*data.info)
Runtime Procedure Function1(*data.info)
Debug *data\info1
Debug *data\info2
EndProcedure
Runtime Procedure Function2(*data.info)
Debug *data\info1
Debug *data\info2
EndProcedure
Procedure LaunchProcedure(*data.info)
Protected ProcedureName.Function = GetRuntimeInteger(*data\FonctionName + "()")
ProcedureName(*data)
EndProcedure
Define Info.info
info\FonctionName = "Function1"
info\info1 = "Info 1 from function1"
info\info2 = "info 2 from function1"
LaunchProcedure(@info)
info\FonctionName = "Function2"
info\info1 = "Info 1 from function2"
info\info2 = "info 2 from function2"
LaunchProcedure(@info)
Hu ??
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 2:49 pm
by Kwai chang caine
Thanks PAPALA
Your code works very well...i take a look and try to understand

Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 2:54 pm
by Papala
Nothing hard to understand, I just send the memory adresse of a structured variable as argument.
If you need more argument to pass to your procedure, just add theim to the structure.
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 3:03 pm
by Derren
To call a procedure by name, you can use the Runtime Library.
For an undetermined number of parameters, either use an array, a map or a linked list, or a string that you parse. for example JSON or XML, since PB already provides parsers for these.
Code: Select all
Runtime Procedure test(myParam.s)
;parse JSON (myParam)
ProcedureReturn 123
EndProcedure
*proc = GetRuntimeInteger("test()")
Debug *proc("{'a':'hello', 'b':'world'}") ;should be "123"
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 3:06 pm
by Kwai chang caine
Yes i have modify your code for understand better and adapt to my need

And apparently that can be a better solution for my problem
Again thanks
Code: Select all
Structure info
info1.s
info2.s
info3.s
info4.s
info5.s
EndStructure
Prototype Function(*data.info)
Runtime Procedure Function1(*data.info)
Debug *data\info1
Debug *data\info2
EndProcedure
Runtime Procedure Function2(*data.info)
Debug *data\info1
Debug *data\info2
EndProcedure
Procedure LaunchProcedure(NameOfProcedure.s, Param1.s = "", Param2.s = "", Param3.s = "", Param4.s = "", Param5.s = "")
Datas.info
Datas\info1 = Param1
Datas\info2 = Param2
Datas\info3 = Param3
Datas\info4 = Param4
Datas\info5 = Param5
Protected ProcedureName.Function = GetRuntimeInteger(NameOfProcedure + "()")
ProcedureName(@Datas)
EndProcedure
Define Info.info
LaunchProcedure("Function1", "Info 1 from function1")
LaunchProcedure("Function2", "Info 1 from function2", "info 2 from function2")
@DERREN
Hello
Code: Select all
Debug *proc("{'a':'hello', 'b':'world'}") ;should be "123"
Waouh !!!! i not thinking to this solution
Thanks too for your help

Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 3:49 pm
by Marc56us
I try to call procedure by name without examine before the number of parameters to send
But why do such complicated things?
Why not create a global list, then browse through it in the procedure and finally delete it after use?
"
Think simple"

Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 4:15 pm
by Kwai chang caine
@DERREN
I have adapting the PAPALA code with your method
Code: Select all
Prototype Function(Json.s)
Procedure ReadJson(Json.s)
If ParseJSON(0, Json)
ObjetValeur = JSONValue(0)
If ExamineJSONMembers(ObjetValeur)
While NextJSONMember(ObjetValeur)
Debug JSONMemberKey(ObjetValeur)
Wend
EndIf
Else
Debug JSONErrorMessage()
EndIf
EndProcedure
Runtime Procedure Function1(Json.s)
ReadJson(Json)
EndProcedure
Runtime Procedure Function2(Json.s)
ReadJson(Json)
EndProcedure
Procedure LaunchProcedure(NameOfProcedure.s, Param1.s = "", Param2.s = "", Param3.s = "", Param4.s = "", Param5.s = "")
Json$ = "{"
Json$ + Chr(34) + Param1 + Chr(34) + ":0,"
Json$ + Chr(34) + Param2 + Chr(34) + ":0,"
Json$ + Chr(34) + Param3 + Chr(34) + ":0,"
Json$ + Chr(34) + Param4 + Chr(34) + ":0,"
Json$ + Chr(34) + Param5 + Chr(34) + ":0"
Json$ + "}"
Protected ProcedureName.Function = GetRuntimeInteger(NameOfProcedure + "()")
ProcedureName(Json$)
EndProcedure
LaunchProcedure("Function1", "Info 1 from function1")
LaunchProcedure("Function2", "Info 1 from function2", "info 2 from function2")
Marc56 wrote:"Think simple"
And again, if you knew how I simplified what came out of the "bidet"

that serves as my brain

It's always those who have the least knowledge who think the most

Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 4:35 pm
by CELTIC88

with asm 32bit
Code: Select all
Structure info
FonctionName.s
List parameterslist.i()
EndStructure
Runtime Procedure Function0()
Debug "pas de parameteres ;)"
EndProcedure
Runtime Procedure Function1(par1)
Debug PeekS(par1)
EndProcedure
Runtime Procedure Function2(par1,par2)
Debug par1
Debug par2
EndProcedure
Procedure LaunchProcedureasm(Fonction,parameterslist,numparameters)
!mov esi, dword [p.v_parameterslist]
!mov ecx, dword [p.v_numparameters]
!mov ebx, dword [p.v_Fonction]
!test ecx,ecx
!jz ._SKIP
!@@:mov eax, [esi + ecx * 4 - 4]
!push eax
!loop @b
!._SKIP:call ebx
EndProcedure
Macro LaunchProcedure(func,parameterslist)
LaunchProcedureasm(GetRuntimeInteger(func),@parameterslist,ArraySize(parameterslist))
EndMacro
Dim parameterslist(2)
parameterslist(0) = 1
parameterslist(1) = 2
LaunchProcedure("Function2()",parameterslist())
ReDim parameterslist(1)
parameterslist(0) = @"wow it works"
LaunchProcedure("Function1()",parameterslist())
ReDim parameterslist(0) ; pas de parameteres
LaunchProcedure("Function0()",parameterslist())
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 4:50 pm
by Kwai chang caine
Hello CELTIC
Waooouuuhh !!!
This time...with the great ASM...even not i try to understand

Thanks a lot for this great piece of code my friend

Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 5:24 pm
by Derren
If you have a procedure with many optional parameters in the first place, why the need for json or any other type of structured data?
You can just put everything minus the json-parser directly into your "Launch" procedure. why not?
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 5:40 pm
by Kwai chang caine
Excuse me DERREN, but i don't really understand what you mean
Have you see what i have do with your idea and PAPALA code
viewtopic.php?p=530208#p530208
In fact, my dream is simple, but like all simples things in programming, it's often very hard to obtain
In one world...
A 4X4 "all-ground" function
Just one call
Code: Select all
LaunchProcedure(NameOfTheProcedure$, [Param1$, Param2$, Param3$, etc...])
Like this i can call, without take care :
Code: Select all
LaunchProcedure("ProcedureWithoutParameter")
LaunchProcedure("ProcedureOneParameter", "The first parameter")
LaunchProcedure("ProcedureTwoParameters", "The first parameter", "The second parameter")
LaunchProcedure("ProcedureTwoParameters", "The first parameter", "The second parameter", etc .....)
Re: Call procedure with several parameters by name
Posted: Wed Dec 12, 2018 10:01 pm
by the.weavster
This is loosely based on JSON-RPC:
Code: Select all
Prototype.s Function(js.s)
Procedure.s JM_GetMethod(jsID)
ProcedureReturn GetJSONString(GetJSONMember(JSONValue(jsID),"method"))
EndProcedure
Procedure.i JM_GetParamCount(jsID)
elem = GetJSONMember(JSONValue(jsID),"params")
ProcedureReturn JSONArraySize(elem)
EndProcedure
Procedure.s JM_GetParamString(jsID,idx)
elem = GetJSONMember(JSONValue(jsID),"params")
ProcedureReturn GetJSONString(GetJSONElement(elem,idx-1))
EndProcedure
Procedure.i JM_New(methodName.s)
nJS = CreateJSON(#PB_Any)
If nJS
ObjectValue = SetJSONObject(JSONValue(nJS))
SetJSONString(AddJSONMember(ObjectValue,"method"),methodName)
SetJSONArray(AddJSONMember(ObjectValue,"params"))
ProcedureReturn nJS
Else
ProcedureReturn -1
EndIf
EndProcedure
Procedure.i JM_Parse(js.s)
ProcedureReturn ParseJSON(#PB_Any,js)
EndProcedure
Procedure JM_Run(js.s)
jsID = JM_Parse(js)
mtd.s = JM_GetMethod(jsID) + "()"
Protected ProcedureName.Function = GetRuntimeInteger(mtd)
Debug ProcedureName(js)
EndProcedure
Procedure JM_SetParamString(jsID,pval.s)
elem = GetJSONMember(JSONValue(jsID),"params")
SetJSONString(AddJSONElement(elem),pval)
EndProcedure
Runtime Procedure.s SayStuff(js.s)
jsID = JM_Parse(js)
ProcedureReturn "There's a hell of a smell in " + JM_GetParamString(jsID,1) + " " + JM_GetParamString(jsID,2)
EndProcedure
nJS = JM_New("SayStuff")
JM_SetParamString(nJS,"Dingly")
JM_SetParamString(nJS,"Dell")
js.s = ComposeJSON(nJS,#PB_JSON_PrettyPrint)
Debug js
Debug ""
JM_Run(js)