Output parameters: none. Rems: 2684 S ALPHNUM exits into S BRACKET subroutine 25E8 Entered only from the scanning function table at 2596 when a bracket "(" is encountered in reading the BASIC line. Thebracket is read as the start of a sub-expression, string or numeric; the characters following it are evaluated as such untila ")" is encountered. Input parameters: none. Action: read the next code in BASIC - call 24FB SCANNING, which puts the value or string parameters of the sub-expression on the calculator stack and returns with the code following the sub-expression - if this code is not 29h ) report "Nonsense in BASIC" - get the next code. Exit: back into the SCANNING loop at 2712 S CONT 2. Output parameters: HL is a BASIC pointer and A the code. SCAN ENT 336C (0028 FP CALC) Jumps from: 33A2 fp-calc-2 SCAN LOOP 1B52 (1B8A LINE RUN) No direct calls or jumps. Return address stacked at: 1B55 GET PARAM Returns from: 1B6F SEPARATOR 1C46 VAR A 3 1C82 CLASS 06 (EXPT 1NUM) 1C8C CLASS 0A (EXPT EXP) Rems: 0605 SAVE ETC address dropped 1BEE CHECK END address dropped 1C11 CLASS 05 address dropped 1C4E CLASS 02 address dropped 1C96 PERMS address dropped SCANNING subroutine 24FB see also BASIC INTERPRETER Any string of codes in the BASIC which is intended to have a numeric value or a string value is an "expression"; from the simplest such as 1.0 or "hello" to complicated ones such as the example in the notes, CHR$ (T+A-26*INT((T+a)/26)+65). SCANNING evaluates all such expressions, from the simplest to the most complex, and puts the result of the evaluation on the calculator stack; if it is a numeric expression the result will be an FP number and the string/ numeric flag, bit 6 of FLAGS, will be set to indicate a numeric result, otherwise it will be the string parameters of the stringresult - essentially a start address and a length - and the flagbit will be zero. Complex expressions are evaluated by building up two stacks simultaneously: - an evaluation stack on the calculator stack, consistingof numeric values and pairs of string parameters obtained by evaluating the various component sub-expressions of the complex expression; these are taken from the stack as they are required to evaluate subsequent components - an op stack on the machine stack; each two-byte value on this stack consists of a_priority in the hi byte and an op code in the lo byte. As each value is ready for stacking, the previous one istaken off and its priority checked. This happens in S LOOP: - if it is the zero stacked on entry to SCANNING, the present operation is executed and the subroutine terminates; zero is lower than any priority - if the last operation has higher_binding_priority than the present operation, the last one is executed. Its result goeson the evaluation stack replacing any values used in executing it; then the op code and priority of the present one is stacked in its place. For the priorities see the table under commands, functions and operators - if the present has higher priority than the last, its op code and priority are simply stacked on the op stack. Input parameters: none. Action: read the first code of the expression - put a double zero on the op stack. _24FF_S_LOOP_1 (loop back to here after each code has been evaluated, provided the next code is not a binary operator,one which comes between its operands: from S PUSH PO after a function op code and priority havegone on the op stack from S U PLUS after a unary plus has been read from S NEXT in some other cases): - use the code to index into the scanning function tableat 2596; the codes in the table are 22 " 28 ( 2E . 2B + A8 FN A5 RND A7 PI A6 INKEY$ C4 BIN AA SCREEN$ AB ATTR A9 POINT - if it is not one of the codes in the table jump on to S ALPHNUM - add the offset from the table to the code address in the table - jump to this address; it is the routine to handle the code. As the offsets are all less than FFh, the routines are packed in after the table, and for the sake of abbreviation several of them merely call secondary subroutines. These routines and secondary routines are indicated here in square brackets, but they each have a separate entry in this index. They all exit back into the scanning loop at one point or another, as indicated. _[250F_S_QUOTE_S: secondary routine to handle quotes.] _[2522_S_2_COORD: subroutine to collect coordinates (X,Y)for SCREEN$, ATTR, POINT.] _[2530_SYNTAX_Z: checks the syntax/run flag.] _[2535_S_SCRN$_S: secondary routine to handle SCREEN$.] _[2580_S_ATTR_A: secondary routine to handle ATTR.] _2596_here the scanning function table itself is inserted _[25AF_S_U_PLUS: handles unary + with exit to S LOOP 1.] _[25B3_S_QUOTE: handles quotes with exit to S CONT 2.] _[25E8_S_BRACKET: handles ( with exit to S CONT 2.] _[25F5_S_FN: handles FN with exit through 27BD S FN SBRN to S CONT 2.] _[25F8_S_RND: handles RND with exit to S NUMERIC.] _[2627_S_PI: handles PI with exit to S NUMERIC.] _[2634_S_INKEY$: handles INKEY$ with exit to S CONT 2.] _[2668_S_SCREEN$: handles SCREEN$ with exit through 25DB S STRING to S CONT 2.] _[2672_S_ATTR: handles ATTR with exit to S NUMERIC.] _[267B_S_POINT: handles POINT with exit to S NUMERIC.] _2684_S_ALPHNUM (jump to here if the code isn't in the scanning function table): call 2C88 ALPHANUM; it returns with NCif the code isn't alphanumeric - if the code isn't alphanumeric jump on to S NEGATE - (alphanumeric code) if it is more than 41h jump on to S LETTER; a letter - (a digit): _[268D_S_BIN/S_DECIMAL: handles numbers, ie any expression beginning with a digit, decimal point, or BIN, with exit to S NUMERIC.] _26C3_S_NUMERIC (all the table operations that produce a numeric result exit to here with the numeric value on the calculator stack): set bit 6 of FLAGS to signal "numeric result" - jump on to S CONT 1. _26C9_S_LETTER (the code is a letter of the alphabet, which can only be a variable letter): call 28B2 LOOK VARS - if it returns with carry report "Variable not found"; no matching variable in the variables area - if it returns with Z call 2996 STK VAR (misprinted STKVARS) to put its value or string parameters on the calculator stack; a string or array - if 5C3B FLAGS is less than 11000000b/C0h jump on to S CONT 1; one of the hi bits is zero, bit 7 zero for syntax checking or bit 6 for a string result - (run time, and the variable is a numeric one; if it isan array, STK VAR placed a pointer before its FP number value inthe variables area, if it is simple LOOK VARS did) move the pointer on to the FP number - call 33B4 STACK NUM to copy the value to the calculator stack. _26DD_S_CONT_1: jump on to S CONT 2; merely a "stepping stone". _26DF_S_NEGATE (the first code of the expression to be evaluated isn't in the scanning function table and isn't a letter or a digit): load priority 09 and op code DB; twice misprinted in the notes, but correct in the listing. This is correct for unary minus, literal 1B negate - if the code is 2D "-" jump on to S PUSH PO - (not unary minus) load priority 10h and op code 18h; this is correct for literal 18 val$ - if the code is AE VAL$ jump on to S PUSH PO - (not unary minus or VAL$) subtract AF from the token code; all the symbols or tokens which can begin a numeric or string expression in BASIC have now been dealt with except thoserunning consecutively from AF CODE to C3 NOT, so subtracting AF leaves 00 to 14h - if the subtraction made a carry report "Nonsense in BASIC"; code less than AF CODE - load priority 04 and op code F0h; this is correct for literal 30 not - if the code is now 14h jump on to S PUSH PO; it was C3NOT - if the comparison didn't make a carry report "Nonsensein BASIC"; code more than C3 NOT - (not NOT) load priority 10h, the highest; all the restof these tokens are functions with priority 10h - add DC to what is left of the token code; the result is an op code matching the table at 32D7, except for the two hi bits which are temporarily used as flags, and they will be zeroed in S STK LST before the table is used. Op codes DC CODE to EF CHR$ match literals 1C code to 2F chr$ in the table; bit 7is set for numeric argument, zero for string argument; bit 6 is set for numeric result, zero for string result - if the code is less than DF zero bit 6 for a numeric result; DC CODE, DD VAL and DE LEN. _2707_S_NO_TO_$: if the code is more than ED zero bit 7 for a string argument; EE STR$ and EF CHR$. _270D_S_PUSH_PO: push the priority and flagged op code onthe op stack - move on the BASIC pointer - loop back to S LOOP 1. _2712_S_CONT_2 (a numeric or string expression or sub- expression has been evaluated and its value or string parametersput on the evaluation stack: the next code could be a binary operator, one which comes between its operands): read the code. _2713_S_CONT_3: if it isn't 28h ( jump on to S OPERTR - (the "(" can only be correct if it indicates slicing of a string expression) if bit 6 of FLAGS is NZ jump on to S LOOP; the string/numeric status flag indicates that the expression just evaluated was numeric. S LOOP will evaluate the whole expression up to the "(" and then return to the calling routine, which will surely report an error, as "(" cannot be syntactically correct in this position - (the expression was a string, the "(" indicates slicing) call 2A52 SLICING to slice it - move on the BASIC pointer - loop back to S CONT 3. _2723_S_OPERTR (a numeric or string expression or sub- expression has been evaluated and its value or string parametersput on the evaluation stack; the next code isn't "(", it may or may not be a binary operator): load the base address of the table of operators at 2795 - call 16DC INDEXER with the next code as index - if INDEXER returns with NC jump on to S LOOP to evaluate the whole expression; the code isn't in the table, ie not a binary operator - read the op code from the table; a code from C3 - to CF + which matches the literal in the table at 32D7 but with both hi bits set: C3 - to C7 OR match 03 subtract to 07 or, C8 AND to CF + match 08 no-&-no to 0F addition and then again, adding 08 to the op codes, match the string operations 10h str-&-no to 17h strs-add - add the op code to the base address 26ED of the priority table at 27B0; eg 26ED + C3 = 27B0, the first entry - get the priority from the table. _2734_S_LOOP (entered with the "present" or "new" operation and priority "o/p" in BC and any previous o/ps stackedup on the machine stack, the "op stack"; the bottom of the op stack is marked with a double zero which was put on it on entry to SCANNING. The corresponding values of expressions and sub- expressions are stacked on the calculator stack, the "evaluationstack"): POP the last o/p and compare the new priority with the one before it - if the new priority is higher, jump on to S TIGHTER; the new o/p will be added to the op stack - (new priority equal or lower) if the last priority waszero, exit into 0018 GET CHAR; the new priority must be zero too, so there is no new operation to perform and the bottom of the op stack has been reached - stack the new o/p; the priority of the last op is higher, so it will be executed now. Note that each operation on the stack, except possibly the new o/p, must have a higher priority than the one below it. If the last code to be read fromBASIC wasn't a binary operator, the new o/p will have zero priority; this will have the effect of executing the stack rightdown to the bottom - put a pointer on FLAGS - if the last op code isn't ED USR jump on to S STK LST - (USR) if bit 6 of FLAGS is zero change the op code to 10011001b/99h, corresponding to literal 19h usr-$; the string/ numeric status flag in the hi bit shows that the argument of USRis a string. _274C_S_STK_LST: stack the last o/p - if syntax is being checked jump on to S SYNTEST - AND the op code with 00111111b/3Fh; this zeroes the flags in bits 6 and 7 and makes it the calculator literal - use the calculator with literal 3B fp-calc-2 and with the operation literal in the B register, which executes the operation - jump on to S RUNTEST. _275B_S_SYNTEST (syntax checking) XOR the op code with 5C3B FLAGS; bit 6 should match, making zero, since in both it isa flag signalling string or numeric argument - AND the result with 01000000b/40h; zero if the flags match. _2761_S_RPORT_C: if the result isn't zero report "Nonsense in BASIC". _2764_S_RUNTEST: recover the last o/p from the op stack - set bit 6 of FLAGS; numeric argument - if bit 7 of the op code is set jump on to S LOOPEND; the result status flag. The argument status matches the result of the last op, as it should, since the result of each op is theargument of the next - (string result) zero bit 6 of FLAGS; the argument status flag, to match the result flag. _2770_S_LOOPEND: recover the top o/p from the stack; thisis now the "new" one, and any remaining on the stack are in order of priority with the highest priority at the top of the stack. The new one could still be lower than the top one on the stack - loop back to S LOOP. _2773_S_TIGHTER (the new o/p has higher priority than anything on the op stack, and must go on the stack) put the lasto/p back on the stack - if bit 6 of FLAGS is set jump on to S NEXT; the argument status flag. The result of the last op was numeric, andnumeric arguments have been assumed in flagging the op code - (the last op had a string result, so the new op has a string argument. It must be one of the binary operators, AND, "+" or a comparison operation; the only_functions which have string arguments, CODE, VAL and LEN, all have top priority, and are PUSHed by S PUSH PO before S LOOP is entered. Whatever the new o/p may be on entry to S LOOP, S TIGHTER can never be reached if any of these are on the op stack) AND the new op codewith 00111111b/3Fh; zero both its argument and its result flags - add 08 to the op code; this changes 08 no-&-no to 10 str-&-no (AND) 0F addition to 17 strs-add (+) and all the number comparisons 09 -> 0E to the corresponding string comparisons 11 -> 16 - if the op code isn't 10h str-&-no jump on to S NOT AND; all the other operators have string arguments after as wellas before them