Prev: 10160 Up: Map Next: 10411
10173: THE 'SCANNING FUNCTION' SUBROUTINE
Used by the routine at S_FN.
This subroutine evaluates a user defined function which occurs in a BASIC line. The subroutine can be considered in four stages:
  • i. The syntax of the FN statement is checked during syntax checking.
  • ii. During line execution, a search is made of the program area for a DEF FN statement, and the names of the functions are compared, until a match is found - or an error is reported.
  • iii. The arguments of the FN are evaluated by calls to SCANNING.
  • iv. The function itself is evaluated by calling SCANNING, which in turn calls LOOK_VARS and so STK_F_ARG.
S_FN_SBRN 10173 CALL SYNTAX_Z Unless syntax is being checked, a jump is made to SF_RUN.
10176 JR NZ,SF_RUN
10178 RST 32 Get the first character of the name.
10179 CALL ALPHA If it is not alphabetic, then report the error.
10182 JP NC,REPORT_C
10185 RST 32 Get the next character.
10186 CP "$" Is it a '$'?
10188 PUSH AF Save the zero flag on the stack.
10189 JR NZ,SF_BRKT_1 Jump if it was not a '$'.
10191 RST 32 But get the next character if it was.
SF_BRKT_1 10192 CP "(" If the character is not a '(', then report the error.
10194 JR NZ,SF_RPRT_C
10196 RST 32 Get the next character.
10197 CP ")" Is it a ')'?
10199 JR Z,SF_FLAG_6 Jump if it is; there are no arguments.
SF_ARGMTS 10201 CALL SCANNING Within the loop, call SCANNING to check the syntax of each argument and to insert floating-point numbers.
10204 RST 24 Get the character which follows the argument; if it is not a ',' then jump - no more arguments.
10205 CP ","
10207 JR NZ,SF_BRKT_2
10209 RST 32 Get the first character in the next argument.
10210 JR SF_ARGMTS Loop back to consider this argument.
SF_BRKT_2 10212 CP ")" Is the current character a ')'?
SF_RPRT_C 10214 JP NZ,REPORT_C Report the error if it is not.
SF_FLAG_6 10217 RST 32 Point to the next character in the BASIC line.
10218 LD HL,23611 Assume a string-valued function and reset bit 6 of FLAGS.
10221 RES 6,(HL)
10223 POP AF Restore the zero flag, jump if the FN is indeed string-valued.
10224 JR Z,SF_SYN_EN
10226 SET 6,(HL) Otherwise, set bit 6 of FLAGS.
SF_SYN_EN 10228 JP S_CONT_2 Jump back to continue scanning the line.
ii. During line execution, a search must first be made for a DEF FN statement.
SF_RUN 10231 RST 32 Get the first character of the name.
10232 AND 223 Reset bit 5 for upper case.
10234 LD B,A Copy the name to B.
10235 RST 32 Get the next character.
10236 SUB "$" Subtract 36, the code for '$'.
10238 LD C,A Copy the result to C (zero for a string, non-zero for a numerical function).
10239 JR NZ,SF_ARGMT1 Jump if non-zero: numerical function.
10241 RST 32 Get the next character, the '('.
SF_ARGMT1 10242 RST 32 Get 1st character of 1st argument.
10243 PUSH HL Save the pointer to it on the stack.
10244 LD HL,(23635) Point to the start of the program (PROG).
10247 DEC HL Go back one location.
SF_FND_DF 10248 LD DE,206 The search will be for 'DEF FN'.
10251 PUSH BC Save the name and 'string status'.
10252 CALL LOOK_PROG Search the program now.
10255 POP BC Restore the name and status.
10256 JR NC,SF_CP_DEF Jump if a DEF FN statement found.
Report P - FN without DEF.
10258 RST 8 Call the error handling routine.
10259 DEFB 24
When a DEF FN statement is found, the name and status of the two functions are compared; if they do not match, the search is resumed.
SF_CP_DEF 10260 PUSH HL Save the pointer to the DEF FN character in case the search has to be resumed.
10261 CALL FN_SKPOVR Get the name of the DEF FN function.
10264 AND 223 Reset bit 5 for upper case.
10266 CP B Does it match the FN name?
10267 JR NZ,SF_NOT_FD Jump if it does not match.
10269 CALL FN_SKPOVR Get the next character in the DEF FN.
10272 SUB "$" Subtract 36, the code for '$'.
10274 CP C Compare the status with that of FN.
10275 JR Z,SF_VALUES Jump if complete match now found.
SF_NOT_FD 10277 POP HL Restore the pointer to the 'DEF FN'.
10278 DEC HL Step back one location.
10279 LD DE,512 Use the search routine to find the end of the DEF FN statement, preparing for the next search; save the name and status meanwhile.
10282 PUSH BC
10283 CALL EACH_STMT
10286 POP BC
10287 JR SF_FND_DF Jump back for a further search.
iii. The correct DEF FN statement has now been found. The arguments of the FN statement will be evaluated by repeated calls of SCANNING, and their 5 byte values (or parameters, for strings) will be inserted into the DEF FN statement in the spaces made there at syntax checking. HL will be used to point along the DEF FN statement (calling FN_SKPOVR as needed) while CH-ADD points along the FN statement (calling NEXT_CHAR as needed).
SF_VALUES 10289 AND A If HL is now pointing to a '$', move on to the '('.
10290 CALL Z,FN_SKPOVR
10293 POP DE Discard the pointer to 'DEF FN'.
10294 POP DE Get the pointer to the first argument of FN, and copy it to CH-ADD.
10295 LD (23645),DE
10299 CALL FN_SKPOVR Move past the '(' now.
10302 PUSH HL Save this pointer on the stack.
10303 CP ")" Is it pointing to a ')'?
10305 JR Z,SF_R_BR_2 If so, jump: FN has no arguments.
SF_ARG_LP 10307 INC HL Point to the next code.
10308 LD A,(HL) Put the code into A.
10309 CP 14 Is it the 'number marker' code, 14?
10311 LD D,64 Set bit 6 of D for a numerical argument.
10313 JR Z,SF_ARG_VL Jump on zero: numerical argument.
10315 DEC HL Now ensure that HL is pointing to the '$' character (not e.g. to a control code).
10316 CALL FN_SKPOVR
10319 INC HL HL now points to the 'number marker'.
10320 LD D,0 Bit 6 of D is reset: string argument.
SF_ARG_VL 10322 INC HL Point to the 1st of the 5 bytes in DEF FN.
10323 PUSH HL Save this pointer on the stack.
10324 PUSH DE Save the 'string status' of the argument.
10325 CALL SCANNING Now evaluate the argument.
10328 POP AF Get the no./string flag into A.
10329 XOR (IY+1) Test bit 6 of it against the result of SCANNING (bit 6 of FLAGS).
10332 AND 64
10334 JR NZ,REPORT_Q Give report Q if they did not match.
10336 POP HL Get the pointer to the first of the 5 spaces in DEF FN into DE.
10337 EX DE,HL
10338 LD HL,(23653) Point HL at STKEND.
10341 LD BC,5 BC will count 5 bytes to be moved.
10344 SBC HL,BC First, decrease STKEND by 5, so deleting the 'last value' from the stack.
10346 LD (23653),HL
10349 LDIR Copy the 5 bytes into the spaces in DEF FN.
10351 EX DE,HL Point HL at the next code.
10352 DEC HL Ensure that HL points to the character after the 5 bytes.
10353 CALL FN_SKPOVR
10356 CP ")" Is it a ')'?
10358 JR Z,SF_R_BR_2 Jump if it is: no more arguments in the DEF FN statement.
10360 PUSH HL It is a ',': save the pointer to it.
10361 RST 24 Get the character after the last argument that was evaluated from FN.
10362 CP "," If it is not a ',' jump: mismatched arguments of FN and DEF FN.
10364 JR NZ,REPORT_Q
10366 RST 32 Point CH-ADD to the next argument of FN.
10367 POP HL Point HL to the ',' in DEF FN again.
10368 CALL FN_SKPOVR Move HL on to the next argument in DEF FN.
10371 JR SF_ARG_LP Jump back to consider this argument.
SF_R_BR_2 10373 PUSH HL Save the pointer to the ')' in DEF FN.
10374 RST 24 Get the character after the last argument in FN.
10375 CP ")" Is it a ')'?
10377 JR Z,SF_VALUE If so, jump to evaluate the function; but if not, give report Q.
Report Q - Parameter error.
REPORT_Q 10379 RST 8 Call the error handling routine.
10380 DEFB 25
iv. Finally, the function itself is evaluated by calling SCANNING, after first setting DEFADD to hold the address of the arguments as they occur in the DEF FN statement. This ensures that LOOK_VARS, when called by SCANNING, will first search these arguments for the required values, before making a search of the variables area.
SF_VALUE 10381 POP DE Restore pointer to ')' in DEF FN.
10382 EX DE,HL Get this pointer into HL.
10383 LD (23645),HL Insert it into CH-ADD.
10386 LD HL,(23563) Get the old value of DEFADD.
10389 EX (SP),HL Stack it, and get the start address of the arguments area of DEF FN into DEFADD.
10390 LD (23563),HL
10393 PUSH DE Save address of ')' in FN.
10394 RST 32 Move CH-ADD on past ')' and '=' to the start of the expression for the function in DEF FN.
10395 RST 32
10396 CALL SCANNING Now evaluate the function.
10399 POP HL Restore the address of ')' in FN.
10400 LD (23645),HL Store it in CH-ADD.
10403 POP HL Restore original value of DEFADD.
10404 LD (23563),HL Put it back into DEFADD.
10407 RST 32 Get the next character in the BASIC line.
10408 JP S_CONT_2 Jump back to continue scanning.
Prev: 10160 Up: Map Next: 10411