Prev: 09869 Up: Map Next: 10133
09929: THE 'SCANNING VARIABLE' ROUTINE
Used by the routine at S_ALPHNUM.
When a variable name has been identified a call is made to LOOK_VARS which looks through those variables that already exist in the variables area (or in the program area at DEF FN statements for a user-defined function FN). If an appropriate numeric value is found then it is copied to the calculator stack using STACK_NUM. However a string or string array entry has to have the appropriate parameters passed to the calculator stack by STK_VAR (or in the case of a user-defined function, by STK_F_ARG as called from LOOK_VARS).
S_LETTER 09929 CALL LOOK_VARS Look in the existing variables for the matching entry.
09932 JP C,REPORT_2 An error is reported if there is no existing entry.
09935 CALL Z,STK_VAR Stack the parameters of the string entry/return numeric element base address.
09938 LD A,(23611) Fetch FLAGS.
09941 CP 192 Test bits 6 and 7 together.
09943 JR C,S_CONT_1 Jump if one or both bits are reset.
09945 INC HL A numeric value is to be stacked.
09946 CALL STACK_NUM Move the number.
This entry point is used by the routine at S_DECIMAL.
S_CONT_1 09949 JR S_CONT_2 Jump forward.
This entry point is used by the routine at S_ALPHNUM.
The character is tested against the code for '-', thus identifying the 'unary minus' operation.
Before the actual test the B register is set to hold the priority 9 and the C register the operation code 219 that are required for this operation.
S_NEGATE 09951 LD BC,2523 Priority 9, operation code 219.
09954 CP "-" Is it a '-'?
09956 JR Z,S_PUSH_PO Jump forward if it is 'unary minus'.
Next the character is tested against the code for 'VAL$', with priority 16 and operation code 24.
09958 LD BC,4120 Priority 16, operation code 24.
09961 CP 174 Is it 'VAL$'?
09963 JR Z,S_PUSH_PO Jump forward if it is 'VAL$'.
The present character must now represent one of the functions CODE to NOT, with codes 175 to 195.
09965 SUB 175 The range of the functions is changed from 175 to 195 to range 0 to 20.
09967 JP C,REPORT_C Report an error if out of range.
The function 'NOT' is identified and dealt with separately from the others.
09970 LD BC,1264 Priority 4, operation code 240.
09973 CP 20 Is it the function 'NOT'?
09975 JR Z,S_PUSH_PO Jump if it is so.
09977 JP NC,REPORT_C Check the range again.
The remaining functions have priority 16. The operation codes for these functions are now calculated. Functions that operate on strings need bit 6 reset and functions that give string results need bit 7 reset in their operation codes.
09980 LD B,16 Priority 16.
09982 ADD A,220 The function range is now 220 to 239.
09984 LD C,A Transfer the operation code.
09985 CP 223 Separate CODE, VAL and LEN which operate on strings to give numerical results.
09987 JR NC,S_NO_TO_S
09989 RES 6,C
S_NO_TO_S 09991 CP 238 Separate STR$ and CHR$ which operate on numbers to give string results.
09993 JR C,S_PUSH_PO
09995 RES 7,C Mark the operation codes. The other operation codes have bits 6 and 7 both set.
This entry point is used by the routine at S_INKEY.
The priority code and the operation code for the function being considered are now pushed on to the machine stack. A hierarchy of operations is thereby built up.
S_PUSH_PO 09997 PUSH BC Stack the priority and operation codes before moving on to consider the next part of the expression.
09998 RST 32
09999 JP S_LOOP_1
This entry point is used by the routines at S_QUOTE, S_BRACKET, S_INKEY and S_FN_SBRN.
The scanning of the line now continues. The present argument may be followed by a '(', a binary operator or, if the end of the expression has been reached, then e.g. a carriage return character or a colon, a separator or a 'THEN'.
S_CONT_2 10002 RST 24 Fetch the present character.
S_CONT_3 10003 CP "(" Jump forward if it is not a '(', which indicates a parenthesised expression.
10005 JR NZ,S_OPERTR
If the 'last value' is numeric then the parenthesised expression is a true sub-expression and must be evaluated by itself. However if the 'last value' is a string then the parenthesised expression represents an element of an array or a slice of a string. A call to SLICING modifies the parameters of the string as required.
10007 BIT 6,(IY+1) Jump forward if dealing with a numeric parenthesised expression (bit 6 of FLAGS set).
10011 JR NZ,S_LOOP
10013 CALL SLICING Modify the parameters of the 'last value'.
10016 RST 32 Move on to consider the next character.
10017 JR S_CONT_3
If the present character is indeed a binary operator it will be given an operation code in the range 195 to 207, and the appropriate priority code.
S_OPERTR 10019 LD B,0 Original code to BC to index into the table of operators.
10021 LD C,A
10022 LD HL,10133 The pointer to the table.
10025 CALL INDEXER Index into the table.
10028 JR NC,S_LOOP Jump forward if no operation found.
10030 LD C,(HL) Get required code from the table.
10031 LD HL,9965 The pointer to the priority table (9965+195 gives PRIORITIES as the first address).
10034 ADD HL,BC Index into the table.
10035 LD B,(HL) Fetch the appropriate priority.
The main loop of this subroutine is now entered. At this stage there are:
  • i. A 'last value' on the calculator stack.
  • ii. The starting priority marker on the machine stack below a hierarchy, of unknown size, of function and binary operation codes. This hierarchy may be null.
  • iii. The BC register pair holding the 'present' operation and priority, which if the end of an expression has been reached will be priority zero.
Initially the 'last' operation and priority are taken off the machine stack and compared against the 'present' operation and priority.
S_LOOP 10036 POP DE Get the 'last' operation and priority.
10037 LD A,D The priority goes to the A register.
10038 CP B Compare 'last' against 'present'.
10039 JR C,S_TIGHTER Exit to wait for the argument.
10041 AND A Are both priorities zero?
10042 JP Z,GET_CHAR Exit via GET_CHAR thereby making 'last value' the required result.
Before the 'last' operation is performed, the 'USR' function is separated into 'USR number' and 'USR string' according as bit 6 of FLAGS was set or reset when the argument of the function was stacked as the 'last value'.
10045 PUSH BC Stack the 'present' values.
10046 LD HL,23611 This is FLAGS.
10049 LD A,E The 'last' operation is compared with the code for USR, which will give 'USR number' unless modified; jump if not 'USR'.
10050 CP 237
10052 JR NZ,S_STK_LST
10054 BIT 6,(HL) Test bit 6 of FLAGS.
10056 JR NZ,S_STK_LST Jump if it is set ('USR number').
10058 LD E,153 Modify the 'last' operation code: 'offset' 25, plus 128 for string input and numerical result ('USR string').
S_STK_LST 10060 PUSH DE Stack the 'last' values briefly.
10061 CALL SYNTAX_Z Do not perform the actual operation if syntax is being checked.
10064 JR Z,S_SYNTEST
10066 LD A,E The 'last' operation code.
10067 AND 63 Strip off bits 6 and 7 to convert the operation code to a calculator offset.
10069 LD B,A
10070 RST 40 Now use the calculator.
10071 DEFB 59 fp_calc_2: (perform the actual operation)
10072 DEFB 56 end_calc
10073 JR S_RUNTEST Jump forward.
An important part of syntax checking involves the testing of the operation to ensure that the nature of the 'last value' is of the correct type for the operation under consideration.
S_SYNTEST 10075 LD A,E Get the 'last' operation code.
10076 XOR (IY+1) This tests the nature of the 'last value' (bit 6 of FLAGS) against the requirement of the operation. They are to be the same for correct syntax.
10079 AND 64
S_RPORT_C_2 10081 JP NZ,REPORT_C Jump if syntax fails.
Before jumping back to go round the loop again the nature of the 'last value' must be recorded in FLAGS.
S_RUNTEST 10084 POP DE Get the 'last' operation code.
10085 LD HL,23611 This is FLAGS.
10088 SET 6,(HL) Assume result to be numeric.
10090 BIT 7,E Jump forward if the nature of 'last value' is numeric.
10092 JR NZ,S_LOOPEND
10094 RES 6,(HL) It is a string.
S_LOOPEND 10096 POP BC Get the 'present' values into BC.
10097 JR S_LOOP Jump back.
Whenever the 'present' operation binds tighter, the 'last' and the 'present' values go back on the machine stack. However if the 'present' operation requires a string as its operand then the operation code is modified to indicate this requirement.
S_TIGHTER 10099 PUSH DE The 'last' values go on the stack.
10100 LD A,C Get the 'present' operation code.
10101 BIT 6,(IY+1) Do not modify the operation code if dealing with a numeric operand (bit 6 of FLAGS set).
10105 JR NZ,S_NEXT
10107 AND 63 Clear bits 6 and 7.
10109 ADD A,8 Increase the code by 8.
10111 LD C,A Return the code to the C register.
10112 CP 16 Is the operation 'AND'?
10114 JR NZ,S_NOT_AND Jump if it is not so.
10116 SET 6,C 'AND' requires a numeric operand.
10118 JR S_NEXT Jump forward.
S_NOT_AND 10120 JR C,S_RPORT_C_2 The operations -, *, /, ↑ and OR are not possible between strings.
10122 CP 23 Is the operation a '+'?
10124 JR Z,S_NEXT Jump if it is so.
10126 SET 7,C The other operations yield a numeric result.
S_NEXT 10128 PUSH BC The 'present' values go on the machine stack.
10129 RST 32 Consider the next character.
10130 JP S_LOOP_1 Go around the loop again.
Prev: 09869 Up: Map Next: 10133