Do you miss GO TO? I hope you dont, as it and its sibling, GO SUB, helped to condemn BASIC to Spaghetti-Hell. I must admit I sometimes miss the two variants ON <expr> GO TO <list of lno's> and ON <expr> GO SUB <list of lno's>! (But not that much.)
Since I started programming in SBASIC, with QD as my primary S*BASIC editor, I never used GO TOs again. Apart from all the other good reasons not to, the lack of automatic line numbering functionality - or line numbers at all - made it virtually impossible. It wouldnt have been so bad if S*BASIC had implemented named LABels, then at least the odd GO TO or ON .. GO SUB might have come in handy once in a while.. So I wondered if there was a way of creating synthetic labels in S*BASIC. (A completely different, and valid, approach is taken by SuperBASIC Linker [SBL], but thats not the point here.)
Of course there is no such thing as a line-number-less S*BASIC program. The numbers still have to be there to make it a valid program, otherwise the interpreter takes it to be an immediate command. So editors that allow you to execute aparently line-number-less programs directly, such as QD (and my SBldr), actually just add the numbers 1, 2, 3.. to each line before execution. Heres the proof: Run this program, without line numbers, directly from QD using the SBAS/QD Thing.
ch = FOPEN("con_"): CLS#ch : GO SUB 10 GO SUB 11 GO SUB 12 PAUSE#ch QUIT : REMark Ensure the next line is the tenth line PRINT#ch; 'Line 10': RETurn PRINT#ch; 'Line 11': RETurn PRINT#ch; 'Line 12': RETurn
What it suggests is that some form of labelling should be possible..
SBASIC has many advantages over the old SuperBASIC but it comes at the price of loosing some treasured old PEEKs into the BASIC Variables Area. Gone are the days when a simple BASIC_W%(104) would return the current line number! (BASIC_W% is from the Turbo Toolkit, BTW.)
On the positive side, we no longer require BASIC_XX to do such business as remains: PEEK_W(\\ offset)
does the
trick! (See FindTheKey and DeHex for some examples, if you like..)
In SuperBASIC (ie under Qdos) you could just do something like in the snippet below. However, it cannot be compiled: Turbo protests about line numbers as variables, and QLib doesnt support the interpreter's line number structure.
10 REMark Declare the labels.. 12 MyLabel1 = Label1 14 MyLabel2 = Label2 16 MyLabel3 = Label3 18 : 30 REMark Execute program.. 32 GO SUB MyLabel1 34 GO SUB MyLabel2 36 GO SUB MyLabel3 38 STOP 40 : 100 DEFine FuNction Label1: RETurn BASIC_W%(104) + 1 110 PRINT 'Label 1'! MyLabel1 120 RETurn 130 : 200 DEFine FuNction Label2: RETurn BASIC_W%(104) + 1 210 PRINT 'Label 2'! MyLabel2 220 RETurn 230 : 300 DEFine FuNction Label3: RETurn BASIC_W%(104) + 1 310 PRINT 'Label 3'! MyLabel3 320 RETurn 330 :
This doesnt work in SBASIC as there BASIC_W%(104) always returns zero. As it happens, there still appears to be one old line number related peek in SBASIC, namely offset $94 (= 14810), aka bv_dalno. This offset holds the current DATA statement line. I wanted to see if that could somehow be used to provide a target for GO TO etc. It appears it can! Run this little number from QD with the SBAS/QD Thing (or copy it into some other editor, add line numbers and EXECute or LRUN it.
This is strictly SBASIC only: QLib doesnt support bv_dalno, and Turbo doesnt like functions and variables in DATA statements, so it is of limited use. Besides, it may not be faster than a SELect ON construct, which was one of the advantages, when the situation lent itself, of ON .. GO TO back in the day. So whats the point? None at all. Just a bit of fun :o)
IF JOBID: ch = FOPEN(#0; 'con'): ELSE : ch = 1 CLS#ch : RANDOMISE DATE RESTORE READ dummy READ LABel1 READ LABel2 READ LABel3 : DATA 0: REMark Dummy PRINT#ch; 'LABel1 is at line no.'! LABel1 PRINT#ch; 'LABel2 is at line no.'! LABel2 PRINT#ch; 'LABel3 is at line no.'! LABel3 : FOR i = 0 TO 9 choose = RND(1 TO 3) PRINT#ch; 'Choice'! choose, ON choose GO SUB LABel1, LABel2, LABel3 END FOR i BGET#ch; k% IF JOBID: QUIT: ELSE : STOP : REMark Lable 1 DATA PEEK_W(\\ $94) PRINT#ch; 1: RETurn : REMark Lable 2 DATA PEEK_W(\\ $94) PRINT#ch; 2: RETurn : REMark Lable 3 DATA PEEK_W(\\ $94) PRINT#ch; 3: RETurn :