How to create and use a list of labels?

BlitzMax Forums/BlitzMax Beginners Area/How to create and use a list of labels?

ImaginaryHuman(Posted 2004) [#1]
Hi folks. I wish to use several GOTO calls, to a selection of several routines that are organized by labels. For example:

Goto Routine1
#BackToBeginning
End

#Routine1
'Add some program lines here
Goto Routine3

#Routine2
'Add some program lines here
Goto Routine 4

#Routine3
'Add some program lines here
Goto Routine 2

#Routine4
'Add some program lines here
Goto BackToBeginning


What I want to be able to do is, at runtime, change which labels are jumped to with each of the Goto's in each routine, so that the routines can run in a different order.

I was hoping that maybe you could use labels in the same way as function pointers so that you can dynamically change the pointers. ie something like this:

FirstRoutine=Routine3
SecondRoutine=Routine2
ThirdRoutine=Routine4
FourthRoutine=BackToBeginning
Goto Routine1
#BackToBeginning
FirstRoutine=Routine4
FourthRoutine=Routine2
SecondRoutine=BackToBeginning2
Goto Routine1
#BackToBeginning2
End

#Routine1
'Add some program lines here
Goto FirstRoutine

#Routine2
'Add some program lines here
Goto SecondRoutine

#Routine3
'Add some program lines here
Goto ThirdRoutine

#Routine4
'Add some program lines here
Goto FourthRoutine


Will this work (any hope in h***?) ... and if not, is there a way to get this to work (efficiently and with the least code possible)? I need to be able to rearrange the order in which the routines are performed and this needs to NOT use functions - it must be GOTO's. ????????

Furthermore, would it then be possible to create an array or bank containing a list of the Label pointers so that they you can Goto Routine[i]? (or something like that)???

Thanks in advance.


Kanati(Posted 2004) [#2]
I'll have to look at this after I get back from lunch...

But GOTO is evil. Avoid it whenever possible.


Warren(Posted 2004) [#3]
But GOTO is evil. Avoid it whenever possible.

*sigh*


ImaginaryHuman(Posted 2004) [#4]
Umm ... I NEED to use the GOTO in this case. That's a given. What I need to figure out is how to change where the Goto goes to.

I think there was a command in Amos Basic that let you jump to a label by supplying a string parameter that contained the name of the label. But I'm sure there isn't anything like that in blitz, and strings aren't very quick.

I also don't want to have to use a bunch of if's or a case-select.

It must be Goto (I know what I'm doing, thanks), I just am not sure about whether labels can be changed at runtime.


xacto(Posted 2004) [#5]
What you're tyring to do, AFAIK is not possible, sorry.

However, even though you assert Goto is required, might I offer an alternative solution?



This code is equivalent to what you're trying to accomplish with the Gotos. Each label, in your example, now becomes a subclass of Functor with a procedural method, Run that does something. Using a TList or Array you can organize the steps any way you like and can even quickly change their sequence at runtime with little overhead.


Perturbatio(Posted 2004) [#6]
could this not be done in a much nicer way with a simple Select..Case?


jhague(Posted 2004) [#7]
You could end each function with a jump through a function pointer. Then you can set those pointers to whatever you want, altering the flow.

Generalized, a pretty solution is to have an array of function pointers. Then you loop through the array and call each function. If you want to change the order or call different functions, just modify the array.


EOF(Posted 2004) [#8]
I think that Amos stuff might have been 'On var Goto' ???
It's worth pointing out that Goto does not work in Strict mode either.


ImaginaryHuman(Posted 2004) [#9]
Hmm. Well, the method idea is nice looking. I'm still getting used to this OO stuff but I do follow it (just). And I understand the linked list part. But the assembler programmer in me is making noise about how efficient this can be, surely handling linked lists, arrays and methods (and functions for that matter) is in general going to be slower than the Goto method.

I am basically saying to use Goto's because I need `program flow` to flow THROUGH several sections of code rather than all the wasted overhead of passing parameters and storing stuff on the stack and the extra math involved in using lists and arrays. This is for a VERY tight highly time-critical piece of code, perhaps THE most critical piece in the entire application, and needs to be very efficient.

I kinda felt that the dynamic labels probably wouldn't work unless Mr Sibly had built in some kind of function-pointer-like support for that.

As to using case-select, that's slow too, it has to do a bunch of comparisons just to decide where to go. I want this more hardwired so that program flow automatically flows to the right place without the compare operations. Also, I can't really write a select-case because I have no idea how many sections are going to be needed - it could be hundreds - I'm not going to have it go through hundreds of comparisons trying to find the right one to execute.

Maybe Mark could add a new type - label pointers, and allow us to do label arithmetic. It would help for jump-tables too. Then I could do something like:

Goto Label[18]
' or
Goto Label[18]+12


I guess if BlitzMax also had linenumbers you could Goto a line number, then Goto would accept an expression like Goto jumpline (a variable containing the line number).

Any other ideas? I guess labels can't be changed at runtime due to the fact that they probably get remapped when the exe is loaded by the o/s depending on where in memory the app is stored, so they aren't fixed?


xacto(Posted 2004) [#10]
The First Rule of Optimization: Don't optimize early.
The Second Rule of Optimization: See First Rule.

Seriously, why not try one of the alternatives here. Make it work, first. Then, once you've been able to instrument working code, determine where performance bottlenecks might be.

I've looked over the assembly code generated by Mark's compiler and it's very tight. Not quite as efficient, yet, as say Visual C++ but very, very close.


ImaginaryHuman(Posted 2004) [#11]
Thanks for the advice ... *rolls into Frank Sinatra impression "I'll do it myyyyyy waaaaaay"* lol

For me,...

1st rule of optimization: Optimization is a myth created by people who can't get the language to do what they want efficiently enough the first time. ;-)

2nd rule of optimization: If you see an optimization opportunity in hindsight, rethink everything.

3rd rule of optimization: Being indirect creates middle-man code, make everything direct in the first place - direct is faster.

4th rule of optimizaiton: Don't let the code define the design, it only works the other way around.

5th rule of optimization: Enough rules already.

Seriously though, maybe I don't work quite the same way as you. Rather than code something first in a given form and seek to optimize it later, I prefer to see exactly in my mind's eye how the system will work best and until that vision is complete I don't commit it to code. Then, writing the code is just a matter of committing it to paper. I see end results before they exist and just sit back to allow the rest (in the physical realm) to catch up, that's how my creativity works. For me the idea of creating a program and then looking at it and saying, hmm, I wonder if there's a better way to do that, is like saying "This program isn't born from a vision, it's born from a reaction". But that's just me. I am a creator, not a regurgitator.

Also, I'm fairly sure these other methods suggested will work, but I also know they aren't quite what I'm looking for. Maybe I should spill the beans on what I'm trying to do with this Goto stuff.

Imagine a Co-processor whose circuity can be reprogrammed by the user - these exist already in hardware. What I want to do is make an area of my software program that acts like a re-programmable circuit. By changing which labels are jumped to I would be able to `re-wire` the circuit. After it's been rewired, program flow goes through it in a sequential manner without any extra stacks or retuns from functions or if's or whatever else. That area of my software should, once set to a given state, act in a particular way as if it were almost hardcoded in that configuration. So yes, I could use functions or methods or whatever else, but I need to remove the if's, the gosubs, the functions, the methods, the case-selects and other such decision-making flow-diverting stuff, so I just end up with a fluid adjustable `circuit` that, when jumped to, performs whatever set of operations I've programmed it to do, at runtime. The only way I can see to do that, efficiently, is with Goto's, except as we know, maybe BlitzMax doesn't support what I'm trying to do.


Kanati(Posted 2004) [#12]
Obviously Warren doesn't think GOTO is evil. Well, to each their own.

Hmm. Well, the method idea is nice looking. I'm still getting used to this OO stuff but I do follow it (just). And I understand the linked list part. But the assembler programmer in me is making noise about how efficient this can be, surely handling linked lists, arrays and methods (and functions for that matter) is in general going to be slower than the Goto method.


That I'll agree with. Obviously mucking about in a linked list isn't going to be nearly as fast as a single JMP xxx. But from a readability standpoint (which is what I like personally)... Goto is still evil. :)

I like the function pointers idea... Think that might be your best bet.


ImaginaryHuman(Posted 2004) [#13]
I understand the function pointers idea and that is something else I will be doing, but for a different application. I need to remove all the function-call overheads, storing stuff on stacks, returning values, if's, case's, selects, all that stuff shouldn't be needed.

Yes for readability I'd say Goto's aren't so great, but they are still useful.