Suggestions for porting old sequential BASIC code?

BlitzMax Forums/BlitzMax Beginners Area/Suggestions for porting old sequential BASIC code?

pmc(Posted 2008) [#1]
I'm looking for suggestions on how best to port some very old sequential BASIC code. It looks like something like this:


var=1
print "what now?"
input q
if q=2 then goto 500
if q=3 then var=var+1
print "that's nice, now what?"
input q
if q=1 then gosub 700
var2=var+var*2
goto 300
etc.



I flow-charted the program and it's pretty nutty with subroutines and goto statements. I can rewrite alot of it, but would rather just try to preserve the logic to make it easier.

So what I did was to put each of the response lines (the print statements) into a list. I rewrite the list in response to the input from the user (the input statements). I use a regular While Not KeyDown(KEY_ESCAPE) loop to refresh the graphics window. The only thing moving on the screen is the input command line (my code for "input q"). You enter a command, hit enter, and based on what you entered, I refresh the list and the screen gets refreshed (the output "print" stuff).

What I'm not sure about is how get the sequential flow control logic (if then, goto gosub etc.) to fit in the context of the continuous While loop.

What I'm thinking is that I need to write a command parser and then just jump out to a function depending on what the input command is. So the original code (minus the input and output parts) just gets mapped to a series of functions. Then I'd have to write some code to determine where in the original program logic I am at any given time.

I don't see a need to oopify this.

Is there a standard approach for something like this?

-pmc


CS_TBL(Posted 2008) [#2]
I'd just ditch the old geeky code and do a complete rewrite in Max in a proper style. I even do that with older Blitz code sometimes, let alone stone-age BASIC.


Xerra(Posted 2008) [#3]
It took me ages to get used to dumping goto and gosub when I first came to Blitz but it does encourage neater programming. In fact I think you can't even use those commands in strict mode. I'm with what the previous poster said. It's far easier to just rewrite the program than try and write some kind of structure to run it with few changes.

From a quick glance you could adapt what i can see with some if/endif statements and still keep it both readable and tidy.


CS_TBL(Posted 2008) [#4]
Goto and Gosub are just legacy from a time when there was no real procedural programming in BASIC and no neat scopes for programflow, no need to have those museum pieces around these days..

If a
..
..
Endif

beats

10 If a=0 goto 40
20 ..
30 ..
40 (continue)

if you ask me..


pmc(Posted 2008) [#5]
Yeah... well that's one reason I wanted to try this. I used to write BASIC code back in the day. I had forgotten how crazy the flow control could get. My question is more about what to consider when doing the rewrite: how to move from a top down flow and map that into a modern event loop. The two are so different that I wasn't sure how to even approach it. Modern games are all user driven. But the old ones were generally top down with pauses to get user input to influence flow control.

I thought about it some more and it occurs to me that I'm approaching it backwards. I was going to build a main event loop and then jump out to several functions to execute the game logic. But I think it makes more sense to just jump out to an event loop function that draws the graphics and does the IO whenever I need user input. That function loops until I get a response. Then I go back to main procedural code. The old procedural BASIC code will execute so fast that you wouldn't notice the time outside of the event loop function.

I can still use a "While Not KeyDown(KEY_ESCAPE)" loop for overall application, and "While Not KeyDown(KEY_ENTER)" loop while waiting for user input.

And yeah, I'm dumping all the GOTO and GOSUBs and all that and converting to modern code. But the logic remains the same because I want the same application in the end.

-pmc


Sledge(Posted 2008) [#6]
What I'm thinking is that I need to write a command parser and then just jump out to a function depending on what the input command is. So the original code (minus the input and output parts) just gets mapped to a series of functions.

That's not an unreasonable solution -- one possible way to (begin to) implement it has been discussed here.


pmc(Posted 2008) [#7]
Thanks for the link. It got me thinking about alternatives -- some of the examples could work for me.

So far I've created a list for outputs. And based on the program logic, I just change the elements of the list which gets displayed at the next screen update. Works like a champ.

The real problem continues to be how to nest the sequential logic into an event loop. I continue to try variants and so far haven't had success.

Bottom-line: the event loop goes round and round a zillion times per second to keep everthing on-screen current. But the code logic goes top to bottom and branches left and right based on the input of the user. These two concepts seem incompatible.

I had no idea this would become such a puzzle for me but I'm enjoying the challenge despite that.

-pmc


Sledge(Posted 2008) [#8]
The real problem continues to be how to nest the sequential logic into an event loop. I continue to try variants and so far haven't had success.

That's because you've moved on from hard-coding logic to thinking about something that's more like an engine from which you can make your content distinct, which is a significant leap.

I made progress on something in a similar vein (a multiple choice adventure thingy) and it worked by using TMap entries as function pointers, each function being a 'location' that was allowed to use a set of sub-functions as a sort of scripting language. (Scripting within BlitzMax source files is obviously not ideal as having to compile scripts defeats part of the object of using them but it was more expedient than writing a LUA interface). BUT ANYWAY, for something like that the game-loop basically goes...

While...
>Run the script for the current location.
>(The location script says 'show this text and present these options').
>Check if the user picked an option and if so alter the current location.
...Wend

...which is very simple because the system was essentially a retarded form of hypertext, but hopefully it gives you a sense of how to start separating the engine from the content. The first step is really to plan out and identify everything that needs to be supported by the engine (much as it is tempting to just dive in and code) because once you know that you're in a much better position to decide how the content should be stored and processed.


pmc(Posted 2008) [#9]
Yup. I wound up doing something similar. I wrote a function for each section of the original code and then just used a variable to track the current "place" in the game. Not a location like you, but the place in the sequential program. Then I just run the event loop continuously just like an arcade game. Every time the user hits Enter, it sends the current input off to the correct function for processing. I update the output list as part of the function and the event loop dutifully keeps the graphics up to date.

So in the end, I actually just mapped the sequential logic into a series of functions and just call them from the event loop every time the user hits Enter.

Took me a while to get my head wrapped around how to get those two concepts to work together. Too long writing arcade stuff I guess.

Maybe I'll start to work on Zork when I'm done with this one. :)

Thanks for the help.

-pmc