(FILECREATED " 8-Sep-86 11:59:34" {ERIS}<LISPCORE>BVM>LOADFNS.;2 48313  

      changes to:  (FNS LOADFNS SCANFILE0 SCANDEFINEQ SCANEXP SCANDECLARE: SCANFILE1 TMPSUBFN 
                        RETRYSCAN)

      previous date: " 2-Aug-86 16:08:53" {ERIS}<LISPCORE>SOURCES>LOADFNS.;3)


(* Copyright (c) 1983, 1984, 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT LOADFNSCOMS)

(RPAQQ LOADFNSCOMS 
       [(FNS LOADFROM LOADBLOCK LOADCOMP LOADCOMP? LOADVARS LOADEFS LOADFILEMAP LOADFNS LOADFNS0 
             LOADFNS1 GETBLOCKDEC LOADFNSCAN SCANFILE0 SCANCOMPILEDFN SCANDEFINEQ SCANEXP 
             SCANDECLARE: SCANFILE1 SCANFILE2 TMPSUBFN RETRYSCAN SCANFILEHELP)
        (VARS (NOT-FOUNDTAG (QUOTE NOT-FOUND:)))
        (BLOCKS (SCANFILEBLOCK LOADFNSCAN SCANFILE0 SCANCOMPILEDFN SCANDEFINEQ SCANEXP SCANDECLARE: 
                       SCANFILE1 SCANFILE2 TMPSUBFN (LOCALFREEVARS FNADRLST DICT DICT0 ADR)
                       (SPECVARS LDFLG PRINTFLG FNS FNLST VARLST VARS DONELST)
                       (GLOBALVARS SYSFILES DWIMFLG FILERDTBL LOADOPTIONS)
                       (ENTRIES LOADFNSCAN TMPSUBFN SCANFILE1)
                       (RETFNS SCANFILE0))
               (NIL LOADFROM (GLOBALVARS LASTWORD DWIMFLG))
               (NIL LOADFNS LOADFNS0 LOADFNS1 (GLOBALVARS DWIMFLG LOADOPTIONS SYSFILES NOT-FOUNDTAG])
(DEFINEQ

(LOADFROM
  [LAMBDA (FILE FNS LDFLG)                                   (* wt: "21-SEP-79 12:03")
                                                             (* 'notices' file.)
    (PROG1 (LOADFNS FNS FILE LDFLG (QUOTE LOADFROM))
           (AND DWIMFLG FNS (SETQ LASTWORD (COND
                                              ((ATOM FNS)
                                               FNS)
                                              (T (CAR (LAST FNS])

(LOADBLOCK
  [LAMBDA (FN FILE LDFLG)
    (PROG (TEM)
          (OR FILE (SETQ FILE (LOADFNS0 FN)))
          (RETURN (AND [SETQ TEM (SUBSET (OR (GETBLOCKDEC FN FILE T)
                                             (LIST FN))
                                        (FUNCTION (LAMBDA (FN)
                                                    (NOT (EXPRP (VIRGINFN FN]
                       (LOADFNS TEM FILE LDFLG])

(LOADCOMP
  [LAMBDA (FILE LDFLG)                                       (* rmk: "17-NOV-81 01:37")
                                                             (* Save FULLNAME for LOADCOMP?)
    (PROG (BLOCKS (FULLNAME (OR (FINDFILE FILE)
                                FILE)))
          (RETURN (PROG1 (LOADFNS T FULLNAME LDFLG (QUOTE LOADCOMP))
                         (/PUTPROP (NAMEFIELD FULLNAME)
                                (QUOTE LOADCOMP)
                                FULLNAME])

(LOADCOMP?
  [LAMBDA (FILE LDFLG)                                       (* rmk: "17-NOV-81 01:38")
    (PROG (BLOCKS TEM (FULLNAME (OR (FINDFILE FILE)
                                    FILE)))
          (DECLARE (SPECVARS FULLNAME))
          (COND
             ([AND (OR [NULL (SETQ TEM (GETPROP (NAMEFIELD FULLNAME)
                                              (QUOTE LOADCOMP]
                       (NEQ TEM FULLNAME))
                   (NULL (SEARCHPDL (FUNCTION (LAMBDA (NAME FRAME)
                                                (AND (EQ NAME (QUOTE LOADCOMP))
                                                     (EQ FULLNAME (EVALV (QUOTE FILE)
                                                                         FRAME]
              (LOADCOMP FULLNAME LDFLG)))
          (RETURN FILE])

(LOADVARS
  [LAMBDA (VARS FILE LDFLG)
    (LOADFNS NIL FILE LDFLG VARS])

(LOADEFS
  [LAMBDA (FNS FILE)                                         (* wt: " 9-APR-80 20:27")
    (LOADFNS FNS FILE (QUOTE GETDEF])

(LOADFILEMAP
  [LAMBDA (FILE)                                             (* wt: "16-MAY-79 22:05")
          
          (* user wants the full filemap. scan file if necessary.
          if updatemapflg=T and any changes are made, e.g.
          map does not exist on file, or is wrong (due to transferring from dorado to 
          maxc), loafns will rewrite the map)

    (LOADFNS NIL FILE NIL (QUOTE FILEMAP])

(LOADFNS
  [LAMBDA (FNS FILE LDFLG VARS)                              (* bvm: " 8-Sep-86 11:18")
          
          (* * "All of LOADVARS, LOADCOMP, LOADFILEMAP, LOADFROM come thru here.")

    (DECLARE (SPECVARS FILE LDFLG VARS))                     (* "Used free by RETRYSCAN")
    (RESETLST
     (PROG ((*PACKAGE* *INTERLISP-PACKAGE*)
            (DFNFLG DFNFLG)
            (BUILDMAPFLG BUILDMAPFLG)
            (FILEPKGFLG FILEPKGFLG)
            (ADDSPELLFLG ADDSPELLFLG)
            (LISPXHIST LISPXHIST)
            (FILECREATEDLST)
            (PRLST (AND FILEPKGFLG (FILEPKGCHANGES)))
            INSTREAM FNLST VARLST DONELST ROOTNAME FILEMAP TEM FILEMAPEND FILECREATEDLOC FILENV 
            RESETSAVER MAPUPDATED)
           (DECLARE (SPECVARS *PACKAGE* DFNFLG BUILDMAPFLG FILEPKGFLG ADDSPELLFLG LISPXHIST FNLST 
                           VARLST DONELST FILECREATEDLST FILECREATEDLOC))
                                                             (* 
                       "FILECREATEDLST is set by SCANEXP when it encounters a FILECREATED expression")
       TOP (COND
              ((OR (EQ LDFLG (QUOTE EXPRESSIONS))
                   (EQ LDFLG (QUOTE GETDEF))
                   (MEMB LDFLG LOADOPTIONS))
               (SETQ DFNFLG LDFLG))
              ((AND DWIMFLG (SETQ TEM (FIXSPELL LDFLG NIL LOADOPTIONS T)))
               (SETQ LDFLG TEM)
               (SETQ DFNFLG LDFLG))
              (T (SETQ LDFLG (ERROR "unrecognized load option" LDFLG))
                 (GO TOP)))
           (COND
              ((EQ LDFLG (QUOTE SYSLOAD))
               (SETQ DFNFLG T)
               (SETQ ADDSPELLFLG NIL)
               (SETQ BUILDMAPFLG NIL)
               (SETQ FILEPKGFLG NIL)
               (SETQ LISPXHIST NIL)))
           [AND LISPXHIST (COND
                             ((SETQ TEM (FMEMB (QUOTE SIDE)
                                               LISPXHIST))
                              (FRPLACA (CADR TEM)
                                     -1))
                             (T (LISPXPUT (QUOTE SIDE)
                                       (LIST -1)
                                       NIL LISPXHIST]        (* 
                    "So that UNDOSAVE will keep saving regardless of how many undosaves are involved")
           (SETQ FNLST (LOADFNS1 FNS T))                     (* "Get list of functions")
           [COND
              ((NULL FILE)                                   (* 
                                                  "Infer what file caller meant (this is a feature!)")
               (SETQ FILE (LOADFNS0 (CAR FNLST]
       RETRY
           [RESETSAVE NIL (SETQ RESETSAVER (LIST (QUOTE CLOSEF?)
                                                 (SETQ INSTREAM (OPENSTREAM FILE (QUOTE INPUT]
                                                             (* CLOSEF? not CLOSEF because 
                                                             UPDATEFILEMAP might close file for us)
           (RESETSAVE (INPUT INSTREAM))
           (SETQ FILE (FULLNAME INSTREAM))                   (* 
  "Gets full file name.  Also note that there may have been some error correction done in OPENSTREAM")
           (COND
              ((NOT (RANDACCESSP INSTREAM))
               (SETQ FILE (ERROR FILE "not a random access file"))
               (GO RETRY)))
           (SETFILEPTR INSTREAM 0)
           (SETQ ROOTNAME (ROOTFILENAME FILE))
           (MULTIPLE-VALUE-SETQ (FILENV FILEMAP FILECREATEDLOC)
                  (GET-ENVIRONMENT-AND-FILEMAP INSTREAM))
           (SETQ VARLST (SELECTQ VARS
                            (NIL NIL)
                            (VARS                            (* 
                                                         "Means load, i.e., evaluate, ALL rpaq/rpaqq")
                                  (QUOTE VARS))
                            (FNS/VARS (LIST (FILECOMS ROOTNAME (QUOTE COMS))
                                            (FILECOMS ROOTNAME (QUOTE BLOCKS))))
                            (LOADCOMP                        (* 
                                     "evaluate the EVAL@COMPILE expresions, notice the fns and vars.")
                                      (SETQ FNLST T)
                                      VARS)
                            (FILEMAP                         (* 
                                          "Return the filemap, or build one if not already available")
                                     (if (AND FILEMAP (NULL (CAR FILEMAP)))
                                         then (RETURN FILEMAP)
                                       elseif (NULL BUILDMAPFLG)
                                         then (RETURN NIL))
                                     (QUOTE FILEMAP))
                            (LOADFROM                        (* "evaluate all non-defineq expressions, but just return file name as value, i.e.  dont bother adding to donelst")
                                      (QUOTE LOADFROM))
                            (DONTCOPY                        (* 
                                                       "means load all DECLARE: DONTCOPY expressions")
                                      VARS)
                            (LOADFNS1 VARS)))
           (SETQ FILEMAPEND (if FILEMAP
                                then (CAR FILEMAP)
                              else T))                       (* 
                                                      "Remember how far the filemap scan got already")
           [WITH-READER-ENVIRONMENT
            FILENV
            (SETQ FILEMAP (LOADFNSCAN FILEMAP))
          
          (* * "SCANFILE0 returns a 'map' for the file.  The form of the map is (ADR ADRLST ADRLST ...) where ADR is last address scanned to in file, or NIL if entire file was scanned, or (ADR) where the scan stopped after a function in the middle of a DEFINEQ.  Each ADRLST is either of the form (ADR1 ADR2 . FN) or (ADR1 ADR2 (FN ADRX . ADRY) (FN ADRX . ADRY) ...).

The first case corresponds to a compiled function, the second to a DEFINEQ.  In the first case, ADR1 is the address of the first character AFTER the function name in the file (for use by LAPRD) and ADR2 the address of the first character after the de definition, i.e., after LAPRD or LCSKIP has finished.

In the second case, ADR1 is the address of the lef paren before the DEFINEQ, and ADR2 either the address of the first character after the entire DEFINEQ expression, or the address of the first chracter after the last function that was scanned.  In (FN ADRX . ADRY), ADR is the address of of the left parentheses before the function name, ADRY the address of the character after the right paren that closes the definition.  

A map of non-functions is not kept because (a) it would not be of use to MAKEFILE since it always recomputes VARS, and (B) most requests for other than functions require scanning the entire file anyway, e.g. to find all RPAQQ's, and (C) the expressions are usually small compared to DEFINEQ's.")

            [if FILEMAP
                then
                (if (NEQ FILEMAPEND (CAR FILEMAP))
                    then                                     (* "something was added")
                         (PUTFILEMAP FILE FILEMAP FILECREATEDLST)
                         (if (AND UPDATEMAPFLG (UPDATEFILEMAP INSTREAM FILEMAP))
                             then (SETQ MAPUPDATED T)))
                (if (AND DWIMFLG (NOT NOSPELLFLG)
                         (LISTP FNLST))
                    then                                     (* 
                                                       "There are still FNS left that we didn't find")
                    (if (SETQ TEM
                         (for X on FNLST
                            bind [KNOWNFNS ← (for TRIPLE in (CDR FILEMAP)
                                                join         (* 
                                   "makes a list of functions found for use for spelling correction.")
                                                     (if (LISTP (SETQ TEM (CDDR TRIPLE)))
                                                         then 
                                                             (* 
                            "This is for normal source files, where TRIPLE = (start end . fnEntries)")
                                                              (MAPCAR TEM (FUNCTION CAR))
                                                       elseif TEM
                                                         then 
                                                             (* 
                                                      "For compiled files, TRIPLE = (start end . fn)")
                                                              (LIST TEM]
                            when (AND (NOT (FMEMB (CAR X)
                                                  KNOWNFNS))
                                      (SETQ X (FIXSPELL (CAR X)
                                                     70 KNOWNFNS NIL X))) collect 
                                                             (* "The FMEMB check is necessary for when VARS=DEFS, as the reason that the function was not removed from FNLST may have been because this was a compiled file.")
                                                                                X))
                        then (if MAPUPDATED
                                 then                        (* UPDATEFILEMAP had closed the file)
                                      [RPLACA (CDR RESETSAVER)
                                             (SETQ STREAM (OPENSTREAM FILE (QUOTE INPUT]
                                      (INPUT STREAM))
                             (SCANFILE1 FILEMAP TEM]
            (if (AND NOT-FOUNDTAG (LISTP FNLST))
                then (SETQ DONELST (CONS (CONS NOT-FOUNDTAG FNLST)
                                         DONELST)))
            (if
             [AND
              NOT-FOUNDTAG
              (LISTP VARLST)
              (SETQ TEM
               (if (FNTYP VARLST)
                   then (AND (NULL DONELST)
                             (LIST VARLST))
                 else (for X in VARLST collect X
                         unless (PROGN                       (* "Reason for this is if user says LOADVARS (DEFLIST file), then DEFLIST is not removed from VARLST, since you want all such instances.")
                                       (for Y in DONELST
                                          thereis (if (ATOM X)
                                                      then (OR (EQ X (CAR Y))
                                                               (EQ X (CADR Y)))
                                                    else (EDIT4E X Y]
                then (SETQ DONELST (CONS (CONS NOT-FOUNDTAG TEM)
                                         DONELST)))
            (if (EQ LDFLG (QUOTE SYSLOAD))
                then (AND (NOT (MEMB (SETQ ROOTNAME (ROOTFILENAME FILE (CDR FILECREATEDLST)))
                                     SYSFILES))
                          (SETQ SYSFILES (NCONC1 SYSFILES ROOTNAME)))
                     (SMASHFILECOMS ROOTNAME)
              elseif FILEPKGFLG
                then (AND (NEQ VARS (QUOTE FILEMAP))
                          (NEQ LDFLG (QUOTE EXPRESSIONS))
                          (NEQ LDFLG (QUOTE GETDEF))
                          (ADDFILE FILE (SELECTQ VARS
                                            ((T LOADFROM) 
                                                 (QUOTE LOADFNS))
                                            (LOADCOMP (QUOTE LOADCOMP))
                                            (QUOTE loadfns))
                                 PRLST FILECREATEDLST]
           (RETURN (if (EQ VARS (QUOTE FILEMAP))
                       then FILEMAP
                     elseif (EQ VARS (QUOTE LOADFROM))
                       then FILE
                     else (DREVERSE DONELST])

(LOADFNS0
  [LAMBDA (FN)                                               (* lmm "19-Jun-86 14:00")
    (PROG ((DWIMFLG T)
           (FILEPKGFLG T))
          (RETURN (OR (EDITLOADFNS? FN)
                      (AND (EQ (NARGS (QUOTE WHEREIS))
                               4)
                           (EDITLOADFNS? FN NIL NIL T))
                      (ERROR FN (QUOTE "'s file not found")
                             T])

(LOADFNS1
  [LAMBDA (X FNSFLG)                                         (* wt: " 6-MAR-80 11:14")
    (COND
       ((EQ X T)                                             (* Eleanor's option, load every fn 
                                                             found in FILE.)
        T)
       ((NULL X)
        NIL)
       ((LITATOM X)
        (LIST X))
       ((NLISTP X)
        (ERROR (QUOTE "illegal arg")
               X))
       [(NULL FNSFLG)
        (MAPCAR X (FUNCTION (LAMBDA (X)
                              (EDITFPAT X]
       (T (MAPCONC X (FUNCTION (LAMBDA (X)
                                 (COND
                                    ((LITATOM X)
                                     (LIST X))
                                    (T (LISPXPRIN2 X T T)
                                       (LISPXPRIN1 (QUOTE " isn't a function name -- ignored.
"))
                                       NIL])

(GETBLOCKDEC
  [LAMBDA (FN FILE FNSONLY)                                  (* lmm " 7-SEP-78 18:39")
    (PROG (BLOCKS BLOCK)
          (OR FILE (SETQ FILE (LOADFNS0 FN)))
          (AND [LISTP (SETQ BLOCKS (FILECOMSLST FILE (QUOTE BLOCKS]
               [SOME BLOCKS (FUNCTION (LAMBDA (X)
                                        (MEMB FN (SETQ BLOCK X]
               (RETURN (COND
                          ((NULL FNSONLY)
                           BLOCK)
                          (T (OR [AND (CAR BLOCK)
                                      (SETQ BLOCKS (SUBSET (CDR BLOCK)
                                                          (FUNCTION ATOM]
                                 (LIST FN])

(LOADFNSCAN
  [LAMBDA (DICT)                                             (* wt: " 7-DEC-79 11:57")
    (PROG (ADR)
          (SCANFILE0)
          (RETURN DICT])

(SCANFILE0
  [LAMBDA NIL                                                (* bvm: "29-Aug-86 23:15")
    (PROG (NXT NXT1 NXT2 FNADRLST (DICT0 (CDR DICT)))
          [COND
             [(NULL DICT)
              (AND BUILDMAPFLG (SETQ DICT (LIST 0]
             (FNLST                                          (* Have some filemap, so go get 
                                                             functions that are on the map)
                    (SCANFILE1 (CDR DICT]
          (COND
             ([AND (NULL VARLST)
                   (OR (NULL FNLST)
                       (AND DICT (NULL (CAR DICT]            (* Either all functions were found, or 
                                                             else the entire file having been 
                                                             scaaned, no point in scanning further)
              (RETURN DICT)))
          (COND
             ((AND VARLST (NEQ VARLST (QUOTE FILEMAP)))
          
          (* Note that at this point there may or may not be some functions to be scanned 
          for. in any event, since there are VARS to be obtained, we have to start 
          scanning at the beginning, although DICT can be of use to save scanning of 
          DEFINEQ's.)

              (SETFILEPTR NIL (OR FILECREATEDLOC 0)))
             ((LISTP (CAR DICT))                             (* The scan stopped in the middle of a 
                                                             DEFINEQ.)
              (SETFILEPTR NIL (SETQ ADR (CAAR DICT)))
              [AND BUILDMAPFLG (SETQ FNADRLST (LCONC NIL (CAR (LAST DICT]
              (SETQ DICT0 NIL)
              (SCANDEFINEQ T))
             (DICT                                           (* Scan stopped after a compiled 
                                                             function.)
                   (SETFILEPTR NIL (CAR DICT))
                   (SETQ DICT0 NIL)))
      PEEKLP
          (SETQ NXT1 (SKIPSEPRCODES))
          (COND
             [(OR (SYNTAXP NXT1 (QUOTE LEFTPAREN))
                  (SYNTAXP NXT1 (QUOTE LEFTBRACKET)))        (* Opening paren and bracket.)
              (SETQ ADR (GETFILEPTR))
              (READC)                                        (* Flush the peeked-at paren.)
              (SETQ NXT1 (RATOM))
              (COND
                 ((EQ NXT1 (QUOTE DEFINEQ))
                  (SCANDEFINEQ))
                 (T                                          (* some functions may be inside of 
                                                             declare:'s so have to look at each 
                                                             expression, even if varlst=NIL)
                    (SETQ NXT2 (RATOM))                      (* Corresponds to CADR of the 
                                                             expression. in the file)
                    (SETFILEPTR NIL ADR)                     (* file pointer now points to just 
                                                             before the expression..)
                    (SCANEXP NXT1 NXT2 (NEQ VARLST (QUOTE LOADCOMP]
             ((OR (EQ (SETQ NXT (READ))
                      (QUOTE STOP))
                  (NULL NXT))                                (* End of file.)
              (AND (CAR DICT)
                   (RPLACA DICT NIL))                        (* says scan of entire map now 
                                                             complete)
              (RETURN))
             ((LITATOM NXT)
              (SETQ ADR (GETFILEPTR))
              (SCANCOMPILEDFN NXT)))
          (GO PEEKLP])

(SCANCOMPILEDFN
  [LAMBDA (FNAME)                                            (* wt: " 9-APR-80 20:54")
    (PROG NIL
          [COND
             (DICT0 (AND (NOT (EQP (CAAR DICT0)
                                   ADR))
                         [NOT (SETQ DICT0 (SOME DICT0 (FUNCTION (LAMBDA (X)
                                                                  (IEQP ADR (CAR X]
                         (RETRYSCAN))
          
          (* redudnacy check the SOME is bcause of the
          (admittedly obsucre but actually happened) case where there are DEFINEQ's 
          inside of a DECLARE:.. in this case, they would appear on the filemap, but 
          DICT0 would not have been stepped because the DEFINIEQ's would not have been 
          seen in the scan.)

                    (SETFILEPTR NIL (CADAR DICT0))
          
          (* We know this function is not of interest, or it ould have been picked up in 
          SCANFILE1. Furthermore, we know its final address, so no need to LCSKIP)

                    (SETQ DICT0 (CDR DICT0))
                    (RETURN T))
             (BUILDMAPFLG (NCONC1 DICT (SETQ FNADRLST (CONS (GETFILEPTR)
                                                            (CONS NIL FNAME]
          [COND
             [[AND FNLST (NEQ LDFLG (QUOTE EXPRESSIONS))
                   (NEQ LDFLG (QUOTE GETDEF))
                   (NEQ VARS (QUOTE LOADCOMP))
                   (OR (EQ FNLST T)
                       (MEMB FNAME FNLST)
                       (SOME FNLST (FUNCTION (LAMBDA (X)
                                               (TMPSUBFN FNAME X]
                                                             (* We want FNAME if it is on FNLST, or 
                                                             a SUBFN of anything on FNLST.
                                                             or if FNLST, is T, i.e.
                                                             load everything.)
              (LAPRD FNAME)
              (SETQ DONELST (CONS FNAME DONELST))
              [AND FNADRLST (RPLACA (CDR FNADRLST)
                                   (SETQ ADR (GETFILEPTR]
              (COND
                 ((AND (NEQ FNLST T)
                       (NULL (SETQ FNLST (DREMOVE FNAME FNLST)))
                       (NULL VARLST))
                  (AND DICT (RPLACA DICT ADR))
                  (RETFROM (QUOTE SCANFILE0]
             (T (LCSKIP FNAME)
                (AND FNADRLST (RPLACA (CDR FNADRLST)
                                     (GETFILEPTR]
          (RETURN T])

(SCANDEFINEQ
  [LAMBDA (CONTINUEFLG)                                      (* bvm: "30-Aug-86 15:54")
                                                             (* L called with file pointer just 
                                                             after atom DEFINEQ)
    (PROG (FNAME)
          (COND
             (CONTINUEFLG (GO DEFQLP))
             ([AND DICT0 (NOT (IEQP (CAAR DICT0)
                                    ADR))
                   (NOT (SETQ DICT0 (find X in DICT0 suchthat (IEQP ADR (CAR X]
              (RETRYSCAN)))
          
          (* Double check. the SOME is bcause of the
          (admittedly obsucre but actually happened) case where there are DEFINEQ's 
          inside of a DECLARE:.. in this case, they would appear on the filemap, but 
          DICT0 would not have been stepped because the DEFINIEQ's would not have been 
          seen in the scan. Now we know that CAR of DICT0 corrresponds to this DEFINEQ.
          We process DEFINEQ's the same when there are functions to be found, i.e.
          when FNLST is non-NIL, as when there aren't any, on the grounds that it takes 
          about as long to do many little SKREAD's as one big SKREAD, and this way we 
          also get to build the map.)

          [COND
             ((CADAR DICT0)
          
          (* This entire DEFINEQ was scanned, and ADR is the address of the first 
          character after it. SFPTR and go on, i.e.
          dont have to do SKREAD Note thatthis applies even if we are looking for 
          functions,, i.e. FNLST not NIL, because in this case all function of interest 
          would have been picked up by SCANFILE1.)

              (SETFILEPTR NIL (CADAR DICT0))
              (SETQ DICT0 (CDR DICT0))
              (RETURN T))
             (DICT0 
          
          (* The scan previously stopped in the middle of a DEFINEQ.
          The address of the end of the scan, i.e.
          (CAAR DICT), corresponds to the character after the last function scanned.)

                    [SETFILEPTR NIL (COND
                                       ((LISTP (CAR DICT))
                                        (CAAR DICT))
                                       (T 
          
          (* Another redudancy check. If the entire DEFINEQ had been processed, then 
          CADAR of DICT0 would be non-NIL, and caught above.
          Therefore, processing stopped in the middle of the DEFINEQ, and CAR of DICT 
          should be a list.)

                                          (RETRYSCAN]
                    [AND BUILDMAPFLG (SETQ FNADRLST (LCONC NIL (CAR DICT0]
                    (SETQ DICT0 NIL))
             (BUILDMAPFLG (SETQ FNADRLST (TCONC NIL ADR))
                    (TCONC FNADRLST NIL)
                    (NCONC1 DICT (CAR FNADRLST]
      DEFQLP
          (SELECTQ (RATOM)
              (%)                                            (* Closes DEFINEQ.)
                  (AND FNADRLST (RPLACA (CDAR FNADRLST)
                                       (GETFILEPTR)))        (* FNADRLST is a ONC format list, 
                                                             hence want to RPLACA CDAR, not just 
                                                             CDR.)
                  (RETURN T))
              (%] (SCANFILEHELP))
              ((%( %[) 
                   (SETQ ADR (SUB1 (GETFILEPTR)))            (* The address of the position of the 
                                                             left paren.)
                   (SETQ FNAME (READ))
                   (AND FNADRLST (TCONC FNADRLST (LIST FNAME ADR))))
              (SCANFILEHELP))
          (SETFILEPTR NIL ADR)
          
          (* Positions file pointer at left paren or brakcet so if fn/def pair is closed 
          bby either right paren or bracket, read or skread will do the right thing.)

          (COND
             [(AND FNLST (OR (EQ FNLST T)
                             (MEMB FNAME FNLST)))
              (SELECTQ VARS
                  (LOADCOMP (AND (NOT (FMEMB FNAME NOFIXFNSLST))
                                 (SETQ NOFIXFNSLST (CONS FNAME NOFIXFNSLST)))
                            (SKREAD))
                  (SETQ DONELST (NCONC [COND
                                          ((OR (EQ LDFLG (QUOTE EXPRESSIONS))
                                               (EQ LDFLG (QUOTE GETDEF)))
                                           (LIST (READ)))
                                          (T (DEFINE (LIST (READ]
                                       DONELST)))
              (AND (NEQ FNLST T)
                   (SETQ FNLST (DREMOVE FNAME FNLST]
             (T (SKREAD)))
          (AND FNADRLST (RPLACD (CDADR FNADRLST)
                               (GETFILEPTR)))
          
          (* FNADRLST is a TCONC format, so its CADR is its last element.
          This is supposed to be of the form (FN ADRX . ADRY)%.
          This adds the ADRY.)

          [COND
             ((AND (NULL FNLST)
                   (NULL VARLST))
          
          (* Actually this check only need be made in the case that a function was 
          actually read, i.e. second clause in above COND, but its cheap enough.)

              [AND DICT (RPLACA DICT (LIST (ADD1 (GETFILEPTR](* says scan stopped in middle of 
                                                             defineq)
              (RETFROM (QUOTE SCANFILE0]
          (GO DEFQLP])

(SCANEXP
  [LAMBDA (EXP1 EXP2 EVALFLG)                                (* bvm: "29-Aug-86 22:32")
                                                             (* exp1 is car of the expression, exp2 
                                                             cadr. file pointer is just before 
                                                             opening left paren and scanexp reads 
                                                             expression if it needs to.)
    (DECLARE (USEDFREE FILECREATEDLST))
    (PROG (EXP)
          (COND
             ((EQ VARLST (QUOTE COMPILING))                  (* wants whole declare:)
              (GO YES))
             ((EQ EXP1 (QUOTE DECLARE:))
              (COND
                 (EXP (SETFILEPTR NIL ADR)))
              (RATOM)
              (RATOM)                                        (* SKIP OVER THE PAREN AND THE 
                                                             DECLARE:)
              (if (EQ VARLST (QUOTE DONTCOPY))
                  then (SCANDECLARE: NIL T)
                else (SCANDECLARE: EVALFLG))
              (RETURN T)))
          (SELECTQ VARLST
              ((T LOADFROM) 
                   (AND EVALFLG (GO YES)))
              (VARS [AND EVALFLG (COND
                                    ((OR (EQ EXP1 (QUOTE RPAQQ))
                                         (EQ EXP1 (QUOTE RPAQ))
                                         (EQ EXP1 (QUOTE RPAQ?)))
                                     (GO YES])
              (LOADCOMP (AND EVALFLG (GO YES))
                        (SELECTQ EXP1
                            ((RPAQQ RPAQ RPAQ?) 
                                 (SETQ NOFIXVARSLST (AND (NOT (FMEMB EXP2 NOFIXVARSLST))
                                                         (CONS EXP2 NOFIXVARSLST))))
                            NIL))
              (AND (LISTP VARLST)
                   [COND
                      ((FNTYP VARLST)
                       (COND
                          ((NULL (SETQ EXP (APPLY* VARLST EXP1 EXP2)))
                                                             (* the functional expression is ree to 
                                                             move filepinter.)
                           (SETFILEPTR NIL ADR)
                           NIL)
                          ((NLISTP EXP)                      (* matched, but user elected not to 
                                                             return entire expression)
                           (SETFILEPTR NIL ADR)
                           (SETQ EXP (READ)))
                          (T T)))
                      (T (SOME VARLST (FUNCTION (LAMBDA (X)
                                                  (COND
                                                     ((OR (EQ EXP1 X)
                                                          (EQ EXP2 X)))
                                                     ((LISTP X)
                                                             (* edit pattern)
                                                      [COND
                                                         ((NULL EXP)
          
          (* The expression on VARLST is a list, which is interpred as an edit pattern, 
          therefore we have to read the entire expression from the file.
          Note that this is only done once, i.e. if there are several patterns on VARLST, 
          the expression from the file is read only once.)

                                                          (SETQ EXP (READ]
                                                      (EDIT4E X EXP]
                   (GO YES)))
          (COND
             ((EQ EXP1 (QUOTE FILECREATED))
              [SETQ FILECREATEDLST (NCONC1 FILECREATEDLST (CDR (OR EXP (SETQ EXP (READ]
                                                             (* So that ADDFILE will have necessary 
                                                             information when it is called.)
              (FILECREATED1 (CDR EXP))                       (* does error checking on filecreated 
                                                             expression)
              )
             ((NULL EXP)
              (SKREAD)))
          (RETURN T)
      YES                                                    (* This IS one of the expressions 
                                                             specified by VARLST.)
          [COND
             ((NULL EXP)
          
          (* If EXP is non-null, means for some eason it had to be READ, e.g.
          there was an dit pattern in VARLST. IN this case not necessary to SKREAD since 
          we have already passed over that expression.)

              (SETQ EXP (READ]
          [COND
             ((AND (NEQ VARLST (QUOTE LOADFROM))
                   (NEQ VARLST (QUOTE LOADCOMP)))
              (SETQ DONELST (CONS EXP DONELST]
          (COND
             ((AND (NEQ LDFLG (QUOTE EXPRESSIONS))
                   (NEQ LDFLG (QUOTE GETDEF)))
              (EVAL EXP)))
          (RETURN T])

(SCANDECLARE:
  [LAMBDA (EVALFLG DONTCOPIES)                               (* bvm: "30-Aug-86 16:06")
          
          (* handles DECLARE:'s only called for either VARS=COMP, or for looking for 
          specific expression or expresions, e.g. VARS, or edit pattern.
          For EXPRESSIONS, T, etc., higher call to SCANEXP has already decided what to 
          do.)

    (PROG ((VARLST (if DONTCOPIES
                       then T
                     else VARLST))
           TEM)
      LP  (SETQ ADR (GETFILEPTR))
          [SELECTQ (SETQ TEM (RATOM))
              ((%( %[) 
                   (SETQ ADR (SUB1 (GETFILEPTR)))
          
          (* reason for this is that there may have been some separators before the %(, 
          e.g. a space and c.r., and in this case the ADR will not match up with what was 
          stored in the file map, which would be the position justbefore the %(.
          The right way to do this is of course not to RATOM but to do a loop with peekc 
          until you ee a non-separator and then record the address.
          however, thi is inefficient and unnecessary since this is the nly case where it 
          matters)

                   (SELECTQ (SETQ TEM (RATOM))
                       (DEFINEQ (PROG ((ADR ADR))
                                      (SCANDEFINEQ)
          
          (* easier to call scandefineq even if FNS is NIL because it knows how to 
          position file pointer without aving to call skread by using filemap)

                                  )
                                [COND
                                   ((AND EVALFLG (EQ VARLST (QUOTE LOADCOMP))
                                         (EQ FNLST T))       (* LOADCOMP is handled specially.
                                                             the SCANDEFINEQ would not have 
                                                             actually done any defining, just 
                                                             scanned for the purposes of 
                                                             constructing the map.)
                                    (SETFILEPTR NIL ADR)
                                    (SETQ TEM (READ))
                                    (COND
                                       ((OR (EQ LDFLG (QUOTE EXPRESSIONS))
                                            (EQ LDFLG (QUOTE GETDEF)))
                                        (SETQ DONELST (CONS TEM DONELST)))
                                       (T (EVAL TEM])
                       (DECLARE: (SCANDECLARE: EVALFLG DONTCOPIES))
                       (SCANEXP TEM (PROG1 (RATOM)
                                           (SETFILEPTR NIL ADR))
                              EVALFLG)))
              ((%) %]) 
                   (RETURN T))
              (COND
                 (DONTCOPIES (SELECTQ TEM
                                 (DONTCOPY (SETQ EVALFLG T))
                                 ((EVAL@COMPILEWHEN) 
                                      (SKREAD))
                                 (COPYWHEN (SKREAD)
                                           (SETQ EVALFLG T))
                                 NIL))
                 ((NEQ LDFLG (QUOTE GETDEF))                 (* getdef means ignore tags, find it 
                                                             if its there.)
                  (SELECTQ TEM
                      ((EVAL@COMPILE DOEVAL@COMPILE) 
                           (AND (EQ VARLST (QUOTE LOADCOMP))
                                (SETQ EVALFLG T)))
                      (DONTEVAL@COMPILE 
                           (AND (EQ VARLST (QUOTE LOADCOMP))
                                (SETQ EVALFLG NIL)))
                      ((EVAL@LOAD DOEVAL@LOAD) 
                           (AND (NEQ VARLST (QUOTE LOADCOMP))
                                (SETQ EVALFLG T)))
                      (DONTEVAL@LOAD (AND (NEQ VARLST (QUOTE LOADCOMP))
                                          (SETQ EVALFLG NIL)))
                      (EVAL@COMPILEWHEN 
                           (SETQ TEM (READ))
                           (AND (EQ VARLST (QUOTE LOADCOMP))
                                (SETQ EVALFLG (EVAL TEM))))
                      (EVAL@LOADWHEN (SETQ TEM (READ))
                                     (AND (NEQ VARLST (QUOTE LOADCOMP))
                                          (SETQ EVALFLG (EVAL TEM))))
                      (COPYWHEN (SKREAD))
                      NIL]
          (GO LP])

(SCANFILE1
  [LAMBDA (DICT LST)                                         (* bvm: "29-Aug-86 22:11")
    (AND (NULL LST)
         (SETQ LST FNLST))                                   (* looks up functions on LST, if 
                                                             given, but removes them from FNLST.
                                                             This so can be called directly from 
                                                             LOADFNS.)
    (PROG (($$LST1 DICT)
           X FNAME TEM)
      $$LP
          (SETQ X (CAR $$LST1))
          (COND
             ((OR (NLISTP $$LST1)
                  (NOT LST))
              (RETURN NIL)))
          (COND
             [(NLISTP (SETQ FNAME (CDDR X)))                 (* compiled definition.)
              (COND
                 ((OR (EQ LDFLG (QUOTE EXPRESSIONS))
                      (EQ LDFLG (QUOTE GETDEF))
                      (EQ VARS (QUOTE LOADCOMP)))            (* User wants symbolic definitions 
                                                             only.)
                  )
                 ([OR (EQ LST T)
                      (MEMB FNAME LST)
                      (SOME LST (FUNCTION (LAMBDA (Y)
                                            (TMPSUBFN FNAME Y]
                  (SETFILEPTR NIL (CAR X))
                  (COND
                     ([NOT (OR (EQ (SETQ TEM (READ))
                                   (QUOTE BINARY))
                               (GETPROP TEM (QUOTE CODEREADER]
          
          (* a file map was built in core, but it isnt right, e.g.
          user ftped another file by same name since this map was built in core.
          so remove map and retry)

                      (RETRYSCAN)))
                  (SETFILEPTR NIL (CAR X))
                  (LAPRD FNAME)
                  (AND (OR (EQ DFNFLG (QUOTE PROP))
                           (EQ DFNFLG (QUOTE ALLPROP)))
                       (UNSAVEDEF FNAME))
                  (SCANFILE2 FNAME]
             (T                                              (* DEFINEQ.)
                (for Y in (CDDR X) do [COND
                                         [(EQ VARS (QUOTE LOADCOMP))
                                          (AND (NOT (FMEMB (CAR Y)
                                                           NOFIXFNSLST))
                                               (SETQ NOFIXFNSLST (CONS (CAR Y)
                                                                       NOFIXFNSLST]
                                         ((OR (EQ LST T)
                                              (MEMB (CAR Y)
                                                    LST))
                                          (SETFILEPTR NIL (CADR Y))
                                          (COND
                                             ([NEQ (CAR Y)
                                                   (CAR (SETQ TEM (READ]
                                              (ERROR (QUOTE "filemap does not agree with contents of"
                                                            )
                                                     (INPUT)
                                                     T)))
                                          (COND
                                             ((OR (EQ LDFLG (QUOTE EXPRESSIONS))
                                                  (EQ LDFLG (QUOTE GETDEF)))
                                              (SCANFILE2 TEM))
                                             (T (DEFINE (LIST TEM))
                                                (SCANFILE2 (CAR TEM] while LST)))
      $$ITERATE
          (SETQ $$LST1 (CDR $$LST1))
          (GO $$LP])

(SCANFILE2
  [LAMBDA (X)
    (SETQ DONELST (CONS X DONELST))
    (AND (NEQ FNLST T)
         (SETQ FNLST (DREMOVE (COND
                                 ((LISTP X)
                                  (CAR X))
                                 (T X))
                            FNLST])

(TMPSUBFN
  [LAMBDA (X FN)                                             (* bvm: "28-Aug-86 14:13")
                                                             (* This guy wants names like 
                                                             FNAnnnnAmmmm...)
    (PROG ((N (STRPOS FN X 1 NIL T T))
           NX C)
          (if (OR (NULL N)
                  (NEQ (IREMAINDER (IDIFFERENCE (SETQ NX (ADD1 (NCHARS X)))
                                          N)
                              5)
                       0))
              then                                           (* X does not start with FN, or end in 
                                                             an integral number of 5 character 
                                                             pieces)
                   (RETURN))
      LP  (if [OR (NEQ (NTHCHARCODE X N)
                       (CHARCODE A))
                  (NOT (for I from 1 to 4 always (AND (SETQ C (NTHCHARCODE X (IPLUS I N)))
                                                      (IGEQ C (CHARCODE 0))
                                                      (ILEQ C (CHARCODE 9]
              then (RETURN)
            elseif (IGEQ (add N 5)
                         NX)
              then (RETURN T))
          (GO LP])

(RETRYSCAN
  [LAMBDA NIL                                                (* bvm: "28-Aug-86 17:05")
    (COND
       ((GETHASH FILE *FILEMAP-HASH*)
        (REMHASH FILE *FILEMAP-HASH*)
        (PRIN1 "something is wrong with the filemap for " T)
        (PRINT FILE T)
        (PRIN1 "rebuilding map..." T)
        (RETFROM (QUOTE LOADFNSCAN)
               (LOADFNSCAN)))
       (T (SCANFILEHELP])

(SCANFILEHELP
  [LAMBDA NIL                                                (* JonL "15-Dec-83 21:04")
                                                             (* This function used to spit out a 
                                                             "sermon" about sysouting and informing 
                                                             W. Teitelman.)
    (PRIN1 (QUOTE "something is wrong with either the filemap or format of ")
           T)
    (PRIN1 (INPUT)
           T)
    (TERPRI T)
    (PRIN1 (QUOTE "Here are some possibilities:
(1) you edited the file with a text editor;
(2) you printed a DEFINEQ in the file directly, i.e. without using
      the FNS command;
(3) the file got clobbered.

If you are convinced it is none of the above, then please inform
the 1100Support program.")
           T)
    (TERPRI T)
    (PRIN1 (QUOTE "Note: for (1) and (2), you may still be
able to use this file by setting USEMAPFLG to NIL,
and then reexecuting the operation that caused this
message.")
           T)
    (TERPRI T)
    (HELP])
)

(RPAQQ NOT-FOUNDTAG NOT-FOUND:)
[DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY
(BLOCK: SCANFILEBLOCK LOADFNSCAN SCANFILE0 SCANCOMPILEDFN SCANDEFINEQ SCANEXP SCANDECLARE: SCANFILE1 
       SCANFILE2 TMPSUBFN (LOCALFREEVARS FNADRLST DICT DICT0 ADR)
       (SPECVARS LDFLG PRINTFLG FNS FNLST VARLST VARS DONELST)
       (GLOBALVARS SYSFILES DWIMFLG FILERDTBL LOADOPTIONS)
       (ENTRIES LOADFNSCAN TMPSUBFN SCANFILE1)
       (RETFNS SCANFILE0))
(BLOCK: NIL LOADFROM (GLOBALVARS LASTWORD DWIMFLG))
(BLOCK: NIL LOADFNS LOADFNS0 LOADFNS1 (GLOBALVARS DWIMFLG LOADOPTIONS SYSFILES NOT-FOUNDTAG))
]
(PUTPROPS LOADFNS COPYRIGHT ("Xerox Corporation" 1983 1984 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1356 47628 (LOADFROM 1366 . 1841) (LOADBLOCK 1843 . 2272) (LOADCOMP 2274 . 2789) (
LOADCOMP? 2791 . 3616) (LOADVARS 3618 . 3698) (LOADEFS 3700 . 3849) (LOADFILEMAP 3851 . 4295) (LOADFNS
 4297 . 16608) (LOADFNS0 16610 . 17046) (LOADFNS1 17048 . 17986) (GETBLOCKDEC 17988 . 18700) (
LOADFNSCAN 18702 . 18879) (SCANFILE0 18881 . 22617) (SCANCOMPILEDFN 22619 . 25238) (SCANDEFINEQ 25240
 . 30864) (SCANEXP 30866 . 36052) (SCANDECLARE: 36054 . 40680) (SCANFILE1 40682 . 44465) (SCANFILE2 
44467 . 44753) (TMPSUBFN 44755 . 46118) (RETRYSCAN 46120 . 46538) (SCANFILEHELP 46540 . 47626)))))
STOP