Prev: 268D Up: Map Next: 2795
26C9: 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).
Input
Output
S_LETTER 26C9 CALL LOOK_VARS Look in the existing variables for the matching entry.
26CC JP C,REPORT_2 An error is reported if there is no existing entry.
26CF CALL Z,STK_VAR Stack the parameters of the string entry/return numeric element base address.
26D2 LD A,($5C3B) Fetch FLAGS.
26D5 CP $C0 Test bits 6 and 7 together.
26D7 JR C,S_CONT_1 Jump if one or both bits are reset.
26D9 INC HL A numeric value is to be stacked.
26DA CALL STACK_NUM Move the number.
This entry point is used by the routine at S_DECIMAL.
S_CONT_1 26DD 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 +09 and the C register the operation code +DB that are required for this operation.
S_NEGATE 26DF LD BC,$09DB Priority +09, operation code +DB.
26E2 CP "-" Is it a '-'?
26E4 JR Z,S_PUSH_PO Jump forward if it is 'unary minus'.
Next the character is tested against the code for 'VAL$', with priority +10 and operation code +18.
26E6 LD BC,$1018 Priority +10, operation code +18.
26E9 CP $AE Is it 'VAL$'?
26EB 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 +AF to +C3.
26ED SUB $AF The range of the functions is changed from +AF to +C3 to range +00 to +14.
26EF JP C,REPORT_C Report an error if out of range.
The function 'NOT' is identified and dealt with separately from the others.
26F2 LD BC,$04F0 Priority +04, operation code +F0.
26F5 CP $14 Is it the function 'NOT'?
26F7 JR Z,S_PUSH_PO Jump if it is so.
26F9 JP NC,REPORT_C Check the range again.
The remaining functions have priority +10. 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.
26FC LD B,$10 Priority +10.
26FE ADD A,$DC The function range is now +DC to +EF.
2700 LD C,A Transfer the operation code.
2701 CP $DF Separate CODE, VAL and LEN which operate on strings to give numerical results.
2703 JR NC,S_NO_TO_S
2705 RES 6,C
S_NO_TO_S 2707 CP $EE Separate STR$ and CHR$ which operate on numbers to give string results.
2709 JR C,S_PUSH_PO
270B 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 270D PUSH BC Stack the priority and operation codes before moving on to consider the next part of the expression.
270E RST $20
270F 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 2712 RST $18 Fetch the present character.
S_CONT_3 2713 CP "(" Jump forward if it is not a '(', which indicates a parenthesised expression.
2715 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.
2717 BIT 6,(IY+$01) Jump forward if dealing with a numeric parenthesised expression (bit 6 of FLAGS set).
271B JR NZ,S_LOOP
271D CALL SLICING Modify the parameters of the 'last value'.
2720 RST $20 Move on to consider the next character.
2721 JR S_CONT_3
If the present character is indeed a binary operator it will be given an operation code in the range +C3 to +CF, and the appropriate priority code.
S_OPERTR 2723 LD B,$00 Original code to BC to index into the table of operators.
2725 LD C,A
2726 LD HL,$2795 The pointer to the table.
2729 CALL INDEXER Index into the table.
272C JR NC,S_LOOP Jump forward if no operation found.
272E LD C,(HL) Get required code from the table.
272F LD HL,$26ED The pointer to the priority table (26ED+C3 gives PRIORITIES as the first address).
2732 ADD HL,BC Index into the table.
2733 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 2734 POP DE Get the 'last' operation and priority.
2735 LD A,D The priority goes to the A register.
2736 CP B Compare 'last' against 'present'.
2737 JR C,S_TIGHTER Exit to wait for the argument.
2739 AND A Are both priorities zero?
273A 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'.
273D PUSH BC Stack the 'present' values.
273E LD HL,$5C3B This is FLAGS.
2741 LD A,E The 'last' operation is compared with the code for USR, which will give 'USR number' unless modified; jump if not 'USR'.
2742 CP $ED
2744 JR NZ,S_STK_LST
2746 BIT 6,(HL) Test bit 6 of FLAGS.
2748 JR NZ,S_STK_LST Jump if it is set ('USR number').
274A LD E,$99 Modify the 'last' operation code: 'offset' +19, plus +80 for string input and numerical result ('USR string').
S_STK_LST 274C PUSH DE Stack the 'last' values briefly.
274D CALL SYNTAX_Z Do not perform the actual operation if syntax is being checked.
2750 JR Z,S_SYNTEST
2752 LD A,E The 'last' operation code.
2753 AND $3F Strip off bits 6 and 7 to convert the operation code to a calculator offset.
2755 LD B,A
2756 RST $28 Now use the calculator.
2757 DEFB $3B fp_calc_2: (perform the actual operation)
2758 DEFB $38 end_calc
2759 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 275B LD A,E Get the 'last' operation code.
275C XOR (IY+$01) 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.
275F AND $40
S_RPORT_C_2 2761 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 2764 POP DE Get the 'last' operation code.
2765 LD HL,$5C3B This is FLAGS.
2768 SET 6,(HL) Assume result to be numeric.
276A BIT 7,E Jump forward if the nature of 'last value' is numeric.
276C JR NZ,S_LOOPEND
276E RES 6,(HL) It is a string.
S_LOOPEND 2770 POP BC Get the 'present' values into BC.
2771 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 2773 PUSH DE The 'last' values go on the stack.
2774 LD A,C Get the 'present' operation code.
2775 BIT 6,(IY+$01) Do not modify the operation code if dealing with a numeric operand (bit 6 of FLAGS set).
2779 JR NZ,S_NEXT
277B AND $3F Clear bits 6 and 7.
277D ADD A,$08 Increase the code by +08.
277F LD C,A Return the code to the C register.
2780 CP $10 Is the operation 'AND'?
2782 JR NZ,S_NOT_AND Jump if it is not so.
2784 SET 6,C 'AND' requires a numeric operand.
2786 JR S_NEXT Jump forward.
S_NOT_AND 2788 JR C,S_RPORT_C_2 The operations -, *, /, ↑ and OR are not possible between strings.
278A CP $17 Is the operation a '+'?
278C JR Z,S_NEXT Jump if it is so.
278E SET 7,C The other operations yield a numeric result.
S_NEXT 2790 PUSH BC The 'present' values go on the machine stack.
2791 RST $20 Consider the next character.
2792 JP S_LOOP_1 Go around the loop again.
Prev: 268D Up: Map Next: 2795