DO .. LOOP in BASIC V2

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
Mike
Herr VC
Posts: 4842
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

DO .. LOOP in BASIC V2

Post by Mike »

I happened to use the following construct quite often lately - the lines:

Code: Select all

DO
<statement>
LOOP WHILE <condition>
can easily be translated with a FOR loop in BASIC V2 thus:

Code: Select all

FOR P=-1 TO 0
<statement>
P=<condition>
NEXT P
... where <condition> is a Boolean expression which evaluates to either -1 (true) or 0 (false). The assignment to P can happen anywhere in the loop.

Unlike the equivalent version with GOTO, the FOR loop remembers the jump target, so execution is likely faster - especially when the loop is located at higher line numbers. Also, the loop can easily be embedded into a larger line, as the start of the loop need not anymore be at the start of a line. Here's an example reading the error channel of the current disc drive:

Code: Select all

1 DN=PEEK(186):OPEN15,DN,15:FORP=-1TO0:GET#15,A$:PRINTA$;:P=ST=0:NEXT:CLOSE15
Even with ON .. GOTO, at least 2 lines are necessary:

Code: Select all

1 DN=PEEK(186):OPEN15,DN,15
2 GET#15,A$:PRINTA$;:ON-(ST=0)GOTO2:CLOSE15
... and IF .. THEN or IF .. GOTO require another one extra for the CLOSE statement:

Code: Select all

1 DN=PEEK(186):OPEN15,DN,15
2 GET#15,A$:PRINTA$;:IFST=0THEN2
3 CLOSE15
Greetings,

Michael
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Post by FD22 »

Nice trick. You're right about the execution speed being quicker - the difference between a stack pop and memory scan making a lot of difference (particularly at higher line numbers in longer programs).
wimoos
Vic 20 Afficionado
Posts: 348
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

improper programming

Post by wimoos »

Call me a purist, but modifying the loopvariable from within the loop is improper programming. Nice trick though!
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Post by FD22 »

Yeah, but this is (essentially) Altair BASIC, where flow control is limited to IF-THEN, FOR-NEXT, [ON] GOTO, and [ON] GOSUB-RETURN. Without the niceties of later BASIC features to moderate our misdemeanours, tweaking the FOR variable is a minor crime. ;)
User avatar
Mike
Herr VC
Posts: 4842
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: improper programming

Post by Mike »

wimoos wrote:modifying the loopvariable from within the loop is ...
... much more harmless than leaving a dangling FOR loop on the stack. ;)
wimoos
Vic 20 Afficionado
Posts: 348
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Re: improper programming

Post by wimoos »

Mike wrote:
wimoos wrote:modifying the loopvariable from within the loop is ...
... much more harmless than leaving a dangling FOR loop on the stack. ;)
...which is why Exbasic/WimBasic has the DISPOSE NEXT command. :wink:
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
User avatar
Mike
Herr VC
Posts: 4842
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

Actually, in the example I gave, such a DISPOSE NEXT command was not necessary, as the dangling FOR loop gets removed with a NEXT of the further enclosing FOR loop variable. Sometimes it pays off to know a little more about the inner workings of the BASIC interpreter. ;)

Likewise, if there's a FOR loop in a subroutine, you don't need to end the FOR loop to be 'allowed' a RETURN, you can return straightaway and the dangling FOR loop likewise is removed from the stack. For example, in my implementation of the game 'TRON Light Cycles' a subroutine searches for a free path for the enemy Light Cycle, and exits as soon one is found:

Code: Select all

17 IFPEEK(G+D(H))<>219ORRND(1)<.1THENI=C:GOSUB41
[...]
41 FORT=1TO4:I=(I+1)AND3:IFPEEK(G+D(I))=219THENH=I:RETURN
42 NEXT:RETURN
If there's no free path, the enemy Light Cycle keeps its old direction, and then crashes into the wall.
Last edited by Mike on Thu Feb 20, 2014 4:53 pm, edited 1 time in total.
User avatar
Witzo
Vic 20 Afficionado
Posts: 381
Joined: Thu Dec 01, 2011 9:14 am
Location: The Hague

Post by Witzo »

How does this work?

Code: Select all

P=ST=0
I had to try it, this double assignment:

Code: Select all

10 p=1
20 s=2
30 p=s=42
40 print p,s
ready.
run
 0          2

ready.
Hm, unexpected results. (Tested in VICE though.)
I'll stick to p=42:s=42 for now.
User avatar
Mike
Herr VC
Posts: 4842
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

Witzo wrote:How does this work?

Code: Select all

P=ST=0
This statement is not interpreted as double assignment in BASIC V2, rather the result of the Boolean expression ST=0 (either -1 if true, or 0 if false) is assigned to P.
User avatar
Witzo
Vic 20 Afficionado
Posts: 381
Joined: Thu Dec 01, 2011 9:14 am
Location: The Hague

Post by Witzo »

Mike wrote:
Witzo wrote:How does this work?

Code: Select all

P=ST=0
This statement is not interpreted as double assignment in BASIC V2, rather the result of the Boolean expression ST=0 (either -1 if true, or 0 if false) is assigned to P.
Do I get it right then, that 'A=B=0' and 'A=B=-1' are valid basic expressions, but 'A=B=33' is not?
Interesting.
User avatar
Mike
Herr VC
Posts: 4842
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

No, you're mixing up expressions and statements. To clarify, most (imperative) programming languages make a difference between statements and expressions:

A statement is some instruction or command which is intended to be executed by the language, e.g. PRINT, GOTO. In that sense, the LET statement is an often overlooked case, it tells the language to evaluate an expression and assign it to a variable, i.e.

LET <variable>=<expression>

An expression is a collection of variables, numbers, functions and - possibly! - strings (the operands), which are combined with operators. Most languages feature numeric expressions, which evaluate to a number. Some languages (like BASIC) also support string expressions, which evaluate to a string. A special form are Boolean expressions, where two numeric or two string expressions are compared using a relational operator, such as '=', '<', etc. A few languages truly return a Boolean result, i.e. true or false, which then can be 'fed' into an IF statement. Most others simply map Booleans to a set of numeric values, false is always mapped to 0 (zero), true to some non-zero number - CBM BASIC uses -1, C uses 1. In any case, the THEN clause after an IF statement is executed if the expression between IF and THEN evaluates to a non-zero number, i.e. it is true (that similarily applies to C).

The result of a Boolean expression can however quite as well be assigned to a variable - that being said, all your examples are valid statements in CBM BASIC:

'A=B=0' assigns -1 to A if B is 0, and 0 to A if B is not 0,

'A=B=-1' assigns -1 to A if B is -1, and 0 to A if B is not -1,

and finally

'A=B=33' assigns -1 to A if B is 33, and 0 to A if B is not 33.

Here 'A=...' is the statement where LET had been omitted because it's optional in CBM BASIC, and 'B=...' is a Boolean expression, whose result is assigned to A. It's an alleged source of confusion, that '=' serves double use in BASIC: as assignment statement and as relational operator in expressions.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Post by FD22 »

Which is why a number of languages make them explicitly different, to avoid that possible confusion (viz. C/C++/C# use '=' for assignment and '==' for equality; Pascal and Modula-2 use ':=' for assignment and '=' for equality, etc.)
User avatar
Witzo
Vic 20 Afficionado
Posts: 381
Joined: Thu Dec 01, 2011 9:14 am
Location: The Hague

Post by Witzo »

Thanks Mike.
It was the '=' being a symbol for both assignment and comparison that confused me; in Python I can keep them apart with '=' and '=='.
I couldn't make out how both '=' were distinguished.
Now I get the first one, which could be preceded by LET, is the assignment and the second one is a comparison, leading to 'assign to A (the result of checking if B equals 33)'.
Post Reply