Annotation of 42BSD/ucb/lisp/liszt/tlev.l, revision 1.1.1.1

1.1       root        1: (include-if (null (get 'chead 'version)) "../chead.l")
                      2: (Liszt-file tlev
                      3:    "$Header: tlev.l,v 1.13 83/09/12 15:25:29 layer Exp $")
                      4: 
                      5: ;;; ----       t l e v                         top level interface
                      6: ;;;
                      7: ;;;                            -[Fri Sep  2 21:50:34 1983 by layer]-
                      8: 
                      9: ;--- lisztinit : called upon compiler startup. If there are any args
                     10: ;             on the command line, we build up a call to liszt, which
                     11: ;             will do the compile. Afterwards we exit.
                     12: ;
                     13: (def lisztinit
                     14:    (lambda nil
                     15:       (setq fl-asm nil)                ; insure it as correct value in case of int
                     16:       (let ((args (command-line-args)))
                     17:         (if args
                     18:            then (signal 2 'liszt-interrupt-signal)  ; die on int
                     19:                 (signal 15 'liszt-interrupt-signal)  ; die on sigterm
                     20:                 (setq user-top-level nil)
                     21:                 (exit (apply 'liszt args))
                     22:            else (patom compiler-name)
                     23:                 (patom " [")(patom franz-minor-version-number)(patom "]")
                     24:                 (terpr poport)
                     25:                 (setq user-top-level nil)))))
                     26: 
                     27: (setq user-top-level 'lisztinit)
                     28: 
                     29: ;--- liszt - v-x : list containing file name to compile and optionaly
                     30: ;               and output file name for the assembler source.
                     31: ;
                     32: (def liszt
                     33:   (nlambda (v-x)
                     34:           (prog (piport v-root v-ifile v-sfile v-ofile 
                     35:                         vp-ifile vp-sfile vps-crap
                     36:                         vps-include vns-include
                     37:                         asm-exit-status ntem temgc temcp
                     38:                         rootreal g-arrayspecs out-path
                     39:                         g-decls g-stdref pre-eval include-files
                     40:                         g-fname g-trueop g-falseop g-didvectorcode
                     41:                         tem temr starttime startptime startgccount
                     42:                         fl-asm fl-warn fl-verb fl-inter fl-xref fl-uci
                     43:                         fl-run fl-case fl-anno g-optionalp
                     44:                         liszt-process-forms in-line-lambda-number
                     45:                         g-skipcode g-dropnpcnt g-complrname)
                     46: 
                     47:                 ;in case "S" switch given, set asm-exit-status
                     48:                 ;  to 0 (so garbage won't be returned).
                     49:                 (setq asm-exit-status 0)
                     50: 
                     51:                 ; turn on monitoring if it exists
                     52:                 #+monitoring
                     53:                 (errset (progn (monitor t)     ; turn it on
                     54:                                (print 'monitor-on)
                     55:                                (terpr))
                     56:                         nil)
                     57:                 (setq starttime (sys:time)   ; real time in seconds
                     58:                       startptime (ptime)
                     59:                       startgccount $gccount$)
                     60:                 (setq in-line-lambda-number (sys:time))
                     61:                 (cond ((null (boundp 'internal-macros))
                     62:                        (setq internal-macros nil)))
                     63:                 (cond ((null (boundp 'macros))
                     64:                        (setq macros nil)))
                     65:                 (setq er-fatal 0)
                     66:                 (setq vps-include nil  
                     67:                       vns-include nil)  ;stack of ports and names
                     68:                 (setq twa-list nil)
                     69:                 (setq liszt-eof-forms nil)
                     70: 
                     71:                 ; look for lisztrc file and return if error occured
                     72:                 ; in reading it
                     73:                 (cond ((eq (do-lisztrc-check) 'error)
                     74:                        (return 1)))
                     75:                 
                     76:                 ; set up once only g variables
                     77:                 (setq g-comments nil
                     78:                       g-current nil            ; current function name
                     79:                       g-funcs nil
                     80:                       g-lits nil
                     81:                       g-trueloc nil
                     82:                       g-tran nil
                     83:                       g-allf nil               ; used in xrefs
                     84:                       g-reguse #+for-vax (copy '((r4 0 . nil) (r3 0 . nil)
                     85:                                                  (r2 0 . nil); (r7 0 . nil)
                     86:                                                  (r1 0 . nil)))
                     87:                                #+for-68k (copy '((a0 0 . nil) (a1 0 . nil)
                     88:                                                  (d1 0 . nil) (d2 0 . nil)
                     89:                                                  (d4 0 . nil) (d5 0 . nil)))
                     90:                       g-trancnt 0
                     91:                       g-ignorereg nil
                     92:                       g-trueop  #+for-vax 'jneq        ; used in e-gotot
                     93:                                 #+for-68k 'jne
                     94:                       g-falseop #+for-vax 'jeql        ; used in e-gotonil
                     95:                                 #+for-68k 'jeq
                     96:                       g-compfcn nil
                     97:                       g-litcnt 0)
                     98:                 (setq g-spec (gensym 'S))      ; flag for special atom
                     99:                 (setq g-fname "")              ; no function yet
                    100:                 (setq special nil)             ; t if all vrbs are special
                    101:                 (setq g-functype (gensym)
                    102:                       g-vartype  (gensym)
                    103:                       g-bindtype (gensym)
                    104:                       g-calltype (gensym)
                    105:                       g-bindloc  (gensym)
                    106:                       g-localf   (gensym)
                    107:                       g-arrayspecs (gensym)
                    108:                       g-tranloc  (gensym)
                    109:                       g-stdref   (gensym)
                    110:                       g-optionalp (gensym))
                    111: 
                    112:                 ; declare these special
                    113: 
                    114:                 (sstatus feature complr)
                    115:                 (d-makespec 't)                ; always special
                    116: 
                    117:                 ; process input form
                    118:                 (setq fl-asm t         ; assembler file assembled
                    119:                       fl-warn t        ; print warnings
                    120:                       fl-verb t        ; be verbose
                    121:                       fl-macl nil      ; compile maclisp file
                    122:                       fl-anno nil      ; annotate 
                    123:                       fl-inter nil     ; do interlisp compatablity
                    124:                       fl-tty nil       ; put .s on tty
                    125:                       fl-comments nil    ; put in comments
                    126:                       fl-profile nil   ; profiling
                    127:                       fl-tran    t     ; use transfer tables
                    128:                       fl-vms   nil     ; vms hacks
                    129:                       fl-case  nil     ; trans uc to lc
                    130:                       fl-xref  nil     ; xrefs
                    131:                       fl-run   nil     ; autorun capability
                    132:                       fl-uci   nil     ; uci lisp compatibility
                    133:                       )
                    134: 
                    135:                 ; look in the environment for a LISZT variable
                    136:                 ; if it exists, make it the first argument 
                    137:                 (if (not (eq '|| (setq tem (getenv 'LISZT))))
                    138:                     then (setq v-x (cons (concat "-" tem) v-x)))
                    139: 
                    140:                 (do ((i v-x (cdr i)))  ; for each argument
                    141:                     ((null i))
                    142:                     (setq tem (aexplodec (car i)))
                    143: 
                    144:                     (cond ((eq '- (car tem))   ; if switch
                    145:                            (do ((j (cdr tem) (cdr j)))
                    146:                                ((null j))
                    147:                                (cond ((eq 'S (car j)) (setq fl-asm nil))
                    148:                                      ((eq 'C (car j)) (setq fl-comments t))
                    149:                                      ((eq 'm (car j)) (setq fl-macl t))
                    150:                                      ((eq 'o (car j)) (setq v-ofile (cadr i)
                    151:                                                             i (cdr i)))
                    152:                                      ((eq 'e (car j)) (setq pre-eval (cadr i)
                    153:                                                             i (cdr i)))
                    154:                                      ((eq 'i (car j)) (push (cadr i)
                    155:                                                             include-files)
                    156:                                                       (pop i))
                    157:                                      ((eq 'w (car j)) (setq fl-warn nil))
                    158:                                      ((eq 'q (car j)) (setq fl-verb nil))
                    159:                                      ((eq 'Q (car j)) (setq fl-verb t))
                    160:                                      ((eq 'T (car j)) (setq fl-tty t))
                    161:                                      ((eq 'a (car j)) (setq fl-anno t))
                    162:                                      ((eq 'i (car j)) (setq fl-inter t))
                    163:                                      ((eq 'p (car j)) (setq fl-profile t))
                    164:                                      ((eq 'F (car j)) (setq fl-tran nil))
                    165:                                      ((eq 'v (car j)) (setq fl-vms t))
                    166:                                      ((eq 'r (car j)) (setq fl-run t))
                    167:                                      ((eq 'x (car j)) (setq fl-xref t))
                    168:                                      ((eq 'c (car j)) (setq fl-case t))
                    169:                                      ((eq 'u (car j)) (setq fl-uci  t))
                    170:                                      ((eq '- (car j)))  ; ignore extra -'s
                    171:                                      (t (comp-gerr "Unknown switch: "
                    172:                                                    (car j))))))
                    173:                           ((null v-root)
                    174:                            (setq temr (reverse tem))
                    175:                            (cond ((and (eq 'l (car temr))
                    176:                                        (eq '\. (cadr temr)))
                    177:                                   (setq rootreal nil)
                    178:                                   (setq v-root
                    179:                                         (apply 'concat
                    180:                                                (reverse (cddr temr)))))
                    181:                                  (t (setq v-root (car i)
                    182:                                           rootreal t))))
                    183: 
                    184:                           (t (comp-gerr "Extra input file name: " (car i)))))
                    185: 
                    186:                 ;no transfer tables in vms
                    187:                 (cond (fl-vms (setq fl-tran nil)))
                    188: 
                    189:                 ; if verbose mode, print out the gc messages and
                    190:                 ; fasl messages, else turn them off.
                    191:                 (cond (fl-verb (setq $gcprint t
                    192:                                      $ldprint t))
                    193:                       (t (setq $gcprint nil
                    194:                                 $ldprint nil)))
                    195: 
                    196:                 ; eval arg after -e
                    197:                 (if pre-eval
                    198:                    then (if (null (errset
                    199:                                      (eval (readlist (exploden pre-eval)))))
                    200:                            then (comp-gerr "-e form caused error: "
                    201:                                            pre-eval)))
                    202: 
                    203:                 ; load file after -i arg
                    204:                 (if include-files
                    205:                    then (catch
                    206:                            (mapc
                    207:                               '(lambda (file)
                    208:                                   (if (null (errset (load file)))
                    209:                                      then (comp-err
                    210:                                              "error when loading -i file: "
                    211:                                              file)))
                    212:                               include-files)
                    213:                            Comp-error))
                    214: 
                    215:                 ; -c says set reader to xlate uc to lc
                    216:                 (cond (fl-case (sstatus uctolc t)))
                    217: 
                    218:                 ; If we are a cross compiler, then don't try to
                    219:                 ; assemble our output...
                    220:                 ;
                    221:                 #+for-vax
                    222:                 (if (status feature 68k)
                    223:                     then (setq fl-asm nil))
                    224:                 #+for-68k
                    225:                 (if (status feature vax)
                    226:                     then (setq fl-asm nil))
                    227: 
                    228:                 ; now see what the arguments have left us
                    229:                 (cond ((null v-root)
                    230:                        (comp-gerr "No file for input"))
                    231:                       ((or (portp 
                    232:                             (setq vp-ifile 
                    233:                                   (car (errset (infile 
                    234:                                                   (setq v-ifile 
                    235:                                                         (concat v-root '".l"))) 
                    236:                                                nil))))
                    237:                            (and rootreal
                    238:                                 (portp
                    239:                                  (setq vp-ifile
                    240:                                        (car (errset 
                    241:                                                 (infile (setq v-ifile v-root))
                    242:                                                 nil)))))))
                    243:                       (t (comp-gerr "Couldn't open the source file :"
                    244:                                     (or v-ifile))))
                    245: 
                    246: 
                    247:                 ; determine the name of the .s file
                    248:                 ; strategy: if fl-asm is t (assemble) use (v-root).s
                    249:                 ;           else use /tmp/(PID).s
                    250:                 ;  
                    251:                 ; direct asm to tty temporarily
                    252:                 (setq v-sfile "tty")
                    253:                 (setq vp-sfile nil)
                    254:                 (if (null fl-tty) then
                    255:                     (cond (fl-asm (setq v-sfile
                    256:                                         (concat '"/tmp/Lzt"
                    257:                                                          (boole 1 65535
                    258:                                                                 (sys:getpid))
                    259:                                                          '".s")))
                    260:                           (t (setq v-sfile
                    261:                                    (if v-ofile
                    262:                                        then v-ofile
                    263:                                        else (concat v-root '".s")))))
                    264:                     
                    265:                     (cond ((not (portp (setq vp-sfile
                    266:                                              (car (errset (outfile v-sfile)
                    267:                                                           nil)))))
                    268:                            (comp-gerr "Couldn't open the .s file: "
                    269:                                       (or v-sfile)))))
                    270:                                     
                    271:                 
                    272:                 ; determine the name of the .o file (object file)
                    273:                 ; strategy: if we aren't supposed to assemble the .s file
                    274:                 ;            don't worry about a name
                    275:                 ;           else if a name is given, use it
                    276:                 ;           else if use (v-root).o
                    277:                 ;  if profiling, use .o
                    278:                 (cond ((or v-ofile (null fl-asm)))             ;ignore
                    279:                       ((null fl-profile) (setq v-ofile (concat v-root ".o")))
                    280:                       (t (setq v-ofile (concat v-root ".o"))))
                    281: 
                    282:                 ; determine the name of the .x file (xref file)
                    283:                 ; strategy: if fl-xref and v-ofile is true, then use
                    284:                 ; v-ofile(minus .o).x, else use (v-root).x
                    285:                 ;
                    286:                 (if fl-xref
                    287:                    then ; check for ending with .X for any X
                    288:                         (setq v-xfile
                    289:                               (if v-ofile
                    290:                                  then (let ((ex (nreverse
                    291:                                                    (exploden v-ofile))))
                    292:                                          (if (eq #/. (cadr ex))
                    293:                                             then (implode
                    294:                                                     (nreverse
                    295:                                                        `(#/x #/.
                    296:                                                           ,@(cddr ex))))
                    297:                                             else (concat v-ofile ".x")))
                    298:                                  else (concat v-root ".x")))
                    299:                         (if (portp
                    300:                                (setq vp-xfile
                    301:                                      (car (errset (outfile v-xfile)))))
                    302:                            thenret
                    303:                            else (comp-gerr "Can't open the .x file: "
                    304:                                            v-xfile)))
                    305:                 (cond ((checkfatal) (return 1)))
                    306: 
                    307:                 ; g-complrname is a symbol which should be unique to
                    308:                 ; each fasl'ed file. It will contain the string which
                    309:                 ; describes the name of this file and the compiler
                    310:                 ; version.
                    311:                 (if fl-anno
                    312:                    then (setq g-complrname (concat "fcn-in-" v-ifile))
                    313:                         (Push g-funcs
                    314:                               `(eval (setq ,g-complrname
                    315:                                            ,(get_pname
                    316:                                                (concat v-ifile
                    317:                                                        " compiled by "
                    318:                                                        compiler-name
                    319:                                                        " on "
                    320:                                                        (status ctime)))))))
                    321:                                                        
                    322:                 
                    323:                 (setq readtable (makereadtable nil))   ; use new readtable
                    324: 
                    325: 
                    326:                 ; if the macsyma flag is set, change the syntax to the
                    327:                 ; maclisp standard syntax.  We must be careful that we
                    328:                 ; dont clobber any syntax changes made by files preloaded
                    329:                 ; into the compiler.
                    330: 
                    331:                 (cond (fl-macl (setsyntax '\/ 'vescape)        ;  143 = vesc
                    332: 
                    333:                                (cond ((eq 'vescape (getsyntax '\\))
                    334:                                       (setsyntax '\\ 'vcharacter)))
                    335: 
                    336:                                (cond ((eq 'vleft-bracket (getsyntax '\[))
                    337:                                       (setsyntax '\[ 'vcharacter)
                    338:                                       (setsyntax '\] 'vcharacter)))
                    339:                                (setq ibase  8.)
                    340:                                (sstatus uctolc t)
                    341:                                
                    342:                                (d-makespec 'ibase)     ; to be special
                    343:                                (d-makespec 'base)
                    344:                                (d-makespec 'tty)
                    345: 
                    346:                                (errset (cond ((null (getd 'macsyma-env))
                    347:                                               (load 'machacks)))
                    348:                                        nil))
                    349:                       (fl-uci (load "ucifnc")
                    350:                               (cvttoucilisp)))
                    351: 
                    352:                 (cond (fl-inter (putprop '* 'cc-ignore 'fl-exprcc) ;comment
                    353:                                 (remprop '* 'fl-expr)
                    354:                                 ))
                    355: 
                    356:                 (cond ((checkfatal) (return 1)))  ; leave if fatal errors      
                    357: 
                    358:                 (if fl-verb 
                    359:                     then (comp-msg "Compilation begins with " compiler-name )
                    360:                          (comp-msg "source: "  v-ifile ", result: "
                    361:                                    (cond (fl-asm v-ofile) (t v-sfile))))
                    362: 
                    363:                 (setq piport vp-ifile)         ; set to standard input
                    364:                 (setq liszt-root-name v-root
                    365:                       liszt-file-name v-ifile)
                    366: 
                    367: 
                    368:                 (if fl-run then (d-printautorun))
                    369:        
                    370:                 (if fl-profile then (e-write1 '".globl mcount"))
                    371:        loop
                    372: 
                    373:                ; main loop of the compiler.  It reads a form and
                    374:                ; compiles it. It continues to compile forms from
                    375:                ; liszt-process-forms was long at that list is
                    376:                ; non-empty.  This allows one form to spawn off other
                    377:                ; forms to be compiled (an alternative to (progn 'compile))
                    378:                ;
                    379:                (cond ((atom (errset            ; list for debugging,
                    380:                                                ; errset for production.
                    381:                              (do ((i (read piport '<<end-of-file>>) 
                    382:                                      (read piport '<<end-of-file>>))) 
                    383:                                  ((eq i '<<end-of-file>>) nil)
                    384:                                  (setq liszt-process-forms
                    385:                                        (cons i liszt-process-forms))
                    386:                                  (do ((this (car liszt-process-forms)
                    387:                                             (car liszt-process-forms)))
                    388:                                      ((null liszt-process-forms))
                    389:                                      (unpush liszt-process-forms)
                    390:                                      (catch (liszt-form this) Comp-error)))))
                    391:                       (catch (comp-err "Lisp error during compilation")
                    392:                              Comp-error)
                    393:                       (setq piport nil)
                    394:                       (setq er-fatal (1+ er-fatal))
                    395:                       (return 1)))
                    396: 
                    397:                 (close piport)
                    398: 
                    399:                 ; if doing special character stuff (maclisp) reassert
                    400:                 ; the state
                    401: 
                    402:                 (cond (vps-include
                    403:                        (comp-note  " done include")
                    404:                        (setq piport (car vps-include)
                    405:                              vps-include (cdr vps-include)
                    406:                              v-ifile (car vns-include)
                    407:                              vns-include (cdr vns-include))
                    408:                        (go loop)))
                    409: 
                    410:                 (cond (liszt-eof-forms
                    411:                        (do ((ll liszt-eof-forms (cdr ll)))
                    412:                            ((null ll))
                    413:                            (cond ((atom (errset (liszt-form (car ll))))
                    414:                                   (catch
                    415:                                    (comp-note "Lisp error during eof forms")
                    416:                                    Comp-error)
                    417:                                   (setq piport nil)
                    418:                                   (return 1))))))
                    419: 
                    420:                 ; reset input base
                    421:                 (setq ibase 10.)
                    422:                 (setq readtable (makereadtable t))
                    423:                 (sstatus uctolc nil)   ; turn off case conversion
                    424:                                        ; so bindtab will not have |'s
                    425:                                        ; to quote lower case
                    426:                 (d-bindtab)
                    427: 
                    428:                 (d-printdocstuff)              ; describe this compiler
                    429: 
                    430:                 (cond ((portp vp-sfile)
                    431:                        (close vp-sfile)))  ; close assembler language file
                    432: 
                    433:                 ; check for fatal errors and don't leave if so
                    434:                 (cond ((checkfatal) 
                    435:                        (if fl-asm                      ; unlink .s file
                    436:                            then (sys:unlink v-sfile))  ; if it is a tmp
                    437:                        (return 1)))            ; and ret with error status
                    438: 
                    439:                 (comp-note "Compilation complete")
                    440: 
                    441:                 (setq tem (Divide (difference (sys:time) starttime) 60))
                    442:                 (setq ntem (ptime))
                    443: 
                    444:                 (setq temcp (Divide (difference (car ntem) (car startptime))
                    445:                                    3600))
                    446: 
                    447:                 (setq temgc (Divide (difference (cadr ntem) (cadr startptime))
                    448:                                    3600))
                    449: 
                    450:                 (comp-note " Time: Real: " (car tem) ":" (cadr tem)
                    451:                        ", CPU: " (car temcp) ":" (quotient (cadr temcp) 60.0) 
                    452:                         ", GC: " (car temgc) ":" (quotient (cadr temgc) 60.0) 
                    453:                            " for "
                    454:                            (difference $gccount$ startgccount)
                    455:                            " gcs")
                    456: 
                    457:                 (cond (fl-xref
                    458:                        (comp-note "Cross reference being generated")
                    459:                        (print (list 'File v-ifile) vp-xfile)
                    460:                        (terpr vp-xfile)
                    461:                        (do ((ii g-allf (cdr ii)))
                    462:                            ((null ii))
                    463:                            (print (car ii) vp-xfile)
                    464:                            (terpr vp-xfile))
                    465:                        (close vp-xfile)))
                    466: 
                    467: 
                    468:                 ; the assember we use must generate the new a.out format
                    469:                 ; with a string table.  We will assume that the assembler
                    470:                 ; is in /usr/lib/lisp/as so that other sites can run
                    471:                 ; the new assembler without installing the new assembler
                    472:                 ; as /bin/as
                    473:                 (cond (fl-asm                  ; assemble file 
                    474:                         (comp-note "Assembly begins")
                    475:                         (cond ((not
                    476:                                   (zerop
                    477:                                      (setq asm-exit-status
                    478:                                            (*process
                    479:                                               (concat
                    480:                                                  lisp-library-directory
                    481:                                                  "/as "
                    482:                                        #+for-vax "-V"   ; use virt mem
                    483:                                                  " -o "
                    484:                                                  v-ofile
                    485:                                                  " "
                    486:                                                  v-sfile)))))
                    487:                                (comp-gerr "Assembler detected error, code: "
                    488:                                           asm-exit-status)
                    489:                                (comp-note "Assembler temp file " v-sfile
                    490:                                           " is not unlinked"))
                    491:                               (t (comp-note "Assembly completed successfully")
                    492:                                  (errset (sys:unlink v-sfile)); unlink tmp
                    493:                                                               ; file
                    494:                                  (if fl-run
                    495:                                      then (errset
                    496:                                            (sys:chmod v-ofile #O775)))))))
                    497: 
                    498:                 #+(and sun (not unisoft))
                    499:                 (if (and v-ofile fl-run)
                    500:                     then (if (null
                    501:                               (errset (let ((port (fileopen v-ofile "r+")))
                    502:                                            (fseek port 20 0)
                    503:                                            (tyo 0 port)
                    504:                                            (tyo 0 port)
                    505:                                            (tyo 128 port)
                    506:                                            (tyo 0 port)
                    507:                                            (close port))))
                    508:                              then (comp-err
                    509:                                    "Error while fixing offset in object file: "
                    510:                                    v-ofile)))
                    511: 
                    512:                 (setq readtable original-readtable)
                    513:                 #+monitoring
                    514:                 (errset (progn (monitor)       ; turn off monitoring
                    515:                                (print 'monitor-off))
                    516:                         nil)
                    517:                 (sstatus nofeature complr)
                    518:                 (return asm-exit-status))))
                    519: 
                    520: (def checkfatal
                    521:   (lambda nil
                    522:          (cond ((greaterp er-fatal 0)
                    523:                 (catch (comp-err "Compilation aborted due to previous errors")
                    524:                        Comp-error)
                    525:                 t))))
                    526: 
                    527: ;--- do-lisztrc-check
                    528: ; look for a liszt init file named
                    529: ;  .lisztrc  or  lisztrc or $HOME/.lisztrc or $HOME/lisztrc
                    530: ; followed by .o or .l or nothing
                    531: ; return the symbol 'error' if an error occured while reading.
                    532: ;
                    533: (defun do-lisztrc-check nil
                    534:    (do ((dirs `("." ,(getenv 'HOME)) (cdr dirs))
                    535:        (val)
                    536:        ($gcprint nil)
                    537:        ($ldprint nil))
                    538:        ((null dirs))
                    539:        (if (setq val
                    540:                 (do ((name '(".lisztrc" "lisztrc") (cdr name))
                    541:                      (val))
                    542:                     ((null name))
                    543:                     (if (setq val
                    544:                               (do ((ext '(".o" ".l" "") (cdr ext))
                    545:                                    (file))
                    546:                                   ((null ext))
                    547:                                   (if (probef
                    548:                                          (setq file (concat (car dirs)
                    549:                                                             "/"
                    550:                                                             (car name)
                    551:                                                             (car ext))))
                    552:                                      then (if (atom (errset (load file)))
                    553:                                              then (comp-msg
                    554:                                        "Error loading liszt init file "
                    555:                                                      file N
                    556:                                                      "Compilation aborted" N)
                    557:                                                   (return 'error)
                    558:                                              else (return t)))))
                    559:                        then (return val))))
                    560:          then (return val))))
                    561: 
                    562:       
                    563: ;--- liszt-form - i : form to compile
                    564: ;      This compiles one form.
                    565: ;
                    566: (def liszt-form
                    567:   (lambda (i)
                    568:      (prog (tmp v-x)
                    569:          ; macro expand
                    570:        loop
                    571:          (setq i (d-macroexpand i))
                    572:          ; now look at what is left
                    573:          (cond ((not (dtpr i)) (Push g-funcs `(eval ,i)))
                    574:                ((eq (car i) 'def)
                    575:                 (cond (fl-verb (print (cadr i)) (terpr)(drain)))
                    576:                 (d-dodef i))
                    577:                ((memq (car i) '(liszt-declare declare))
                    578:                 (funcall 'liszt-declare  (cdr i)))
                    579:                ((eq (car i) 'eval-when) (doevalwhen i))
                    580:                ((and (eq (car i) 'progn) (equal (cadr i) '(quote compile)))
                    581:                 ((lambda (internal-macros)     ; compile macros too
                    582:                          (mapc 'liszt-form (cddr i)))
                    583:                       t))
                    584:                ((or (and (eq (car i) 'includef) (setq tmp (eval (cadr i))))
                    585:                     (and (eq (car i) 'include ) (setq tmp (cadr i))))
                    586:                 (cond ((or (portp (setq v-x 
                    587:                                         (car (errset (infile tmp) nil))))
                    588:                            (portp (setq v-x 
                    589:                                         (car
                    590:                                            (errset
                    591:                                               (infile
                    592:                                                  (concat
                    593:                                                     lisp-library-directory
                    594:                                                     "/"
                    595:                                                     tmp))
                    596:                                               nil))))
                    597:                            (portp (setq v-x 
                    598:                                         (car (errset (infile (concat tmp
                    599:                                                                      '".l")) 
                    600:                                                      nil)))))
                    601:                        (setq vps-include (cons piport vps-include))
                    602:                        (setq piport v-x)
                    603:                        (comp-note " INCLUDEing file: "  tmp)
                    604:                        (setq vns-include (cons v-ifile vns-include)
                    605:                              v-ifile tmp))
                    606:                       (t (comp-gerr "Cannot open include file: " tmp))))
                    607:                ((eq (car i) 'comment) nil)   ; just ignore comments
                    608:                (t ; we have to macro expand
                    609:                   ; certain forms we would normally
                    610:                   ; just dump in the eval list.  This is due to hacks in
                    611:                   ; the mit lisp compiler which are relied upon by certain
                    612:                   ; code from mit.
                    613:                   (setq i (d-fullmacroexpand i))
                    614:                   
                    615:                   (Push g-funcs `(eval ,i)))))))
                    616: 
                    617: ;--- d-dodef :: handle the def form
                    618: ;      - form : a def form: (def name (type args . body))
                    619: ;
                    620: (defun d-dodef (form)
                    621:   (prog (g-fname g-ftype g-args body lambdaform symlab g-arginfo
                    622:                 g-compfcn g-decls)
                    623: 
                    624:      (setq g-arginfo 'empty)
                    625:        
                    626:  loop
                    627:        ; extract the components of the def form
                    628:        (setq g-fname (cadr form))
                    629:        (if (dtpr (caddr form))
                    630:            then (setq g-ftype (caaddr form)
                    631:                       g-args (cadaddr form)
                    632:                       body (cddaddr form)
                    633:                       lambdaform (caddr form)
                    634:                       symlab (gensym 'F))
                    635:            else (comp-gerr "bad def form " form))
                    636:        
                    637:        ; check for a def which uses the mit hackish &xxx forms.
                    638:        ; if seen, convert to a standard form and reexamine
                    639:        ; the vax handles these forms in a special way.
                    640:        #+for-68k
                    641:        (if (or (memq '&rest g-args) 
                    642:                (memq '&optional g-args)
                    643:                (memq '&aux g-args))
                    644:            then (setq form 
                    645:                       `(def ,(cadr form) ,(lambdacvt (cdr lambdaform))))
                    646:                 (go loop))
                    647:        
                    648:        ; check for legal function name.  
                    649:        ; then look at the type of the function and update the data base.
                    650:        (if (null (atom g-fname))
                    651:            then (comp-err "bad function name")
                    652:            else (setq g-flocal (get g-fname g-localf))    ; check local decl.
                    653:                 ; macros are special, they are always evaluated
                    654:                 ; and sometimes compiled.
                    655:                 (if (and (not g-flocal) (eq g-ftype 'macro))
                    656:                     then (eval form)
                    657:                          (if (and (null macros)
                    658:                                   (null internal-macros))
                    659:                              then (comp-note g-fname
                    660:                                              " macro will not be compiled")
                    661:                                   (return nil))
                    662:                          (Push g-funcs `(macro ,symlab ,g-fname))
                    663:                          (if fl-anno then (setq g-arginfo nil)) ; no arg info
                    664:                  elseif g-flocal
                    665:                     then (if (null (or (eq g-ftype 'lambda)
                    666:                                        (eq g-ftype 'nlambda)))
                    667:                              then (comp-err
                    668:                                       "bad type for local fcn: " g-ftype))
                    669:                          (if (or (memq '&rest g-args)
                    670:                                  (memq '&optional g-args)
                    671:                                  (memq '&aux g-args))
                    672:                              then (comp-err
                    673:                                       "local functions can't use &keyword's "
                    674:                                       g-fname))
                    675:                  elseif (or (eq g-ftype 'lambda)
                    676:                             (eq g-ftype 'lexpr))
                    677:                     then (push `(lambda ,symlab ,g-fname) g-funcs)
                    678:                          (putprop g-fname 'lambda g-functype)
                    679:                  elseif (eq g-ftype 'nlambda)
                    680:                     then (Push g-funcs `(nlambda ,symlab ,g-fname))
                    681:                          (putprop g-fname 'nlambda g-functype)
                    682:                     else (comp-err " bad function type " g-ftype)))
                    683:        (setq g-skipcode nil)   ;make sure we aren't skipping code
                    684:        (forcecomment `(fcn ,g-ftype ,g-fname))
                    685:        (if g-flocal 
                    686:           then (comp-note g-fname " is a local function")
                    687:                (e-writel (car g-flocal))
                    688:           else (if (null fl-vms) then (e-write2 '".globl" symlab))
                    689:                (e-writel symlab))
                    690:        (setq g-locs nil g-loccnt 0 g-labs nil g-loc 'reg g-cc nil
                    691:              g-ret t g-topsym (d-genlab))
                    692:        (if fl-xref then (setq g-refseen (gensym) g-reflst nil))
                    693:        (d-clearreg)
                    694:        #+for-68k (init-regmaskvec)
                    695:        ; set up global variables which maintain knowledge about
                    696:        ; the stack.  these variables are set up as if the correct
                    697:        ; number of args were passed.
                    698:        (setq g-compfcn t)      ; now compiling a function
                    699:        (push nil g-labs)               ; no labels in a lambda
                    700:        (setq g-currentargs (length g-args))
                    701:        (d-prelude)                     ; do beginning stuff
                    702:        
                    703:        #+for-vax
                    704:        (d-outerlambdacomp g-fname g-args (cddr lambdaform))
                    705:        #+for-68k
                    706:        (progn
                    707:            (push (cons 'lambda 0) g-locs)
                    708:            (mapc '(lambda (x)
                    709:                       (push nil g-locs)
                    710:                       (incr g-loccnt))
                    711:                  g-args)
                    712:            (d-lambbody lambdaform))
                    713: 
                    714:        (d-fini)
                    715:        (setq g-compfcn nil)            ; done compiling a fcn
                    716:        (if fl-xref then 
                    717:            (Push g-allf
                    718:                  (cons g-fname
                    719:                        (cons (cond (g-flocal (cons g-ftype 'local))
                    720:                                    (t g-ftype))
                    721:                              g-reflst))))
                    722:        (if (and fl-anno (not (eq 'empty g-arginfo)))
                    723:           then (Push g-funcs `(eval (putprop
                    724:                                        ',g-fname
                    725:                                        (list ',g-arginfo
                    726:                                              ,g-complrname)
                    727:                                        'fcn-info))))
                    728:        ; by storing argument count information during compilation
                    729:        ; we can arg number check calls to this function which occur
                    730:        ; further on. 
                    731:        (if (not (eq 'empty g-arginfo))
                    732:           then (putprop g-fname (list g-arginfo) 'fcn-info))))
                    733: 
                    734: ;--- d-lambdalistcheck :: scan lambda var list for & forms
                    735: ; return
                    736: ;  (required optional rest op-p body)
                    737: ; required - list of required args
                    738: ; optional - list of (variable default [optional-p])
                    739: ; rest - either nil or the name of a variable for optionals
                    740: ; op-p - list of variables set to t or nil depending if optional exists
                    741: ; body - body to compile (has &aux's wrapped around it in lambdas)
                    742: ;
                    743: #+for-vax
                    744: (defun d-lambdalistcheck (list body)
                    745:    (do ((xx list (cdr xx))
                    746:        (state 'req)
                    747:        (statechange)
                    748:        (arg)
                    749:        (req)(optional)(rest)(op-p)(aux))
                    750:        ((null xx)
                    751:        (list (nreverse req)
                    752:              (nreverse optional)
                    753:              rest
                    754:              (nreverse op-p)
                    755:              (d-lambda-aux-body-convert body (nreverse aux))))
                    756:        (setq arg (car xx))
                    757:        (if (memq arg '(&optional &rest &aux))
                    758:          then (setq statechange arg)
                    759:          else (setq statechange nil))
                    760:        (caseq state
                    761:              (req
                    762:                 (if statechange
                    763:                    then (setq state statechange)
                    764:                  elseif (and (symbolp arg) arg)
                    765:                    then (push arg req)
                    766:                    else (comp-err " illegal lambda variable " arg)))
                    767:              (&optional
                    768:                 (if statechange
                    769:                    then (if (memq statechange '(&rest &aux))
                    770:                            then (setq state statechange)
                    771:                            else (comp-err "illegal form in lambda list "
                    772:                                           xx))
                    773:                  elseif (symbolp arg)
                    774:                    then ; optional which defaults to nil
                    775:                         (push (list arg nil) optional)
                    776:                  elseif (dtpr arg)
                    777:                    then (if (and (symbolp (car arg))
                    778:                                  (symbolp (caddr arg)))
                    779:                            then ; optional with default
                    780:                                 (push arg optional)
                    781:                                 ; save op-p
                    782:                                 (if (cddr arg)
                    783:                                    then (push (caddr arg) op-p)))
                    784:                    else (comp-err "illegal &optional form "
                    785:                                   arg)))
                    786:              (&rest
                    787:                 (if statechange
                    788:                    then (if (eq statechange '&aux)
                    789:                            then (setq state statechange)
                    790:                            else (comp-err "illegal lambda variable form "
                    791:                                           xx))
                    792:                  elseif rest
                    793:                    then (comp-err
                    794:                            "more than one rest variable in lambda list"
                    795:                            arg)
                    796:                    else (setq rest arg)))
                    797:              (&aux
                    798:                 (if statechange
                    799:                    then (comp-err "illegal lambda form " xx)
                    800:                  elseif (and (symbolp arg) arg)
                    801:                    then (push (list arg nil) aux)
                    802:                  elseif (and (dtpr arg) (and (symbolp (car arg))
                    803:                                              (car arg)))
                    804:                    then (push arg aux)))
                    805:              (t (comp-err "bizzarro internal compiler error ")))))
                    806: 
                    807: ;--- d-lambda-aux-body-convert :: convert aux's to lambdas
                    808: ; give a function body and a list of aux variables
                    809: ; and their inits, place a lambda initializing body around body
                    810: ; for each lambda (basically doing a let*).
                    811: ;
                    812: #+for-vax
                    813: (defun d-lambda-aux-body-convert (body auxlist)
                    814:    (if (null auxlist)
                    815:       then body
                    816:       else `(((lambda (,(caar auxlist))
                    817:                ,@(d-lambda-aux-body-convert body (cdr auxlist)))
                    818:             ,(cadar auxlist)))))
                    819: 
                    820: ;--- d-outerlambdacomp :: compile a functions outer lambda body
                    821: ; This function compiles the lambda expression which defines
                    822: ; the function.   This lambda expression differs from the kind that
                    823: ; appears within a function because
                    824: ;  1. we aren't sure that the correct number of arguments have been stacked
                    825: ;  2. the keywords &optional, &rest, and &aux may appear
                    826: ;
                    827: ; funname - name of function
                    828: ; lambdalist - the local argument list, (with possible keywords)
                    829: ; body - what follows the lambdalist
                    830: ;
                    831: ; 
                    832: ;
                    833: #+for-vax
                    834: (defun d-outerlambdacomp (funname lambdalist body)
                    835:    (let (((required optional rest op-p newbody)
                    836:          (d-lambdalistcheck lambdalist body))
                    837:         (g-decls g-decls)
                    838:         (reqnum 0) maxwithopt labs (maxnum -1) args)
                    839:        (d-scanfordecls body)
                    840:        ; if this is a declared lexpr, we aren't called
                    841:        ;
                    842:        (if (and (null optional) (null rest))
                    843:           then ; simple, the number of args is required
                    844:                ; if lexpr or local function, then don't bother
                    845:                (if (and (not g-flocal)
                    846:                         (not (eq g-ftype 'lexpr)))
                    847:                    then (d-checkforfixedargs
                    848:                             funname
                    849:                             (setq reqnum (setq maxnum (length required)))))
                    850:           else ; complex, unknown number of args
                    851:                ; cases:
                    852:                ;  optional, no rest
                    853:                ;  optional, with rest
                    854:                ; no optional, rest + required
                    855:                ; no optional, rest + no required
                    856:                (setq reqnum (length required)
                    857:                      maxwithopt (+ reqnum (length optional))
                    858:                      maxnum (if rest then -1 else maxwithopt))
                    859:                ; determine how many args were given
                    860:                (e-sub3 '#.lbot-reg '#.np-reg '#.lbot-reg)
                    861:                (e-write4 'ashl '$-2 '#.lbot-reg '#.lbot-reg)
                    862:                ;
                    863:                (if (null optional)
                    864:                    then ; just a rest
                    865:                         (let ((oklab (d-genlab))
                    866:                               (lllab (d-genlab))
                    867:                               (nopushlab (d-genlab)))
                    868:                             (if (> reqnum 0)
                    869:                                 then (e-cmp '#.lbot-reg `($ ,reqnum))
                    870:                                      (e-write2 'jgeq oklab)
                    871:                                      ; not enough arguments given
                    872:                                      (d-wnaerr funname reqnum -1)
                    873:                                      (e-label oklab))
                    874:                             (e-pushnil 1)
                    875:                             (if (> reqnum 0)
                    876:                                 then (e-sub `($ ,reqnum) '#.lbot-reg)
                    877:                                 else (e-tst '#.lbot-reg))
                    878:                             (e-write2 'jleq nopushlab)
                    879:                             (e-label lllab)
                    880:                             (e-quick-call '_qcons)
                    881:                             (d-move 'reg 'stack)
                    882:                             (e-write3 'sobgtr '#.lbot-reg lllab)
                    883:                             (e-label nopushlab))
                    884:                    else ; has optional args
                    885:                         ; need one label for each optional plus 2
                    886:                         (do ((xx optional (cdr xx))
                    887:                              (res (list (d-genlab) (d-genlab))))
                    888:                             ((null xx) (setq labs res))
                    889:                             (push (d-genlab) res))
                    890:                         ; push nils for missing optionals
                    891:                         ; one case for required amount and one for
                    892:                         ; each possible number of optionals
                    893:                         (e-write4 'casel
                    894:                                   '#.lbot-reg `($ ,reqnum)
                    895:                                   `($ ,(- maxwithopt reqnum)))
                    896:                         (e-label (car labs))
                    897:                         (do ((xx (cdr labs) (cdr xx))
                    898:                              (head (car labs)))
                    899:                             ((null xx))
                    900:                             (e-write2 '.word (concat (car xx) "-" head)))
                    901:                         ; get here (when running code) if there are more
                    902:                         ; than the optional number of args or if there are
                    903:                         ; too few args.  If &rest is given, it is permitted
                    904:                         ; to have more than the required number
                    905:                         (let ((dorest (d-genlab))
                    906:                               (again (d-genlab))
                    907:                               (afterpush (d-genlab)))
                    908:                             (if rest
                    909:                                 then ; check if there are greater than
                    910:                                      ; the required number
                    911:                                      ; preserve arg #
                    912:                                      (C-push '#.lbot-reg)
                    913:                                      (e-sub2 `($ ,maxwithopt) '#.lbot-reg)
                    914:                                      (e-write2 'jgtr dorest)
                    915:                                      (C-pop '#.lbot-reg))
                    916:                             ; wrong number of args
                    917:                             (d-wnaerr funname reqnum maxnum)
                    918:                             (if rest
                    919:                                 then ; now cons the rest forms
                    920:                                      (e-label dorest)
                    921:                                      (e-pushnil 1)   ; list ends with nil
                    922:                                      (e-label again)
                    923:                                      (e-quick-call '_qcons)
                    924:                                      (d-move 'reg 'stack)
                    925:                                      ; and loop
                    926:                                      (e-write3 'sobgtr '#.lbot-reg again)
                    927:                                      ; arg #
                    928:                                      (C-pop '#.lbot-reg)
                    929:                                      (e-goto afterpush))
                    930:                             ; push the nils on the optionals
                    931:                             (do ((xx (cdr labs) (cdr xx)))
                    932:                                 ((null xx))
                    933:                                 (e-label (car xx))
                    934:                                 ; if we have exactly as many arguments given
                    935:                                 ; as the number of optionals, then we stack
                    936:                                 ; a nil if there is a &rest after
                    937:                                 ; the optionals
                    938:                                 (if (null (cdr xx))
                    939:                                     then (if rest
                    940:                                              then (e-pushnil 1))
                    941:                                     else (e-pushnil 1)))
                    942:                             (e-label afterpush))))
                    943:        ; for optional-p's stack t's
                    944:        (mapc '(lambda (form) (d-move 'T 'stack)) op-p)
                    945: 
                    946:        ; now the variables must be shallow bound
                    947:        ; creat a list of all arguments
                    948:        (setq args (append required
                    949:                          (mapcar 'car optional)
                    950:                          (if rest then (list rest))
                    951:                          op-p))
                    952: 
                    953:        (push (cons 'lambda 0) g-locs)
                    954:        (mapc '(lambda (x)
                    955:                  (push nil g-locs))
                    956:             args)
                    957:        (setq g-loccnt (length args))
                    958:        (d-bindlamb args)  ; do shallow binding if necessary
                    959:        ;
                    960:        ; if any of the optionals have non null defaults or
                    961:        ; optional-p's, we have to evaluate their defaults
                    962:        ; or set their predicates.
                    963:        ; first, see if it is necessary
                    964:        (if (do ((xx optional (cdr xx)))
                    965:               ((null xx) nil)
                    966:               (if (or (cadar xx)  ; if non null default
                    967:                       (caddar xx)); or predicate
                    968:                   then (return t)))
                    969:           then (makecomment '(do optional defaults and preds))
                    970:                ; create labels again
                    971:                ; need one label for each optional plus 1
                    972:                (do ((xx optional (cdr xx))
                    973:                     (res (list (d-genlab) )))
                    974:                    ((null xx) (setq labs res))
                    975:                    (push (d-genlab) res))
                    976:                ; we need to do something if the argument count
                    977:                ; is between the number of required arguments and
                    978:                ; the maximum number of args with optional minus 1.
                    979:                ; we have one case for the required number and
                    980:                ; one for each optional except the last optional number
                    981:                ;
                    982:                (let ((afterthis (d-genlab)))
                    983:                    (e-write4 'casel
                    984:                              '#.lbot-reg `($ ,reqnum)
                    985:                              `($ ,(- maxwithopt reqnum 1)))
                    986:                    (e-label (car labs))
                    987:                    (do ((xx (cdr labs) (cdr xx))
                    988:                         (head (car labs)))
                    989:                        ((null xx))
                    990:                        (e-write2 '.word (concat (car xx) "-" head)))
                    991:                    (e-goto afterthis)
                    992:                    (do ((ll (cdr labs) (cdr ll))
                    993:                         (op optional (cdr op))
                    994:                         (g-loc nil)
                    995:                         (g-cc nil)
                    996:                         (g-ret nil))
                    997:                        ((null ll))
                    998:                        (e-label (car ll))
                    999:                        (if (caddar op)
                   1000:                            then (d-exp `(setq ,(caddar op) nil)))
                   1001:                        (if (cadar op)
                   1002:                            then (d-exp `(setq ,(caar op) ,(cadar op)))))
                   1003:                    (e-label afterthis)))
                   1004: 
                   1005:        ; now compile the function
                   1006:        (d-clearreg)
                   1007:        (setq g-arginfo
                   1008:             (if (eq g-ftype 'nlambda)
                   1009:                 then nil
                   1010:                 else (cons reqnum (if (>& maxnum 0) then maxnum else nil))))
                   1011:        (makecomment '(begin-fcn-body))
                   1012:        (d-exp (do ((ll newbody (cdr ll))
                   1013:                   (g-loc)
                   1014:                   (g-cc)
                   1015:                   (g-ret))
                   1016:                  ((null (cdr ll)) (car ll))
                   1017:                  (d-exp (car ll))))
                   1018:        (d-unbind)))
                   1019: 
                   1020: #+for-vax
                   1021: (defun d-checkforfixedargs (fcnname number)
                   1022:    (let ((oklab (d-genlab)))
                   1023:       (makecomment `(,fcnname should-have-exactly ,number args))
                   1024:       ; calc -4*# of args
                   1025:       (e-sub '#.np-reg '#.lbot-reg)
                   1026:       (e-cmp '#.lbot-reg `($ ,(- (* number 4))))
                   1027:       (e-write2 'jeql oklab)
                   1028:       (d-wnaerr fcnname number number)
                   1029:       (e-label oklab)))
                   1030: 
                   1031: ;--- d-wnaerr  :: generate code to call wrong number of args error
                   1032: ; name is the function name,
                   1033: ; min is the minumum number of args for this function
                   1034: ; max is the maximum number (-1 if there is no maximum)
                   1035: ;  we encode the min and max in the way shown below.
                   1036: ;
                   1037: #+for-vax
                   1038: (defun d-wnaerr (name min max)
                   1039:    (makecomment `(arg error for fcn ,name min ,min max ,max))
                   1040:    (e-move 'r10 '#.lbot-reg)
                   1041:    (C-push `($ ,(+ (* min 1000) (+ max 1))))
                   1042:    (C-push (e-cvt (d-loclit name nil)))
                   1043:    (e-write3 'calls '$2 '_wnaerr))
                   1044: 
                   1045: ;--- d-genlab :: generate a pseudo label
                   1046: ;
                   1047: (defun d-genlab nil
                   1048:   (gensym 'L))
                   1049: 
                   1050: ;--- liszt-interrupt-signal
                   1051: ; if we receive a interrupt signal (commonly a ^C), then
                   1052: ; unlink the .s file if we are generating a temporary one
                   1053: ; and exit
                   1054: (defun liszt-interrupt-signal (sig)
                   1055:    (if (and fl-asm (boundp 'v-sfile) v-sfile)
                   1056:       then (sys:unlink v-sfile))
                   1057:    (exit 1))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.