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