![]() |
Routines |
Prev: 09869 | Up: Map |
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 | ||||||
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:
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 |