Hi...
You probably know that is in Creative Basic possible to jump to
subroutine with string if subroutine name are prefixed by string sign $:
like this:
Def w1:window
def mysub:string
mysub="newsub"
'create main window
openWindow w1,0,0,500,400,@minbox,0,"MainGUI",&main
Setwindowcolor w1,rgb(220,220,220)
'--------------------------------------------------------
gosub $mysub
'---------------------------------------------------------
run=1
waituntil w1=0
end
'-------------------------------------------------------
sub newsub
move w1,20,20:print w1,"OK"
return
endsub
'------------------------------------------------------
Sub main
Select @class
Case @idclosewindow
closewindow w1
Case @idcreate
Centerwindow w1
ENDSELECT
RETURN
ENDSUB
But same program not work in EB/IWB.
Is there a way to do similiar thing in EB/IWB ?
Using this method we can avoid long select/case and directly jump to subroutine.
Any ideas ....?
Aurel,
If you have a SUB named "Aurel" it is enough in IWB just to call Aurel(), as in:
Aurel()
SUB Aurel
Called from Aurel()
ENDSUB
Brian
Not sure what you are ultimately trying to do.
If you are wanting to call different routines at a single point in your program by setting a string to a value and then doing the call I suggest you look at the IWB Help file Language/Subroutines/Indirectly calling subroutines section.
And the indirect_functions.iwb example.
LarryMc
What Brian posted is also correct.
Your code modified where it works in IWB:
Def w1:window
'def mysub:string
'mysub="newsub"
'create main window
openWindow w1,0,0,500,400,@minbox,0,"MainGUI",&main
Setwindowcolor w1,rgb(220,220,220)
'--------------------------------------------------------
mysub()
'---------------------------------------------------------
run=1
waituntil w1=0
end
'-------------------------------------------------------
sub newsub
move w1,20,20:print w1,"OK"
return
endsub
'------------------------------------------------------
Sub main
Select @class
Case @idclosewindow
closewindow w1
Case @idcreate
Centerwindow w1
ENDSELECT
RETURN
ENDSUB
LarryMc
Brian i know this of course....
Yes Larry i want to call muliple subs from one point using string.
You probably see this simple example from CB.
I already look into this example but this works with adresses...
Maby i must be more clear.
So what i want to do is next:
Get sub name from hash table (dictionary) and use this string to call
subroutine.
Quote from: aurelCB on September 21, 2011, 11:18:16 AM
Maby i must be more clear.
So what i want to do is next:
Get sub name from hash table (dictionary) and use this string to call
subroutine.
The only way I know of doing that is creating a SELECT block; unless you can store a pointer to a subroutine in your hash instead of a string.
LarryMc
Uff yes Larry you right there is no way like in CB .
Hmm i dont know but i think that that i can store string pointer in hash.
I will try...
hello,
you need to store an array of pointers like that :
DECLARE fnTemplate
Def w1:window
def mysub[2] as pointer 'string
mysub[0]=&newsub
mysub[1]=&newsub1
'create main window
openWindow w1,0,0,500,400,@minbox,0,"MainGUI",&main
Setwindowcolor w1,rgb(220,220,220)
'--------------------------------------------------------
!<fntemplate>mysub[0]()
!<fntemplate>mysub[1]()
'---------------------------------------------------------
run=1
waituntil w1=0
end
'-------------------------------------------------------
sub newsub
move w1,20,20:print w1,"OK"
return
endsub
sub newsub1
move w1,20,40:print w1,"O0K"
return
endsub
'------------------------------------------------------
Sub main
Select @class
Case @idclosewindow
closewindow w1
Case @idcreate
Centerwindow w1
ENDSELECT
RETURN
ENDSUB
Helo zaphod ...
good idea but not work.
i recive error -> invalid function pointer in this two lines:
!<fntemplate>mysub[0]()
!<fntemplate>mysub[1]()
Your code looks logical to me but still dont work...
Change
def mysub[2] as pointer 'string
to
def mysub[2] as UINT 'pointer 'string
and it should work.
LarryMc
Not work with strings...
hash table (dict) need string not UINT.
so i look into CB source code and find do_gosub structure.
But i simply do not uinderstand how misterP solve this thing:
if(*k=='$')
{
if(!(cv=find_var(k+1))) return(0);
k = (TEXT *)cv->mem;
maby this piece of code is not for this place but im curious how this thing work
in CB.heck ...this looks like adventage of interpreter over compiler ::)
Well it seems that will work with tamplate. :)
Here is code which use hash table:
'by zapHod array of strings as template
DECLARE fn()
'create hash table (dictionary)
strHash=DICTCREATE (100)
Def w1:window
def mysub[2] as uint 'string
'set two uintegers
mysub[0]=&newsub
mysub[1]=&newsub1
'test
MESSAGEBOX 0,"Adrr:"+str$(mysub[0]),"Test sub adress!"
'fill hash with strings
DictAdd(strHash,"s0",str$(mysub[0]))
DictAdd(strHash,"s1",str$(mysub[1]))
'create main window
openWindow w1,0,0,500,400,@minbox,0,"MainGUI",&main
Setwindowcolor w1,rgb(220,220,220)
'--------------------------------------------------------
uint temp
string temp$
'get string from hash table
temp$ = DictLookup(strHash,"s1")
'check if is not empty
IF temp$ <> ""
'set temp variable with subroutine adress
temp=VAL(DictLookup(strHash,"s1"))
IF temp <> 0
'jump indirectly to subroutine
!<fn>temp()
ENDIF
ENDIF
'---------------------------------------------------------
run=1
waituntil w1=0
end
'-------------------------------------------------------
sub newsub
move w1,20,20:print w1,"OK"
return
endsub
sub newsub1
move w1,20,40:print w1,"O0K"
return
endsub
'------------------------------------------------------
Sub main
Select @class
Case @idclosewindow
closewindow w1
Case @idcreate
Centerwindow w1
ENDSELECT
RETURN
ENDSUB
I hope that this will be usefull for anyone of you which have program with
long select/case block . ;)
Just for info...
I don't know that this things exists in old implementation of FORTH language.
his is called direct threaded code (DTC).
from wikipaedia:
To save space, programmers squeezed the lists of subroutine calls into simple lists of subroutine addresses, and used a small loop to call each subroutine in turn.
I am not 100% sure, but take a look at Indirectly calling subroutines, in the User's Guide. It sounds like what you are looking to do.
Bill
Bill problem is solved and work fine ;)