|
|
1.1 ! root 1: ! 2: ! 3: ; l i s z t v 4 ! 4: ! 5: ! 6: ! 7: ! 8: ; Copyright (c) 1980 , The Regents of the University of California. ! 9: ; All rights reserved. ! 10: ; author: j. foderaro ! 11: ! 12: ; Section EXPR -- general expression compiler ! 13: ! 14: (include "caspecs.l") ! 15: ! 16: (eval-when (compile eval) ! 17: (cond ((not (getd 'If)) ! 18: (fasl 'camacs)))) ! 19: ! 20: (setq sectioncadrid "@(#)cadr.l 5.4 10/22/80") ; id for SCCS ! 21: ! 22: ;--- d-exp :: compile a lisp expression = d-exp = ! 23: ; v-form : a lisp expression to compile ! 24: ; returns an IADR which tells where the value was located. ! 25: ; ! 26: (defun d-exp (v-form) ! 27: (prog (first resloc tmp ftyp) ! 28: ! 29: begin ! 30: (If (atom v-form) ! 31: then (setq tmp (d-loc v-form)) ;locate vrble ! 32: (If (null g-loc) ! 33: then (If g-cc then (d-tst tmp)) ! 34: else (d-move tmp g-loc)) ! 35: (d-handlecc) ! 36: (return tmp) ! 37: ! 38: elseif (atom (setq first (car v-form))) ! 39: then (If (and fl-xref (not (get first g-refseen))) ! 40: then (Push g-reflst first) ! 41: (putprop first t g-refseen)) ! 42: (setq ftyp (d-functyp first)) ! 43: (If (eq 'macro ftyp) ! 44: then (setq v-form (apply first v-form)) ! 45: (go begin) ! 46: elseif (setq tmp (get first 'fl-exprcc)) ! 47: then (return (funcall tmp)) ! 48: elseif (setq tmp (get first 'fl-exprm)) ! 49: then (setq v-form (funcall tmp)) ! 50: (go begin) ! 51: elseif (setq tmp (get first 'fl-expr)) ! 52: then (funcall tmp) ! 53: elseif (setq tmp (or (and (eq 'car first) ! 54: '( a )) ! 55: (and (eq 'cdr first) ! 56: '( d )) ! 57: (d-cxxr first))) ! 58: then (return (cc-cxxr (cadr v-form) tmp)) ! 59: elseif (eq 'nlambda ftyp) ! 60: then (d-callbig first `(',(cdr v-form))) ! 61: elseif (or (eq 'lambda ftyp) (eq 'lexpr ftyp)) ! 62: then (setq tmp (length v-form)) ! 63: ! 64: (d-callbig first (cdr v-form))) ! 65: elseif (eq 'lambda (car first)) ! 66: then (c-lambexp) ! 67: ! 68: elseif (or (eq 'quote (car first)) (eq 'function (car first))) ! 69: then (comp-warn "bizzare function name " (or first)) ! 70: (setq v-form (cons (cadr first) (cdr v-form))) ! 71: (go begin) ! 72: ! 73: else (comp-err "bad expression" (or v-form))) ! 74: ! 75: (If (null g-loc) ! 76: then (If g-cc then (d-tst 'reg)) ! 77: elseif (eq g-loc 'reg) ! 78: then (If g-cc then (d-tst 'reg)) ! 79: else (d-move 'reg g-loc)) ! 80: (If g-cc then (d-handlecc)))) ! 81: ! 82: ;--- d-functyp :: return the type of function ! 83: ; - name : function name ! 84: ; ! 85: (defun d-functyp (name) ! 86: (let (ftyp ) ! 87: (If (atom name) then ! 88: (If (setq ftyp (getd name)) ! 89: then (If (bcdp ftyp) ! 90: then (getdisc ftyp) ! 91: elseif (dtpr ftyp) ! 92: then (car ftyp)) ! 93: elseif (get name g-functype) thenret ! 94: else 'lambda)))) ; default is lambda ! 95: ! 96: ! 97: ;--- d-exps :: compile a list of expressions ! 98: ; - exps : list of expressions ! 99: ; the last expression is evaluated according to g-loc and g-cc, the others ! 100: ; are evaluated with g-loc and g-cc nil. ! 101: ; ! 102: (defun d-exps (exps) ! 103: (d-exp (do ((ll exps (cdr ll)) ! 104: (g-loc nil) ! 105: (g-cc nil) ! 106: (g-ret nil)) ! 107: ((null (cdr ll)) (car ll)) ! 108: (d-exp (car ll))))) ! 109: ! 110: ! 111: ;--- d-pushargs :: compile and push a list of expressions ! 112: ; - exps : list of expressions ! 113: ; compiles and stacks a list of expressions ! 114: ; ! 115: (defun d-pushargs (args) ! 116: (If args then (do ((ll args (cdr ll)) ! 117: (g-loc 'stack) ! 118: (g-cc nil) ! 119: (g-ret nil)) ! 120: ((null ll)) ! 121: (d-exp (car ll)) ! 122: (Push g-locs nil) ! 123: (incr g-loccnt)))) ! 124: ! 125: ;--- d-cxxr :: split apart a cxxr function name ! 126: ; - name : a possible cxxr function name ! 127: ; returns the a's and d's between c and r in reverse order, or else ! 128: ; returns nil if this is not a cxxr name ! 129: ; ! 130: (defun d-cxxr (name) ! 131: (let ((expl (explodec name))) ! 132: (If (eq 'c (car expl)) ; must begin with c ! 133: then (do ((ll (cdr expl) (cdr ll)) ! 134: (tmp) ! 135: (res)) ! 136: (nil) ! 137: (setq tmp (car ll)) ! 138: (If (null (cdr ll)) ! 139: then (If (eq 'r tmp) ; must end in r ! 140: then (return res) ! 141: else (return nil)) ! 142: elseif (or (eq 'a tmp) ; and contain only a's and d's ! 143: (eq 'd tmp)) ! 144: then (setq res (cons tmp res)) ! 145: else (return nil)))))) ! 146: ! 147: ;--- d-call :: call another function ! 148: ; - name : name of funtion to call ! 149: ; - nargs : number of args stacked (including the function name) ! 150: ; ! 151: (defun d-call (name nargs) ! 152: (prog (tmp) ! 153: (forcecomment `(calling ,name)) ! 154: (If (null (setq tmp (cdr (assoc nargs ! 155: '( (1 . (* -8 #.bind-reg)) ! 156: (2 . (* -12 #.bind-reg)) ! 157: (3 . (* -16 #.bind-reg)) ! 158: (4 . (* -20 #.bind-reg)) ! 159: (5 . (* -24 #.bind-reg))))))) ! 160: then ; lbot will not be set up automatically ! 161: (e-write3 'movab ; must set up lbot ! 162: `(,(* -4 nargs) #.Np-reg) ! 163: '#.Lbot-reg) ! 164: (setq tmp '(* -28 #.bind-reg))) ! 165: (e-write2 'jsb tmp))) ! 166: ! 167: ;--- d-callbig :: call a local or global function ! 168: ; ! 169: ; ! 170: (defun d-callbig (name args) ! 171: (let ((tmp (get name g-localf)) ! 172: c) ! 173: (forcecomment `(calling ,name)) ! 174: (If (d-dotailrecursion name args) thenret ! 175: elseif tmp then ;-- local function call ! 176: (d-pushargs args) ! 177: (e-write2 'jsb (car tmp)) ! 178: (setq g-locs (nthcdr (setq c (length args)) g-locs)) ! 179: (setq g-loccnt (- g-loccnt c)) ! 180: else (If fl-tran ;-- transfer table linkage ! 181: then (d-pushargs args) ! 182: (setq c (length args)) ! 183: (d-calltran name c) ! 184: else ;--- standard function call ! 185: (d-pushargs `(',name ,@args)) ! 186: (d-call name (setq c (1+ (length args))))) ! 187: (setq g-locs (nthcdr c g-locs)) ! 188: (setq g-loccnt (- g-loccnt c))) ! 189: (d-clearreg))) ! 190: ! 191: ! 192: ;--- d-calltran :: call a function through the transfer table = d-calltran = ! 193: ; name - name of function to call ! 194: ; c - number of arguments to the function ! 195: ; ! 196: (defun d-calltran (name c) ! 197: (e-write3 'movab `(,(* -4 c) #.Np-reg) '#.Lbot-reg) ! 198: (e-write3 'calls '$0 (concat "*trantb+" (d-tranloc name))) ! 199: (e-write3 'movl '#.Lbot-reg '#.Np-reg)) ! 200: ! 201: ;--- d-tranloc :: locate a function in the transfer table = d-tranloc = ! 202: ; ! 203: ; return the offset we should use for this function call ! 204: ; ! 205: (defun d-tranloc (fname) ! 206: (cond ((get fname g-tranloc)) ! 207: (t (Push g-tran fname) ! 208: (let ((newval (* 8 g-trancnt))) ! 209: (putprop fname newval g-tranloc) ! 210: (incr g-trancnt) ! 211: newval)))) ! 212: ! 213: ;--- d-dotailrecursion :: do tail recursion if possible ! 214: ; name - function name we are to call ! 215: ; args - arguments to give to function ! 216: ; ! 217: ; return t iff we were able to do tail recursion ! 218: ; We can do tail recursion if: ! 219: ; g-ret is set indicating that the result of this call will be returned ! 220: ; as the value of the function we are compiling ! 221: ; the function we are calling, name, is the same as the function we are ! 222: ; compiling, g-fname ! 223: ; there are no variables shallow bound, since we would have to unbind ! 224: ; them, which may cause problems in the function. ! 225: ; ! 226: (defun d-dotailrecursion (name args) ! 227: (If (and g-ret ! 228: (eq name g-fname) ! 229: (do ((loccnt 0) ! 230: (ll g-locs (cdr ll))) ! 231: ((null ll) (return t)) ! 232: (If (dtpr (car ll)) ! 233: then (If (or (eq 'catcherrset (caar ll)) ! 234: (greaterp (cdar ll) 0)) ! 235: then (return nil)) ! 236: else (incr loccnt)))) ! 237: then ! 238: ; evalate the arguments and pop them back to the location of ! 239: ; the original args. ! 240: (makecomment '(tail merging)) ! 241: (comp-note "Tail merging being done: " v-form) ! 242: (let ((g-locs g-locs) ! 243: (g-loccnt g-loccnt)) ! 244: (d-pushargs args)) ; push then forget about ! 245: (let (base-reg nargs) ! 246: (If (eq g-ftype 'lexpr) ! 247: then ; the beginning of the local variables ! 248: ;has been stacked ! 249: (e-write3 'addl2 '$4 'sp) ; pop off arg count ! 250: (e-write4 'addl3 '$4 "(sp)" Lbot-reg) ! 251: (setq base-reg Lbot-reg) ; will push from bot ! 252: else (setq base-reg oLbot-reg)) ; will push from olbot ! 253: (setq nargs (length args)) ! 254: (do ((i nargs (1- i)) ! 255: (top (* nargs -4) (+ top 4)) ! 256: (bot 0 (+ bot 4))) ! 257: ((zerop i)) ! 258: (e-write3 'movl `(,top ,Np-reg) `(,bot ,base-reg))) ! 259: (e-write3 'movab `(,(* 4 nargs) ,base-reg) Np-reg) ! 260: (e-goto g-topsym)) ! 261: t)) ; return t to indicate that tailrecursion was successful ! 262: ! 263: ! 264: ! 265: ! 266: ; Section xxx -- specific function compilers ! 267: ; ! 268: ! 269: ;--- cc-and :: compile an and expression ! 270: ; We evaluate forms from left to right as long as they evaluate to ! 271: ; a non nil value. We only have to worry about storing the value of ! 272: ; the last expression in g-loc. ! 273: ; ! 274: (defun cc-and nil ! 275: (let ((finlab (d-genlab)) ! 276: (finlab2) ! 277: (exps (If (cdr v-form) thenret else '(t)))) ; (and) ==> t ! 278: (If (null (cdr g-cc)) ! 279: then (d-exp (do ((g-cc (cons nil finlab)) ! 280: (g-loc) ! 281: (g-ret) ! 282: (ll exps (cdr ll))) ! 283: ((null (cdr ll)) (car ll)) ! 284: (d-exp (car ll)))) ! 285: (If g-loc then (setq finlab2 (d-genlab)) ! 286: (e-goto finlab2) ! 287: (e-label finlab) ! 288: (d-move 'Nil g-loc) ! 289: (e-label finlab2) ! 290: else (e-label finlab)) ! 291: else ;--- cdr g-cc is non nil, thus there is ! 292: ; a quick escape possible if one of the ! 293: ; expressions evals to nil ! 294: ! 295: (If (null g-loc) then (setq finlab (cdr g-cc))) ! 296: (d-exp (do ((g-cc (cons nil finlab)) ! 297: (g-loc) ! 298: (g-ret) ! 299: (ll exps (cdr ll))) ! 300: ((null (cdr ll)) (car ll)) ! 301: (d-exp (car ll)))) ! 302: ; if g-loc is non nil, then we have evaled the and ! 303: ; expression to yield nil, which we must store in ! 304: ; g-loc and then jump to where the cdr of g-cc takes us ! 305: (If g-loc then (setq finlab2 (d-genlab)) ! 306: (e-goto finlab2) ! 307: (e-label finlab) ! 308: (d-move 'Nil g-loc) ! 309: (e-goto (cdr g-cc)) ! 310: (e-label finlab2)))) ! 311: (d-clearreg)) ; we cannot predict the state of the registers ! 312: ! 313: ! 314: ! 315: ! 316: ;--- cc-arg :: get the nth arg from the current lexpr = cc-arg = ! 317: ; ! 318: ; the syntax for Franz lisp is (arg i) ! 319: ; for interlisp the syntax is (arg x i) where x is not evaluated and is ! 320: ; the name of the variable bound to the number of args. We can only handle ! 321: ; the case of x being the variable for the current lexpr we are compiling ! 322: ; ! 323: (defun cc-arg nil ! 324: (let ((nillab (d-genlab)) (finlab (d-genlab))) ! 325: (If (not (eq 'lexpr g-ftype)) ! 326: then (comp-err " arg only allowed in lexprs")) ! 327: (If (and (eq (length (cdr v-form)) 2) fl-inter) ! 328: then (If (not (eq (car g-args) (cadr v-form))) ! 329: then (comp-err " arg expression is for non local lexpr " ! 330: v-form) ! 331: else (setq v-form (cdr v-form)))) ! 332: (If (or g-loc g-cc) ! 333: then (let ((g-loc 'reg) ! 334: (g-cc (cons nil nillab)) ! 335: (g-ret)) ! 336: (d-exp `(cdr ,(cadr v-form)))) ; calc the numeric arg ! 337: (If g-loc then (d-move '"*-4(fp)[r0]" g-loc) ! 338: else (e-tst '"*-4(fp)[r0]")) ! 339: (d-handlecc) ! 340: (e-goto finlab) ! 341: (e-label nillab) ! 342: ; here we are doing (arg nil) which returns the number of args ! 343: ; which is always true if anyone is testing ! 344: (If g-loc then (d-move '"-8(fp)" g-loc) ! 345: (d-handlecc) ! 346: elseif (car g-cc) then (e-goto (car g-cc))) ;always true ! 347: (e-label finlab)))) ! 348: ! 349: ! 350: ;--- cc-atom :: test for atomness = cc-atom = ! 351: ; ! 352: (defun cc-atom nil ! 353: (d-typecmplx (cadr v-form) ! 354: '#.(concat '$ (plus 1_0 1_1 1_2 1_4 1_5 1_6 1_7 1_9 1_10)))) ! 355: ! 356: ! 357: ;--- cc-bcdp :: check for bcdpness = cc-bcdp = ! 358: ; ! 359: (defun cc-bcdp nil ! 360: (d-typesimp (cadr v-form) '$5)) ! 361: ! 362: ! 363: ;--- cc-bigp :: check for bignumness = cc-bigp = ! 364: ; ! 365: (defun cc-bigp nil ! 366: (d-typesimp (cadr v-form) '$9)) ! 367: ! 368: ;--- c-*catch :: compile a *catch expression = c-*catch = ! 369: ; ! 370: ; the form of *catch is (*catch 'tag 'val) ! 371: ; we evaluate 'tag and set up a catch frame, and then eval 'val ! 372: ; ! 373: (defun c-*catch nil ! 374: (let ((g-loc 'reg) ! 375: (g-cc nil) ! 376: (g-ret nil) ! 377: (finlab (d-genlab))) ! 378: (d-exp (cadr v-form)) ; calculate tag into r0 ! 379: (d-catcherrset finlab 'reg 'T (caddr v-form)) ! 380: (e-label finlab))) ! 381: ! 382: ! 383: ! 384: ;--- d-catcherrset :: common code to catch and errset ! 385: ; ! 386: (defun d-catcherrset (finlab tagloc flagloc expr) ! 387: (e-write2 'pushab finlab) ! 388: (e-write2 'pushr '$0x2540) ; save registers ! 389: (e-write2 'jsb '_svkludg) ; save rest of state ! 390: (e-write2 'pushl Bnp-val) ! 391: (e-write2 'pushl (e-cvt tagloc)) ; push tag ! 392: (e-write2 'pushl (e-cvt flagloc)) ; non-nil flag ! 393: (e-write2 'pushl '_errp) ; old error pointer ! 394: (e-write3 'movl 'sp '_errp) ; set up new error pointer ! 395: (Push g-locs '(catcherrset . 0)) ! 396: (d-exp expr) ; now do the expression ! 397: (unpush g-locs) ! 398: (e-write3 'movl '"(sp)" '_errp) ; unlink this error frame ! 399: (e-write3 'addl2 '$80 'sp) ! 400: (d-clearreg)) ; cant predict contents after retune ! 401: ! 402: ! 403: ;--- c-cond :: compile a "cond" expression = c-cond = ! 404: ; ! 405: ; not that this version of cond is a 'c' rather than a 'cc' . ! 406: ; this was done to make coding this routine easier and because ! 407: ; it is believed that it wont harm things much if at all ! 408: ; ! 409: (defun c-cond nil ! 410: (makecomment '(beginning cond)) ! 411: (do ((clau (cdr v-form) (cdr clau)) ! 412: (finlab (d-genlab)) ! 413: (nxtlab) ! 414: (save-reguse) ! 415: (seent)) ! 416: ((or (null clau) seent) ! 417: ; end of cond ! 418: ; if haven't seen a t must store a nil in r0 ! 419: (If (null seent) then (d-move 'Nil 'reg)) ! 420: (e-label finlab)) ! 421: ! 422: ; case 1 - expr ! 423: (If (atom (car clau)) ! 424: then (comp-err "bad cond clause " (car clau)) ! 425: ; case 2 - (expr) ! 426: elseif (null (cdar clau)) ! 427: then (let ((g-loc (If (or g-cc g-loc) then 'reg)) ! 428: (g-cc (cons finlab nil)) ! 429: (g-ret)) ! 430: (d-exp (caar clau))) ! 431: ; case 3 - (t expr1 expr2 ...) ! 432: elseif (or (eq t (caar clau)) ! 433: (equal ''t (caar clau))) ! 434: then (let ((g-loc (If (or g-cc g-loc) then 'reg)) ! 435: g-cc) ! 436: (d-exps (cdar clau))) ! 437: (setq seent t) ! 438: ; case 4 - (expr1 expr2 ...) ! 439: else (let ((g-loc nil) ! 440: (g-cc (cons nil (setq nxtlab (d-genlab)))) ! 441: (g-ret nil)) ! 442: (d-exp (caar clau))) ! 443: (setq save-reguse (copy g-reguse)) ! 444: (let ((g-loc (If (or g-cc g-loc) then 'reg)) ! 445: g-cc) ! 446: (d-exps (cdar clau))) ! 447: (If (or (cdr clau) (null seent)) then (e-goto finlab)) ! 448: (e-label nxtlab) ! 449: (setq g-reguse save-reguse))) ! 450: ! 451: (d-clearreg)) ! 452: ! 453: ! 454: ! 455: ;--- c-cons :: do a cons instruction quickly = c-cons = ! 456: ; ! 457: (defun c-cons nil ! 458: (d-pushargs (cdr v-form)) ; there better be 2 args ! 459: (e-write2 'jsb '_qcons) ! 460: (setq g-locs (cddr g-locs)) ! 461: (setq g-loccnt (- g-loccnt 2)) ! 462: (d-clearreg)) ! 463: ! 464: ! 465: ;--- c-cxr :: compile a cxr instruction = c-cxr = ! 466: ; ! 467: ; this code would also be useful for accessing any vector of lispvals. ! 468: ; ! 469: (defun c-cxr nil ! 470: (prog (arg1 arg2 arg1loc arg2loc) ! 471: (setq arg1loc (d-simple (setq arg1 (list 'cdr (cadr v-form)))) ! 472: arg2loc (d-simple (setq arg2 (caddr v-form)))) ! 473: ! 474: (If (not (and (dtpr arg1loc) (eq 'immed (car arg1loc)))) ! 475: then ! 476: (If arg2loc ! 477: then (If (null arg1loc) ! 478: then (let ((g-loc 'r1) ! 479: (g-cc)) ! 480: (d-exp arg1)) ! 481: else (d-move arg1loc 'r1)) ! 482: (d-move arg2loc 'r0) ! 483: else (d-pushargs (ncons arg1)) ! 484: (let ((g-loc 'r0) ! 485: (g-cc)) ! 486: (d-exp arg2)) ! 487: (d-move 'unstack 'r1) ! 488: (decr g-loccnt) ! 489: (Pop g-locs)) ! 490: (d-inreg 'r1 nil) ; register clobbered ! 491: (If g-loc then (e-move `(0 r0 r1) (e-cvt g-loc)) ! 492: (d-handlecc) ! 493: elseif g-cc then (e-tst `(0 r0 r1)) ! 494: (d-handlecc)) ! 495: else (let ((g-loc 'r0) ! 496: (g-cc)) ! 497: (d-exp arg2)) ! 498: (setq arg1loc (list (* 4 (cadr arg1loc)) 'r0)) ! 499: (If g-loc then (e-move arg1loc (e-cvt g-loc)) ! 500: (d-handlecc) ! 501: elseif g-cc then (e-tst arg1loc) ! 502: (d-handlecc))))) ! 503: ! 504: ! 505: ;--- cc-cxxr :: compile a "c*r" instr where * = c-cxxr = ! 506: ; is any sequence of a's and d's ! 507: ; - arg : argument of the cxxr function ! 508: ; - pat : a list of a's and d's in the reverse order of that ! 509: ; which appeared between the c and r ! 510: ; ! 511: (defun cc-cxxr (arg pat) ! 512: (prog (resloc loc qloc sofar togo keeptrack) ! 513: ; check for the special case of nil, since car's and cdr's ! 514: ; are nil anyway ! 515: (If (null arg) then (If g-loc then (d-move 'Nil g-loc) ! 516: (d-handlecc) ! 517: elseif (cdr g-cc) then (e-goto (cdr g-cc))) ! 518: (return)) ! 519: ! 520: (If (and (symbolp arg) (setq qloc (d-bestreg arg pat))) ! 521: then (setq resloc (car qloc) ! 522: loc resloc ! 523: sofar (cadr qloc) ! 524: togo (caddr qloc)) ! 525: else (setq resloc (If (d-simple arg) thenret ! 526: else (let ((g-loc 'reg) ! 527: (g-cc nil) ! 528: (g-ret nil)) ! 529: (d-exp arg)) ! 530: 'r0)) ! 531: (setq sofar nil ! 532: togo pat)) ! 533: ! 534: (If (and arg (symbolp arg)) then (setq keeptrack t)) ! 535: ! 536: ; if resloc is a global variable, we must move it into a register ! 537: ; right away to be able to do car's and cdr's ! 538: (If (and (dtpr resloc) (or (eq (car resloc) 'bind) ! 539: (eq (car resloc) 'vstack))) ! 540: then (d-move resloc 'reg) ! 541: (setq resloc 'r0)) ! 542: ! 543: ; now do car's and cdr's . Values are placed in r0. We stop when ! 544: ; we can get the result in one machine instruction. At that point ! 545: ; we see whether we want the value or just want to set the cc's. ! 546: ; If the intermediate value is in a register, ! 547: ; we can do : car cdr cddr cdar ! 548: ; If the intermediate value is on the local vrbl stack or lbind ! 549: ; we can do : cdr ! 550: (do ((curp togo newp) ! 551: (newp)) ! 552: ((null curp) (If g-loc then (d-movespec loc g-loc) ! 553: elseif g-cc then (e-tst loc)) ! 554: (d-handlecc)) ! 555: (If (symbolp resloc) ! 556: then (If (eq 'd (car curp)) ! 557: then (If (or (null (cdr curp)) ! 558: (eq 'a (cadr curp))) ! 559: then (setq newp (cdr curp) ; cdr ! 560: loc `(0 ,resloc) ! 561: sofar (append sofar (list 'd))) ! 562: else (setq newp (cddr curp) ; cddr ! 563: loc `(* 0 ,resloc) ! 564: sofar (append sofar (list 'd 'd)))) ! 565: else (If (or (null (cdr curp)) ! 566: (eq 'a (cadr curp))) ! 567: then (setq newp (cdr curp) ; car ! 568: loc `(4 ,resloc) ! 569: sofar (append sofar (list 'a))) ! 570: else (setq newp (cddr curp) ; cdar ! 571: loc `(* 4 ,resloc) ! 572: sofar (append sofar (list 'a 'd))))) ! 573: elseif (and (eq 'd (car curp)) ! 574: (not (eq '* (car (setq loc (e-cvt resloc)))))) ! 575: then (setq newp (cdr curp) ; (cdr <local>) ! 576: loc (cons '* loc) ! 577: sofar (append sofar (list 'd))) ! 578: else (setq loc (e-cvt resloc) ! 579: newp curp)) ! 580: (If newp ; if this is not the last move ! 581: then (setq resloc (d-allocreg (If keeptrack then nil else 'r0))) ! 582: (d-movespec loc resloc) ! 583: (If keeptrack then (d-inreg resloc (cons arg sofar))))))) ! 584: ! 585: ;--- c-declare :: handle the "declare" form ! 586: ; if a declare is seen inside a function definition, we just ! 587: ; ignore it. We probably should see what it is declareing, as it ! 588: ; might be declaring a special. ! 589: ; ! 590: (defun c-declare nil) ! 591: ! 592: ;--- c-do :: compile a "do" expression = c-do = ! 593: ; ! 594: ; a do has this form: ! 595: ; (do vrbls tst . body) ! 596: ; we note the special case of tst being nil, in which case the loop ! 597: ; is evaluated only once, and thus acts like a let with labels allowed. ! 598: ; The do statement is a cross between a prog and a lambda. It is like ! 599: ; a prog in that labels are allowed. It is like a lambda in that ! 600: ; we stack the values of all init forms then bind to the variables, just ! 601: ; like a lambda expression (that is the initial values of even specials ! 602: ; are stored on the stack, and then copied into the value cell of the ! 603: ; atom during the binding phase. From then on the stack location is ! 604: ; not used). ! 605: ; ! 606: (defun c-do nil ! 607: (prog (b-vrbls b-tst b-body chklab bodylab x-repeat x-vrbs x-fst ! 608: g-loc g-cc oldreguse) ! 609: (forcecomment '(beginning do)) ! 610: (setq g-loc 'reg chklab (d-genlab) bodylab (d-genlab)) ! 611: ! 612: (If (and (cadr v-form) (atom (cadr v-form))) ! 613: then (setq v-form (d-olddo-to-newdo (cdr v-form)))) ! 614: ! 615: (Push g-locs (cons 'do 0 )) ; begin our frame ! 616: ! 617: (setq b-vrbls (cadr v-form) ! 618: b-tst (caddr v-form) ! 619: b-body (cdddr v-form)) ! 620: ! 621: ; push value of init forms on stack ! 622: (d-pushargs (mapcar '(lambda (x) ! 623: (If (atom x) then nil ; no init form => nil ! 624: else (cadr x))) ! 625: b-vrbls)) ! 626: ! 627: ; now bind to the variables in the vrbls form ! 628: (d-bindlamb (mapcar '(lambda (x) ! 629: (If (atom x) then x ! 630: else (car x))) ! 631: b-vrbls)) ! 632: ! 633: ; search through body for all labels and assign them gensymed labels ! 634: (Push g-labs (cons (d-genlab) ! 635: (do ((ll b-body (cdr ll)) ! 636: (res)) ! 637: ((null ll) res) ! 638: (If (and (car ll) (symbolp (car ll))) ! 639: then (Push res (cons (car ll) (d-genlab))))))) ! 640: ! 641: ; if the test is non nil, we do the test ! 642: ; another strange thing, a test form of (pred) will not return ! 643: ; the value of pred if it is not nil! it will return nil (in this ! 644: ; way, it is not like a cond clause) ! 645: (d-clearreg) ! 646: (If b-tst then (e-label chklab) ! 647: (let ((g-cc (cons nil bodylab)) g-loc g-ret) ! 648: (d-exp (car b-tst))) ; eval test ! 649: ; if false, do body ! 650: (If (cdr b-tst) ! 651: then (setq oldreguse (copy g-reguse)) ! 652: (d-exps (cdr b-tst)) ! 653: (setq g-reguse oldreguse) ! 654: else (d-move 'Nil 'reg)) ! 655: (e-goto (caar g-labs)) ; leave do ! 656: (e-label bodylab)) ; begin body ! 657: ! 658: ; process body ! 659: (do ((ll b-body (cdr ll)) ! 660: (g-cc) (g-loc)(g-ret)) ! 661: ((null ll)) ! 662: (If (or (null (car ll)) (not (symbolp (car ll)))) ! 663: then (d-exp (car ll)) ! 664: else (e-label (cdr (assoc (car ll) (cdar g-labs)))) ! 665: (d-clearreg))) ! 666: ! 667: (If b-tst then ; determine all repeat forms which must be ! 668: ; evaluated, and all the variables affected. ! 669: ; store the results in x-repeat and x-vrbs ! 670: ; if there is just one repeat form, we calculate ! 671: ; its value directly into where it is stored, ! 672: ; if there is more than one, we stack them ! 673: ; and then store them back at once. ! 674: (do ((ll b-vrbls (cdr ll))) ! 675: ((null ll)) ! 676: (If (and (dtpr (car ll)) (cddar ll)) ! 677: then (Push x-repeat (caddar ll)) ! 678: (Push x-vrbs (caar ll)))) ! 679: (If x-vrbs ! 680: then (If (null (cdr x-vrbs)) ; if just one repeat.. ! 681: then (let ((g-loc (d-locv (car x-vrbs))) ! 682: (g-cc nil)) ! 683: (d-exp (car x-repeat))) ! 684: else (setq x-fst (car x-repeat)) ! 685: (d-pushargs (nreverse (cdr x-repeat))) ! 686: (let ((g-loc (d-locv (car x-vrbs))) ! 687: (g-cc) ! 688: (g-ret)) ! 689: (d-exp x-fst)) ! 690: (do ((ll (cdr x-vrbs) (cdr ll))) ! 691: ((null ll)) ! 692: (d-move 'unstack (d-locv (car ll))) ! 693: (setq g-locs (cdr g-locs)) ! 694: (decr g-loccnt)))) ! 695: (e-goto chklab)) ! 696: ! 697: (e-label (caar g-labs)) ; end of do label ! 698: (d-clearreg) ! 699: (d-unbind) ! 700: (setq g-labs (cdr g-labs)))) ! 701: ! 702: ! 703: ;--- d-olddo-to-newdo :: map old do to new do ! 704: ; ! 705: ; form of old do is (do var tst . body) ! 706: ; where var is a symbol, not nil ! 707: ; ! 708: (defun d-olddo-to-newdo (v-l) ! 709: `(do ((,(car v-l) ,(cadr v-l) ,(caddr v-l))) ! 710: (,(cadddr v-l)) ! 711: ,@(cddddr v-l))) ! 712: ! 713: ! 714: ! 715: ;--- cc-dtpr :: check for dtprness = cc-dtpr = ! 716: ; ! 717: (defun cc-dtpr nil ! 718: (d-typesimp (cadr v-form) '$3)) ! 719: ! 720: ! 721: ;--- cc-eq :: compile an "eq" expression = cc-eq = ! 722: ; ! 723: (defun cc-eq nil ! 724: (let ((arg1 (cadr v-form)) ! 725: (arg2 (caddr v-form)) ! 726: arg1loc ! 727: arg2loc) ! 728: (If (setq arg2loc (d-simple arg2)) ! 729: then (If (setq arg1loc (d-simple arg1)) ! 730: then ; eq <simple> <simple> ! 731: (d-cmp arg1loc arg2loc) ! 732: else ; eq <nonsimple> <simple> ! 733: (let ((g-loc 'reg) ; put <nonsimple> in r0 ! 734: g-cc ! 735: g-ret) ! 736: (d-exp arg1)) ! 737: (d-cmp 'reg arg2loc)) ! 738: else ; since second is nonsimple, must stack first ! 739: ; arg out of harms way ! 740: (let ((g-loc 'stack) ! 741: g-cc ! 742: g-ret) ! 743: (d-exp arg1) ! 744: (Push g-locs nil) ! 745: (incr g-loccnt) ! 746: (setq g-loc 'reg) ; second arg to r0 ! 747: (d-exp arg2)) ! 748: (d-cmp 'unstack 'reg) ! 749: (setq g-locs (cdr g-locs)) ! 750: (decr g-loccnt))) ! 751: ! 752: (d-invert)) ! 753: ! 754: (defun cc-equal nil ! 755: (let ((lab1 (d-genlab)) ! 756: (lab11 (d-genlab)) ! 757: lab2) ! 758: (d-pushargs (cdr v-form)) ! 759: (e-write3 'cmpl "-8(r6)" "-4(r6)") ! 760: (e-gotonil lab1) ! 761: (d-calltran 'equal '2) ; not eq, try equal. ! 762: (d-clearreg) ! 763: (e-write2 'tstl 'r0) ! 764: (e-gotot lab11) ! 765: (If g-loc then (d-move 'Nil g-loc)) ! 766: (If (cdr g-cc) then (e-goto (cdr g-cc)) ! 767: else (e-goto (setq lab2 (d-genlab)))) ! 768: (e-writel lab1) ! 769: (e-dropnp 2) ! 770: (e-writel lab11) ! 771: (If g-loc then (d-move 'T g-loc)) ! 772: (If (car g-cc) then (e-goto (car g-cc))) ! 773: (If lab2 then (e-writel lab2)) ! 774: (setq g-locs (cddr g-locs)) ! 775: (setq g-loccnt (- g-loccnt 2)))) ! 776: ! 777: ! 778: ! 779: ! 780: ;--- c-errset :: compile an errset expression = c-errset = ! 781: ; ! 782: ; the errset has this form: (errset 'value ['tag]) ! 783: ; where tag defaults to t. ! 784: ; ! 785: (defun c-errset nil ! 786: (let ((g-loc 'reg) ! 787: (g-cc nil) ! 788: (g-ret nil) ! 789: (finlab (d-genlab))) ! 790: (d-exp (If (cddr v-form) then (caddr v-form) else t)) ! 791: (d-catcherrset finlab (d-loclit '(ER%all) nil) 'reg (cadr v-form)) ! 792: (d-move 'reg 'stack) ! 793: (d-calltran 'ncons 1) ! 794: (e-label finlab) ! 795: (d-clearreg))) ! 796: ! 797: ! 798: ;--- cc-fixp :: check for a fixnum or bignum = cc-fixp = ! 799: ; ! 800: (defun cc-fixp nil ! 801: (d-typecmplx (cadr v-form) ! 802: '#.(concat '$ (plus 1_2 1_9)))) ! 803: ! 804: ! 805: ;--- cc-floatp :: check for a flonum = cc-floatp = ! 806: ; ! 807: (defun cc-floatp nil ! 808: (d-typesimp (cadr v-form) '$4)) ! 809: ! 810: ! 811: ;--- c-get :: do a get from the prop list ! 812: ; ! 813: (defun c-get nil ! 814: (If (not (eq 2 (length (cdr v-form)))) ! 815: then (comp-err "Wrong number of args to get " v-form)) ! 816: (d-pushargs (cdr v-form)) ; there better be 2 args ! 817: (e-write2 'jsb '_qget) ! 818: (d-clearreg) ! 819: (setq g-locs (cddr g-locs)) ! 820: (setq g-loccnt (- g-loccnt 2))) ! 821: ! 822: ;--- c-go :: compile a "go" expression = c-go = ! 823: ; ! 824: ; we only compile the (go symbol)type expression, we do not ! 825: ; allow symbol to be anything by a non null symbol. ! 826: ; ! 827: (defun c-go nil ! 828: ; find number of frames we have to go down to get to the label ! 829: (do ((labs g-labs (cdr labs)) ! 830: (locs g-locs) ! 831: (locals 0) ! 832: (specials 0) ! 833: (catcherrset 0) ! 834: (label)) ! 835: ((null labs) (comp-err "go label not found for expression: " (or v-form))) ! 836: ; if there are any enclosing *catches or errsets, they will be ! 837: ; first in g-locs ! 838: (do nil ! 839: ((not (and (dtpr (car locs)) (eq (caar locs) 'catcherrset)))) ! 840: (incr catcherrset) ! 841: (unpush locs)) ! 842: ! 843: (If (car labs) ! 844: then (If (setq label (do ((lbs (cdar labs) (cdr lbs))) ! 845: ((null lbs)) ! 846: (If (eq (caar lbs) (cadr v-form)) ! 847: then (return (cdar lbs))))) ! 848: then (If (not (eq labs g-labs)) ! 849: then (comp-warn "non local go used : " (or v-form))) ! 850: (If (greaterp catcherrset 0) ! 851: then (comp-warn "Go through a catch or errset " v-form) ! 852: (do ((i 0 (1+ i))) ! 853: ((equal catcherrset i)) ! 854: (e-write3 'movl "(sp)" '_errp) ! 855: (e-write3 'addl2 '$80 'sp))) ! 856: (e-pop locals) ! 857: (If (greaterp specials 0) ! 858: then (e-unshallowbind specials)) ! 859: (e-goto label) ! 860: (return))) ! 861: ; tally all locals and specials used in this frame ! 862: (do () ! 863: ((dtpr (car locs)) (setq specials (+ specials (cdar locs)) ! 864: locs (cdr locs))) ! 865: (setq locs (cdr locs)) ! 866: (incr locals)))) ! 867: ! 868: ! 869: ;--- cc-ingnore :: just ignore this code ! 870: ; ! 871: (defun cc-ignore nil ! 872: nil) ! 873: ! 874: ;--- c-lambexp :: compile a lambda expression = c-lambexp = ! 875: ; ! 876: (defun c-lambexp nil ! 877: (let ((g-loc (If (or g-loc g-cc) then 'reg)) ! 878: (g-cc nil)) ! 879: (Push g-locs (cons 'lambda 0)) ; add null lambda header ! 880: (d-pushargs (cdr v-form)) ; then push vals ! 881: (d-lambbody (car v-form)) ! 882: (d-clearreg))) ! 883: ! 884: ;--- d-lambbody :: do a lambda body ! 885: ; - body : body of lambda expression, eg (lambda () dld) ! 886: ; ! 887: (defun d-lambbody (body) ! 888: (d-bindlamb (cadr body)) ; bind locals ! 889: (setq g-labs (cons nil g-labs)) ; no labels allowed ! 890: (d-clearreg) ! 891: (d-exp (do ((ll (cddr body) (cdr ll)) ! 892: (g-loc) ! 893: (g-cc) ! 894: (g-ret)) ! 895: ((null (cdr ll)) (car ll)) ! 896: (d-exp (car ll)))) ! 897: ! 898: (setq g-labs (cdr g-labs)) ! 899: (d-unbind)) ; unbind this frame ! 900: ! 901: ! 902: ;--- d-bindlamb :: bind variables in lambda list ! 903: ; - vrbs : list of lambda variables, may include nil meaning ignore ! 904: ; ! 905: (defun d-bindlamb (vrbs) ! 906: (let ((res (d-bindlrec (reverse vrbs) g-locs 0 g-loccnt))) ! 907: (If res then (e-setupbind) ! 908: (mapc '(lambda (vrb) (e-shallowbind (car vrb) (cdr vrb))) ! 909: res) ! 910: (e-unsetupbind)))) ! 911: ! 912: ;--- d-bindlrec :: recusive routine to bind lambda variables ! 913: ; - vrb : list of variables yet to bind ! 914: ; - locs : current location in g-loc ! 915: ; - specs : number of specials seen so far ! 916: ; - lev : how far up from the bottom of stack we are. ! 917: ; returns: list of elements, one for each special, of this form: ! 918: ; (<specialvrbname> stack <n>) ! 919: ; where specialvrbname is the name of the special variable, and n is ! 920: ; the distance from the top of the stack where its initial value is ! 921: ; located ! 922: ; also: puts the names of the local variables in the g-locs list, as well ! 923: ; as placing the number of special variables in the lambda header. ! 924: ; ! 925: (defun d-bindlrec (vrb locs specs lev) ! 926: (If vrb ! 927: then (let ((spcflg (d-specialp (car vrb))) ! 928: retv) ! 929: (If spcflg then (setq specs (1+ specs))) ! 930: ! 931: (If (cdr vrb) ; if more vrbls to go ... ! 932: then (setq retv (d-bindlrec (cdr vrb) ! 933: (cdr locs) ! 934: specs ! 935: (1- lev))) ! 936: else (rplacd (cadr locs) specs)) ; else fix up lambda hdr ! 937: ! 938: (If (not spcflg) then (rplaca locs (car vrb)) ! 939: else (Push retv `(,(car vrb) stack ,lev))) ! 940: ! 941: retv))) ! 942: ;--- c-list :: compile a list expression = c-list = ! 943: ; ! 944: ; this is compiled as a bunch of conses with a nil pushed on the ! 945: ; top for good measure ! 946: ; ! 947: (defun c-list nil ! 948: (prog (nargs) ! 949: (setq nargs (length (cdr v-form))) ! 950: (makecomment '(list expression)) ! 951: (If (zerop nargs) then (d-move 'Nil 'reg) ; (list) ==> nil ! 952: (return)) ! 953: (d-pushargs (cdr v-form)) ! 954: (e-write2 'clrl '(+ #.Np-reg)) ; stack one nil ! 955: ! 956: ; now do the consing ! 957: (do ((i (max 1 nargs) (1- i))) ! 958: ((zerop i)) ! 959: (e-write2 'jsb '_qcons) ! 960: (d-clearreg) ! 961: (If (> i 1) then (d-move 'reg 'stack))) ! 962: ! 963: (setq g-locs (nthcdr nargs g-locs) ! 964: g-loccnt (- g-loccnt nargs)))) ! 965: ! 966: ! 967: ! 968: ;--- d-mapconvert - access : function to access parts of lists ! 969: ; - join : function to join results ! 970: ; - resu : function to apply to result ! 971: ; - form : mapping form ! 972: ; This function converts maps to an equivalent do form. ! 973: ; ! 974: (defun d-mapconvert (access join resu form ) ! 975: (prog (vrbls finvar acc accform compform tmp) ! 976: ! 977: (setq finvar (gensym 'X) ; holds result ! 978: ! 979: vrbls (reverse ! 980: (maplist '(lambda (arg) ! 981: ((lambda (temp) ! 982: (cond ((or resu (cdr arg)) ! 983: `(,temp ,(car arg) ! 984: (cdr ,temp))) ! 985: (t `(,temp ! 986: (setq ,finvar ,(car arg)) ! 987: (cdr ,temp))))) ! 988: (gensym 'X))) ! 989: (reverse (cdr form)))) ! 990: ! 991: acc (mapcar '(lambda (tem) ! 992: (cond (access `(,access ,(car tem))) ! 993: (t (car tem)))) ! 994: vrbls) ! 995: ! 996: accform (cond ((or (atom (setq tmp (car form))) ! 997: (null (setq tmp (d-macroexpand tmp))) ! 998: (not (member (car tmp) '(quote function)))) ! 999: `(funcall ,tmp ,@acc)) ! 1000: (t `(,(cadr tmp) ,@acc)))) ! 1001: (return ! 1002: `((lambda (,finvar) ! 1003: (do ( ,@vrbls) ! 1004: ((null ,(caar vrbls))) ! 1005: ,(cond ((eq join 'nconc) ! 1006: `(setq ,finvar (nconc ,finvar ,accform))) ! 1007: (join `(setq ,finvar (,join ,accform ,finvar))) ! 1008: (t accform))) ! 1009: ,(cond ((eq resu 'identity) finvar) ! 1010: (resu `(,resu ,finvar)) ! 1011: (t finvar))) ! 1012: nil )))) ! 1013: ; apply to successive elements, return second arg ! 1014: (defun cm-mapc nil ! 1015: (d-mapconvert 'car nil nil (cdr v-form))) ! 1016: ! 1017: ; apply to successive elements, return list of results ! 1018: (defun cm-mapcar nil ! 1019: (d-mapconvert 'car 'cons 'nreverse (cdr v-form))) ! 1020: ! 1021: ; apply to successive elements, returned nconc of results ! 1022: (defun cm-mapcan nil ! 1023: (d-mapconvert 'car 'nconc 'identity (cdr v-form))) ! 1024: ! 1025: ! 1026: ; apply to successive sublists, return second arg ! 1027: (defun cm-map nil ! 1028: (d-mapconvert nil nil nil (cdr v-form))) ! 1029: ! 1030: ! 1031: ; apply to successive sublists, return list of results ! 1032: (defun cm-maplist nil ! 1033: (d-mapconvert nil 'cons 'reverse (cdr v-form))) ! 1034: ! 1035: ; apply to successive sublists, return nconc of results ! 1036: (defun cm-mapcon nil ! 1037: (d-mapconvert nil 'nconc 'identity (cdr v-form))) ! 1038: ! 1039: ! 1040: ;--- cc-memq :: compile a memq expression = cc-memq = ! 1041: ; ! 1042: (defun cc-memq nil ! 1043: (let ((loc1 (d-simple (cadr v-form))) ! 1044: (loc2 (d-simple (caddr v-form))) ! 1045: looploc finlab) ! 1046: (If loc2 then (d-clearreg 'r1) ! 1047: (If loc1 then (d-move loc1 'r1) ! 1048: else (let ((g-loc 'r1) ! 1049: g-cc ! 1050: g-ret) ! 1051: (d-exp (cadr v-form)))) ! 1052: (d-move loc2 'reg) ! 1053: else (let ((g-loc 'stack) ! 1054: g-cc ! 1055: g-ret) ! 1056: (d-exp (cadr v-form))) ! 1057: (Push g-locs nil) ! 1058: (incr g-loccnt) ! 1059: (let ((g-loc 'reg) ! 1060: g-cc ! 1061: g-ret) ! 1062: (d-exp (caddr v-form))) ! 1063: (d-move 'unstack 'r1) ! 1064: (d-clearreg 'r1) ! 1065: (unpush g-locs) ! 1066: (decr g-loccnt)) ! 1067: ; now set up the jump addresses ! 1068: (If (null g-loc) ! 1069: then (setq loc1 (If (car g-cc) thenret ! 1070: else (d-genlab)) ! 1071: loc2 (If (cdr g-cc) thenret ! 1072: else (d-genlab))) ! 1073: else (setq loc1 (d-genlab) ! 1074: loc2 (d-genlab))) ! 1075: ! 1076: (setq looploc (d-genlab)) ! 1077: ! 1078: (e-write2 'tstl 'r0) ! 1079: (e-write2 'jeql loc2) ! 1080: (e-label looploc) ! 1081: (e-write3 'cmpl 'r1 "4(r0)") ! 1082: (e-write2 'jeql loc1) ! 1083: (e-write3 'movl "(r0)" 'r0) ! 1084: (e-write2 'jneq looploc) ! 1085: (If g-loc then (e-label loc2) ; nil result ! 1086: (d-move 'reg g-loc) ! 1087: (If (cdr g-cc) then (e-goto (cdr g-cc)) ! 1088: else (e-goto (setq finlab (d-genlab)))) ! 1089: else (If (cdr g-cc) then (e-goto (cdr g-cc)) ! 1090: else (e-label loc2))) ! 1091: (If g-loc then (e-label loc1) ; non nil result ! 1092: (d-move 'reg g-loc) ! 1093: (If (car g-cc) then (e-goto (car g-cc))) ! 1094: else (If (null (car g-cc)) then (e-label loc1))) ! 1095: (If finlab then (e-label finlab)))) ! 1096:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.