Home > CBM > BASIC > Keywords > Else 180 Subpages: (divide), (equal), (less), (minus), (more), (multiply), (plus), (power), Abs, And, Append, Asc, Atn, Auto, Backup, Bank, Begin, Bend, Bload, Boot, Box, Bsave, Bump, Catalog, Char, Chr, Circle, Close, Clr, Cmd, Collect, Collision, Color, Concat, Cont, Copy, Cos, Data, Dclear, Dclose, Dec, Def, Delete, Dim, Directory, Dispose, Dload, Do, Dopen, Draw, Ds, Ds string, Dsave, Dverify, El, End, Envelope, Er, Err, Exit, Exp, Fast, Fetch, Filter, Fn, For, Fre, Get, Get num, Getkey, Go, Gosub, Goto, Graphic, Gshape, Header, Help, Hex, If, Input, Input num, Instr, Int, Joy, Key, Left, Len, Let, List, Load, Locate, Log, Loop, Mid, Monitor, Movspr, New, Next, Not, Off, On, Open, Or, Paint, Peek, Pen, Pi, Play, Pointer, Poke, Pos, Pot, Print, Print num, Pudef, Quit, Rclr, Rdot, Read, Record, Rem, Rename, Renumber, Restore, Resume, Return, Rgr, Right, Rlum, Rnd, Rreg, Rspcolor, Rsppos, Rsprite, Run, Rwindow, Save, Scale, Scnclr, Scratch, Sgn, Sin, Sleep, Slow, Sound, Spc, Sprcolor, Sprdef, Sprite, Sprsav, Sqr, Sshape, St, Stash, Step, Stop, Str, Swap, Sys, Tab, Tan, Tempo, Then, Ti, Ti string, To, Trap, Troff, Tron, Until, Using, Usr, Val, Verify, Vol, Wait, While, Width, Window, Xor |
| Keyword | Abbreviation | Token (hex) | Version(s) | Classification |
| ELSE | E{Shift+L} | D5 | 3.5, 7.0 | Command**, Preposition, Statement** |
| DSAVE | D{Shift+S} | D5 | 4.x | Command and Statement |
| ELSE | E{Shift+L} | E1 | 4.7 | Command**, Preposition, Statement** |
| BOX | varies | E1 | 3.5, 7.0 | Command and Statement |
IF condition { GOTO lineNumTrue | THEN [
lineNumTrue | BEGIN ] } [ statementT ] [ : statementT ] ...
[ statementT : ] ... BEND [ junk1 ]
[ : ELSE [ lineNumFalse | BEGIN ] [ statementF ]
[ : statementF ] ...
[ statementF : ] ... BEND [ junk2 ] ]
| Parameters | Type | Legal Value(s) | Default Value | Note(s) |
| condition | Boolean | all numeric | | |
lineNumTrue | Unsigned integer | 0 ~ 63999 | | Must be a literal number Branched to when condition is true (not 0) |
statementT | Command or Statement | all* | | Must be valid in current direct/RUN mode Executed when condition is true (not 0) |
junk1 | Literal character(s) | any but colon (:) | | ignored; similar to DATA |
| lineNumFalse | Unsigned integer | 0 ~ 63999 | | Only valid in v3.5, 4.7, and 7.0 Must be a literal number. Branched to when condition is false (0) |
| statementF | Command or Statement | all* | | Only valid in v3.5, 4.7, and 7.0 Must be valid in current direct/RUN mode Executed when condition is false (0) |
junk2 | Literal character(s) | all | | ignored; just like REM |
Program flow control. Conditionally execute statement(s) or change program execution line.
Because the syntax shown above is rather complex, let me explain the 3 normal uses of the ELSE clause.
ELSE may be followed by:
- a literal line number (a numeric variable or expression is forbidden),
- or a series of statements that must all fit on the same line,
- or the BEGIN keyword (allows for multiple lines, but only in v7.0).
The ELSE clause is only executed when the condition is false (evaluates to zero).
Compared to the BASIC of other computers, and many non-BASIC languages, the ELSE clause
of CBM BASIC is "broken". I guess it isn't technically a bug, but it does operate rather strangely
if you have done programming with other machines/languages. In particular, nested IF/THEN/ELSE's do not work.
So first let me show some psudo-code of how ELSE works in most languages:
IF condition1 THEN { 'execute T1 if true
optional initial statement(s)...
IF condition2 THEN { 'execute T2 statement(s) if true
statements in block... }
ELSE { 'execute F2 statement(s) if false
some statements in block... }
optional final statement(s)...}
'do nothing if condition1 is false
|
That is a nested IF/THEN/ELSE. Two things to note:
first, if condition1 is false then nothing is executed; and second, the F2 statment(s)
will only execute if condition1 is true and condition2 is false.
Here is an attempt to write that in CBM BASIC (which fails):
IF condition1 THEN PRINT "T1" : IF condition2 THEN PRINT "T2" : ELSE PRINT "F2"
|
In CBM BASIC, the F2 statement(s) will execute if either condition1
or condition2 is false.
In other words, in most languages, an ELSE matches the most recent IF (this allows nesting).
But in CBM BASIC, ELSE which match any/all previous IFs that had a false condition
(unless an ELSE clause was present for them).
In most versions of BASIC that have an ELSE clause, there is no general way
to re-write that failed attempt to work like the psudo-code shown above (i.e., nested IF/THEN/ELSE is broken).
In BASIC v7.0, you can use BEGIN and BEND to force "blocking" of code so that it works,
but it is over-kill for a simple 1-line statement:
IF condition1 THEN BEGIN : PRINT "T1" : IF condition2 THEN PRINT "T2" : ELSE PRINT "F2" : BEND
|
Because ELSE is "broken", a silly trick is possible to emulate EITHER in some cases.
Either only makes sense when you are trying to pack as many statements as possible onto a single line.
(A natural EITHER is built-in by simply using a following line of BASIC code.)
The only case in which it works is when you don't want an ELSE clause
(that is, you don't need some statements that execute only when the condition is false):
IF condition1 THEN statementTrue : IF 0 THEN: ELSE statementEither
|
The first statement following ELSE (or lineNumTrue, lineNumFalse, BEGIN or THEN), if any,
does not need a leading colon (:). This makes typing programs a bit easier and saves a byte;
however, many BASIC extensions will fail if a leading colon is not present.
It seems this derives from a hack written by Microsoft in the original version of BASIC.
It essentially short-circuits the normal BASIC execution logic, with some ugly side-effects.
Besides causing trouble for BASIC extensions, HELP will highlight the entire IF / THEN / ELSE construct
when the error occured in the ELSE clause; similarly error trapping is messed up;
the hacked implementation also delays execution of a COLLISION routine.
* The selected command/statement must be valid for the current Interpreter mode
(valid for Direct Mode, or Run Mode, per the current state of the BASIC Interpreter).
** ELSE is designed to be used as a preposition with IF. However, it may also be a "trick REM"
if used as a command or statement (i.e., used without a leading IF in direct mode or program mode respectively).
The way the BASIC interpreter is written, whenever it encounters the ELSE keyword it stops executing the current line,
just like a REM command/statement. The only exception is when the IF keyword evaluates condition as false;
in which case IF seeks out ELSE to execute the following statements.
In BASIC v7.0, this trick can be extented to skip multiple lines by following ELSE with BEGIN.
In any case, this "trick REM" has no value other than code obfusication.
Example 1:
IF 0 THEN PRINT "TRUE" : ELSE PRINT "FALSE"
FALSE
READY.
X=0: IF X=1 THEN PRINT "TRUE"
READY.
IF X=1 THEN PRINT "EQUALS ONE IS TRUE" : ELSE PRINT "UNTRUE"
UNTRUE
READY.
NEW
READY.
10 X=9 : IF X=1 THEN BEGIN
20 : PRINT "TRUE" : X = 2 : BEND : ELSE PRINT "FALSE" : X = 0
30 PRINT X
RUN
FALSE 0
READY.
|
Example 2 is for BASIC v1.0 and v2.x which lack an ELSE clause (uses GOTO):
NEW
READY.
10 X=9 : IF X=1 THEN PRINT "TRUE" : X=2 : GOTO 30 :REM THEN clause + GOTO to skip ELSE clause
20 PRINT "FALSE" : X = 0 : REM the ELSE clause
30 PRINT X
RUN
FALSE 0
READY.
|
Example 3, ELSE as Trick REM (for BASIC v3.5 to 7.0):
Example 4, multi-line Trick REM for BASIC v7.0
NEW
READY.
10 ELSE BEGIN
20 PRINT "MISSED ME!"
30 BEND
40 PRINT "WHERE DID HE GO?"
RUN
WHERE DID HE GO?
READY.
|
GOTO, REM
BEGIN, BEND,
IF, THEN
© H2Obsession, 2014
|