BASIC Tipics: Use Logic

(NOTE: While the author refers to the TS1000 in his examples, the information put forth in this article applies to any computer using BASIC- even the mega-buck mainframes.-ed.)

The topic of logic applied to Sinclair 1000 BASIC is exciting in several ways:

  • 1) Using logic, one can branch a multitude of ways from one program line;
  • 2) One can cause alternate PRINT results, again from a single line;
  • 3) The programmer can cause the program to make alternate assignments of value to variables from a single LET command;
  • 4) The operations above will be faster and more memory efficient than a string of simple IF statements.

The logic this article will explore is a blend of two forms; arithmetic and Boolean logic (AND, OR, and NOT) operations. You and I will explore how to apply this blend of both forms to achieve some very powerful results.

Before we begin our dive into logic, consider parentheses ( “()” ). Parentheses force the TS/1000 to evaluate something between them as if that something had higher processing priority than the surrounding commands or calculations. In other words, the machine evaluates the contents of the inner most parentheses first and then uses the result to atempt to do whatever you told it to outside the parentheses. If you don’t understand this, look at the resolutions of expressions later in this article and watch how the parentheses disappear as the computer solves your logic.

How it Works

The easiest way to understand how to use this logic is to look at real examples, so take a minute to look at Figure 1 and then come back to “DISSECTING THE LOGIC”.

Figure 1

   1 REM INITIALIZATION 1-100
200 REM BRANCH MENU ROUTINE
205 LET I=0
210 REM MENU PRINT LINE HERE
220 INPUT I$
230 IF (CODE I$>28 AND CODE I$<
32) THEN LET I=(VAL I$)
240 GOTO (((I*1000) AND I>0)+(9
000 AND I=0))
1000 REM DISK READ ROUTINE
2000 REM DISK WRITE ROUTINE
3000 REM PRINT FILE ROUTINE
...
9000 PRINT "CANNOT DO THAT, SO T
RY AGAIN."
9010 GOTO 220

Dissecting the Logic

Let us presume that line 210 prints a branch menu that looks like this:

            MAIN MENU

      1 LOAD FILE FROM DISK
      2 WRITE FILE TO DISK
      3 PRINT FILE

     ENTER YOUR CHOICE(1-3)

Just before the menu was printed, line 205 set I to 0. Given this, we need a way to check that what the user enters is a number and that the number is 1 or 2 or 3.

So, line 230 reads: IF (CODE I$>28 AND CODE I$<32) THEN LET I=(VAL I$). This line checks that the input is a number between 0 and 4. (Note that “1” is CODE 29, and “3” is CODE 31.) If the test is false, I remains equal to 0.

The computer resolves the expression in line 230 as follows:

First, it goes to a table in the ROM and pulls out the CODE for the value in I. Let us presume that 1 was entered. The CODE for 1 is 29, so the computer then looks at the expression. 29>28 AND 29<32, so the expression is true. Since this is so, the computer sets I to 1.

The next task is to make the computer branch to the chosen routine or print an error message and give the user another chance. This is accomplished by line 240, which is resolved as follows:

GOTO (((I*1000) and I>0)+(9000 AND I=0))
GOTO ((1000 AND 1)+(9000 AND I=0))
          (true)          (false)
GOTO ((1000)+(9000 AND 0)
                (false)
GOTO (1000+0)
GOTO 1000.

The computer goes to the load disk routine.

Let us look at what happens if the user enters an E instead of a number at line 220. The LET in line 230 does not execute, because CODE E is 42, and 42 is not a member of the set (29, 30, 31). I remains equal to 0, thanks to line 205. Line 240 reolves as follows:

GOTO (((I*1000) AND I>0)+(9000 AND 1))
                (false)     (true)
GOTO ((0 and 0)+(9000 AND 1))
GOTO (0+9000)
GOTO 9000.

The computer prints an error message and gives the user another chance.

Boolean Peculiarities

A few peculiarities of the way the TS/1000 handles AND, OR, and NOT need to be explained here. Let us start with OR.

GOTO (((I*1000) AND I>0) OR (9000 AND I=0))looks as if it might work like line 240 in Figure 1. However, what the TS/1000 does is (where I=0):

GOTO (((I*1000) AND I>0) OR (9000 AND I=0))
GOTO ((0 AND 0) or (9000 AND 1))
        (false)        (true)
GOTO (0 OR 1)
GOTO 1.

The computer looks for a line number 1.

In other words, the OR functions differently than an English “or”. If we denote an OR expression as X OR Y, and if X is true, then the machine returns 1 if Y is true or X where Y is false. I have tried to use OR as “or” again and again, until rereading Page 35, Exercise 3(iii) in the TS/1000 Manual. In fact, stubborn old me had to review Sharon Aker‘s “The Logical Operators” in Sync(Volume 3, No. 5) before admitting that the explanation above is really how the TS/1000 handles ORs.

Let’s look at NOTs next. Review line 230 in Figure 1, and then look at this rewrite using NOTs:

230 GOTO (((I*1000)AND NOT I<=0)+
(9000 AND (NOT I>0 AND I<0)))

This statement means the same as the old line 230 did. It is just more complex.

The only use for NOT which I can think of quickly goes as follows:

1170 PRINT "ENTER Y TO QUIT"
1180 INPUT I$
1190 GOTO ((2000 AND I$="Y")+(200 (main menu
routine) AND NOT I$="Y"))
2000 STOP.

If Y is typed in at the INPUT prompt, the computer treats line 1190 as commanding it to go to line 2000 and STOPs. If anything else is typed in, the computer rePRINTs the main menu.

Mutual exclusivity is required for all this branching to work. OOPS– translation time. Look at line 1190 in the previous example. Assume a case of idiocy, for the moment. If I$ could equal “Y” and at the same time not equal “Y”, the computer might try to branch to a line 2200. Error B/1190 would result. The past two statements are idiocy because the two conditions are mutually exclusive– ONLY ONE CAN BE TRUE AT ANY GIVEN INSTANT. Your logical operations should present the computer with mutually exclusive alternatives unless you wish to create chaos.

Since you now have looked at several ANDs, let’s glance at them from a different perspective. The rules used to resolve one AND pair are simple. If we denote our pair as X AND Y, and X is true, the following results will occur. The machine will return X where Y is true or 0 where Y is false. If we are looking at X$ and Y, the machine will return X$ where Y is true or the null string where Y is false.

Read that last sentence again. One logical extension of that statement is that we can use Boolean logic to to control slicing and concatenation of strings. However, this topic needs to be deferred due to its complexity. See you later, with some words concerning strings, error-trapping and structured BASIC.

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.