CROSS-REFERENCE YOUR BASIC VARIABLES
A programmer-productivity toolBy BILL BROWN
This program creates a sorted list of variables from any SAVEd Atari BASIC program on disk or cassette. The accompanying article discusses Atari BASIC's structure, and may be difficult for beginning computerists to follow. The program requires Atari BASIC and 3500bytes of RAM; it works on all Atari computers.
A cross-referenced list of a program's variables and the line numbers
in which they appear is useful for finding duplicate or conflicting variable
names. Conflicting variable names often occurs before merging two
programs. The program in Listing 1 produces an alphabetized, cross-referenced
list of variables for any Atari BASIC program on diskette or cassette.
The resulting list can be stored on diskette or cassette, or output to
screen or printer.
The program needs two pieces of information to produce a cross-referenced list. Initially, it asks for the device or file that contains the program to be analyzed. Here, the cassette user would respond with C:, and press [RETURN] at the beep; the disk user should enter D:FILENAME.BAS. The file should contain a tokenized Atari BASIC program created with the SAVE command. A cassette file created with the CSAVE command will not work-you must use SAVE "C:".
Next, the program prompts for the device or file to which the cross-referenced list will be written. Type C: to store the list on cassette; disk users should type D:FILENAME.CRE Since the program writes the file to the same disk, you should make sure that there is ample free space on the disk to hold the variable table. Type E: to display the list on the screen, or P: to send the list to the printer.
At this point, the program begins to construct the cross-referenced list, and a report of the program's progress is displayed on the screen. As each line of the tokenized program is scanned, its line number is displayed. When all of the lines have been scanned, the variable names are alphabetically sorted. Each pass of the sort routine is also displayed on the screen. Finally, the completed list is written as a text file to the selected device or file. If you're saving the file on a cassette, the computer will beep twice (through the TV speaker with XL computers). If you're using cassette, insert a new tape, press RECORD and PLAY on the recorder, then press [RETURN] on the keyboard.
To access the target file, type in the following program (change the C: to D:FILENAME.CRC if you're using a disk-drive):
10 DIM HOLD$(500)
20 OPEN #2,4,0,"C:"
30 TRAP 50
40 INPUT #2,HOLD$:?
50 CLOSE #2
If you wish hard copy, change line 40 from ? HOI.D$ to LPRINT HOLD$.
To use a cross-referenced list most effectively, you may need to refer back to the program listing. If you don't own a printer or a full-screen editor, this can be difficult. In this case, display the cross-referenced list on the screen, freezing the screen (with CTRL-1) at the point of interest. Earlier portions of the list can be repeated by entering GOSUB 6000 in direct mode.
HOW IT WORKS
This program's structure is dictated by the structure of a stored, tokenized Atari BASIC program file. Each file is divided into four major blocks:
(1) the zero-page pointers
(2) the variable name table
(3) the variable value table
(4) the token program
Zero-page pointers are two-byte values that point into the token file. The block is fourteen bytes long and consists of seven of the nine zero-pagc pointers that BASIC uses to maintain a token program in RAM. The pointers are:
0,l LOMEM Token-output-buffer pointer
2,3 VNTP Variable-name-table pointer
4,5 VNTD End of variable-name-table pointer
6,7 VVTP Variable-value-table pointer
8,9 STMTAB Statement-table pointer
10,11 STMCUR Pointer to the current statement
12,13 STARP String/Array Area pointer
While the program was in memory (before storage), the value of LOMEM
was subtracted from each of these pointers, including LOMEM itself.
Thus, LOMEM in the stored file is always equal to zero, and the values
of the other pointers are offsets from LOMEM.
The zero-page-pointers block is read and used to compute the length of the variable-name table in lines 1000-1060.
The variable-name table is a list of all the variable names in the program. They are stored as ATASCII characters in the same order that they were entered into the program. The high-order bit of the last byte (or character) of each name is set to one. The program reads the variable-name-table block, saves it in RAM and computes the number of variables in the program. This occurs in lines 2000-2070.
The variable-value table provides current information on each variable. The table reserves eight bytes for each variable in the program. Since this program does not change the value of any variable in your main program, the values in the table are read, then ignored in lines 3000-3060.
The token program block is essentially the original BASIC program with its commands, operators, functions and variables replaced by one-byte tokens. This block is organized into program lines. Each program line has the following structure:
0,1 NUMLINE The BASIC line number
2 OFFLINE The offset from the start of the
current line to the start of the
3 OFFSTATE The offset from the start of the
current line to the start of the
4 OFFSTATE-1 BASIC tokens and constants
The last two entries are repeated for multiple-statement lines. For example, the BASIC line:
10 LET X=1:PRINT X
generates the following in the token file:
Bytes Hex Tokens
0,1 0A 00 Line 10
2 13 Line offset
3 0F Statement offset
4 06 LET
5 80 X
6 2D =
7 0E Numeric constant
8,13 40 01 00 00 00 00 1
14 14 :
15 13 Statement offset
16 20 PRINT
17 80 X
18 16 End of line
The immediate-mode line is the last line in a token program block.
It is assigned line number 32768. The token program block is read
and analyzed, line-by-line, in lines 4000-4080.
A variable's token is determined by its position in the variable name table, with its high-ordered bit set to one. For example, the first variable in a program is assigned the token value of 128 (80 hex) and the second variable is assigned 129 (81 hex). Thus, it is fairly simple, as in line 4044, to pick out references to variables-their token values will be greater than 127. The value of all tokens for commands, operators and functions is less than or equal to 127.
There are several exceptions to this rule, however. In string constants (token 0F hex), the high-order bits of characters entered in inverse video are set. Likewise, inverse-video characters that occur in REM statements (token 00 hex) and DATA statements (token 01 hex) also have the high-order bit set. Numeric constants (token 0E hex) may contain bytes that have the high-order bit set. Lines 4041-4043 handle such exceptions.
Each time a variable is detected, the program makes an entry into both the VREF and LREF arrays. References to particular variables are recorded indirectly, using a chained approach in the VREF array. The value of a link in the chain indicates the location of the next link. The first link is found by examining the element of VREF that corresponds to the variable's token value. The line number for each reference to a variable is given in the corresponding location in LREF.
A shell sort algorithm is used in lines 5000-5090 to alphabetize the variable names. Although the variable-name table remains unchanged, pointers into the table are rearranged with pointers into the variable-reference list to produce the alphabetized cross-reference list. The list is written to a device or file in lines 6000-6110.
Listing: CROSSREF.BAS Download