Prev: 28AB Up: Map Next: 2951
28B2: THE 'LOOK-VARS' SUBROUTINE
Used by the routines at SAVE_ETC, CLASS_01, CLASS_04, S_LETTER and DIM.
This subroutine is called whenever a search of the variables area or of the arguments of a DEF FN statement is required. The subroutine is entered with the system variable CH-ADD pointing to the first letter of the name of the variable whose location is being sought. The name will be in the program area or the work space. The subroutine initially builds up a discriminator byte, in the C register, that is based on the first letter of the variable's name. Bits 5 and 6 of this byte indicate the type of the variable that is being handled.
The B register is used as a bit register to hold flags.
Output
C Bits 0-4: Code of the variable's name (if executing)
C Bit 5: Set if the variable is numeric, reset if it's a string
C Bit 6: Set if the variable is simple, reset if it's an array
C Bit 7: Set if checking syntax, reset if executing
HL Address of the last letter of the variable's name (in the variables area, if found)
F Carry flag reset if the variable already exists or if checking syntax
F Zero flag reset if the variable is simple (not an array) and does not exist
LOOK_VARS 28B2 SET 6,(IY+$01) Presume a numeric variable (set bit 6 of FLAGS).
28B6 RST $18 Get the first character into A.
28B7 CALL ALPHA Is it alphabetic?
28BA JP NC,REPORT_C Give an error report if it is not so.
28BD PUSH HL Save the pointer to the first letter.
28BE AND $1F Transfer bits 0 to 4 of the letter to the C register; bits 5 and 7 are always reset.
28C0 LD C,A
28C1 RST $20 Get the second character into A.
28C2 PUSH HL Save this pointer also.
28C3 CP "(" Is the second character a '('?
28C5 JR Z,V_RUN_SYN Separate arrays of numbers.
28C7 SET 6,C Now set bit 6.
28C9 CP "$" Is the second character a '$'?
28CB JR Z,V_STR_VAR Separate all the strings.
28CD SET 5,C Now set bit 5.
28CF CALL ALPHANUM If the variable's name has only one character then jump forward.
28D2 JR NC,V_TEST_FN
Now find the end character of a name that has more than one character.
V_CHAR 28D4 CALL ALPHANUM Is the character alphanumeric?
28D7 JR NC,V_RUN_SYN Jump out of the loop when the end of the name is found.
28D9 RES 6,C Mark the discriminator byte.
28DB RST $20 Get the next character.
28DC JR V_CHAR Go back to test it.
Simple strings and arrays of strings require that bit 6 of FLAGS is reset.
V_STR_VAR 28DE RST $20 Step CH-ADD past the '$'.
28DF RES 6,(IY+$01) Reset bit 6 of FLAGS to indicate a string.
If DEFADD-hi is non-zero, indicating that a 'function' (a 'FN') is being evaluated, and if in 'run-time', a search will be made of the arguments in the DEF FN statement.
V_TEST_FN 28E3 LD A,($5C0C) Is DEFADD-hi zero?
28E6 AND A
28E7 JR Z,V_RUN_SYN If so, jump forward.
28E9 CALL SYNTAX_Z In 'run-time'?
28EC JP NZ,STK_F_ARG If so, jump forward to search the DEF FN statement.
This entry point is used by the routine at STK_F_ARG.
Otherwise (or if the variable was not found in the DEF FN statement) a search of variables area will be made, unless syntax is being checked.
V_RUN_SYN 28EF LD B,C Copy the discriminator byte to the B register.
28F0 CALL SYNTAX_Z Jump forward if in 'run-time'.
28F3 JR NZ,V_RUN
28F5 LD A,C Move the discriminator to A.
28F6 AND $E0 Drop the character code part.
28F8 SET 7,A Indicate syntax by setting bit 7.
28FA LD C,A Restore the discriminator.
28FB JR V_SYNTAX Jump forward to continue.
A BASIC line is being executed so make a search of the variables area.
V_RUN 28FD LD HL,($5C4B) Pick up the VARS pointer.
Now enter a loop to consider the names of the existing variables.
V_EACH 2900 LD A,(HL) The first letter of each existing variable.
2901 AND $7F Match on bits 0 to 6.
2903 JR Z,V_80_BYTE Jump when the '+80-byte' is reached.
2905 CP C The actual comparison.
2906 JR NZ,V_NEXT Jump forward if the first characters do not match.
2908 RLA Rotate A leftwards and then double it to test bits 5 and 6.
2909 ADD A,A
290A JP P,V_FOUND_2 Strings and array variables.
290D JR C,V_FOUND_2 Simple numeric and FOR-NEXT variables.
Long names are required to be matched fully.
290F POP DE Take a copy of the pointer to the second character.
2910 PUSH DE
2911 PUSH HL Save the first letter pointer.
V_MATCHES 2912 INC HL Consider the next character.
V_SPACES 2913 LD A,(DE) Fetch each character in turn.
2914 INC DE Point to the next character.
2915 CP " " Is the character a 'space'?
2917 JR Z,V_SPACES Ignore the spaces.
2919 OR $20 Set bit 5 so as to match lower and upper case letters.
291B CP (HL) Make the comparison.
291C JR Z,V_MATCHES Back for another character if it does match.
291E OR $80 Will it match with bit 7 set?
2920 CP (HL) Try it.
2921 JR NZ,V_GET_PTR Jump forward if the 'last characters' do not match.
2923 LD A,(DE) Check that the end of the name has been reached before jumping forward.
2924 CALL ALPHANUM
2927 JR NC,V_FOUND_1
In all cases where the names fail to match the HL register pair has to be made to point to the next variable in the variables area.
V_GET_PTR 2929 POP HL Fetch the pointer.
V_NEXT 292A PUSH BC Save B and C briefly.
292B CALL NEXT_ONE DE is made to point to the next variable.
292E EX DE,HL Switch the two pointers.
292F POP BC Get B and C back.
2930 JR V_EACH Go around the loop again.
Come here if no entry was found with the correct name.
V_80_BYTE 2932 SET 7,B Signal 'variable not found'.
Come here if checking syntax.
V_SYNTAX 2934 POP DE Drop the pointer to the second character.
2935 RST $18 Fetch the present character.
2936 CP "(" Is it a '('?
2938 JR Z,V_PASS Jump forward if so.
293A SET 5,B Indicate not dealing with an array and jump forward.
293C JR V_END
Come here when an entry with the correct name was found.
V_FOUND_1 293E POP DE Drop the saved variable pointer.
V_FOUND_2 293F POP DE Drop the second character pointer.
2940 POP DE Drop the first letter pointer.
2941 PUSH HL Save the 'last' letter pointer.
2942 RST $18 Fetch the current character.
If the matching variable name has more than a single letter then the other characters must be passed over.
Note: this appears to have been done already at V_CHAR.
V_PASS 2943 CALL ALPHANUM Is it alphanumeric?
2946 JR NC,V_END Jump when the end of the name has been found.
2948 RST $20 Fetch the next character.
2949 JR V_PASS Go back and test it.
The exit-parameters are now set.
V_END 294B POP HL HL holds the pointer to the letter of a short name or the 'last' character of a long name.
294C RL B Rotate the whole register.
294E BIT 6,B Specify the state of bit 6.
2950 RET Finished.
The exit-parameters for the subroutine can be summarised as follows.
The system variable CH-ADD points to the first location after the name of the variable as it occurs in the BASIC line.
When 'variable not found':
  • The carry flag is set.
  • The zero flag is set only when the search was for an array variable.
  • The HL register pair points to the first letter of the name of the variable as it occurs in the BASIC line.
When 'variable found':
  • The carry flag is reset.
  • The zero flag is set for both simple string variables and all array variables.
  • The HL register pair points to the letter of a 'short' name, or the last character of a 'long' name, of the existing entry that was found in the variables area.
In all cases bits 5 and 6 of the C register indicate the type of variable being handled. Bit 7 is the complement of the SYNTAX/RUN flag. But only when the subroutine is used in 'runtime' will bits 0 to 4 hold the code of the variable's letter.
In syntax time the return is always made with the carry flag reset. The zero flag is set for arrays and reset for all other variables, except that a simple string name incorrectly followed by a '$' sets the zero flag and, in the case of SAVE "name" DATA a$(), passes syntax as well.
Prev: 28AB Up: Map Next: 2951