|Prev: 268D||Up: Map||Next: 2795|
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||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.|
|S_NO_TO_S||2707||CP $EE||Separate STR$ and CHR$ which operate on numbers to give string results.|
|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.|
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.|
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).|
|271D||CALL SLICING||Modify the parameters of the 'last value'.|
|2720||RST $20||Move on to consider the next character.|
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.|
|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:
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'.|
|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.|
|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.|
|2756||RST $28||Now use the calculator.|
|2757||DEFB $3B||fp_calc_2: (perform the actual operation)|
|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.|
|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.|
|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).|
|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|