Annotation of 43BSD/ucb/lisp/liszt/funb.l, revision 1.1

1.1     ! root        1: (include-if (null (get 'chead 'version)) "../chead.l")
        !             2: (Liszt-file funb
        !             3:    "$Header: funb.l,v 1.12 83/08/28 17:14:58 layer Exp $")
        !             4: 
        !             5: ;;; ----       f u n b                         function compilation
        !             6: ;;;
        !             7: ;;;                            -[Wed Aug 24 17:14:56 1983 by layer]-
        !             8: 
        !             9: ;--- c-declare :: handle the "declare" form
        !            10: ; if a declare is seen inside a function definition, we just 
        !            11: ; ignore it.  We probably should see what it is declareing, as it
        !            12: ; might be declaring a special.
        !            13: ;
        !            14: (defun c-declare nil nil)
        !            15: 
        !            16: ;--- c-do :: compile a "do" expression
        !            17: ;
        !            18: ; a do has this form:
        !            19: ;  (do vrbls tst . body)
        !            20: ; we note the special case of tst being nil, in which case the loop
        !            21: ; is evaluated only once, and thus acts like a let with labels allowed.
        !            22: ; The do statement is a cross between a prog and a lambda. It is like
        !            23: ; a prog in that labels are allowed. It is like a lambda in that
        !            24: ; we stack the values of all init forms then bind to the variables, just
        !            25: ; like a lambda expression (that is the initial values of even specials
        !            26: ; are stored on the stack, and then copied into the value cell of the
        !            27: ; atom during the binding phase. From then on the stack location is
        !            28: ; not used).
        !            29: ;
        !            30: (defun c-do nil
        !            31:    (let (b-vrbls b-tst b-body chklab bodylab x-repeat x-vrbs x-fst
        !            32:                 g-loc g-cc oldreguse (g-decls g-decls))
        !            33:        (forcecomment '(beginning do))
        !            34:        (setq g-loc 'reg  chklab (d-genlab)   bodylab (d-genlab))
        !            35: 
        !            36:        (if (and (cadr v-form) (atom (cadr v-form)))
        !            37:           then (setq v-form (d-olddo-to-newdo (cdr v-form))))
        !            38: 
        !            39:        (push (cons 'do 0) g-locs)              ; begin our frame
        !            40: 
        !            41:        (setq b-vrbls (cadr v-form)
        !            42:             b-tst   (caddr v-form)
        !            43:             b-body  (cdddr v-form))
        !            44: 
        !            45:        (d-scanfordecls b-body)
        !            46: 
        !            47:        ; push value of init forms on stack
        !            48:        (d-pushargs (mapcar '(lambda (x)
        !            49:                                (if (atom x)
        !            50:                                    then nil ; no init form => nil
        !            51:                                    else (cadr x)))
        !            52:                           b-vrbls))
        !            53: 
        !            54:        ; now bind to  the variables in the vrbls form
        !            55:        (d-bindlamb (mapcar '(lambda (x)
        !            56:                                (if (atom x) then x
        !            57:                                    else (car x)))
        !            58:                           b-vrbls))
        !            59: 
        !            60:        ; search through body for all labels and assign them gensymed labels
        !            61:        (push (cons (d-genlab)
        !            62:                   (do ((ll b-body (cdr ll))
        !            63:                        (res))
        !            64:                       ((null ll) res)
        !            65:                       (if (and (car ll) (symbolp (car ll)))
        !            66:                           then (Push res
        !            67:                                      (cons (car ll) (d-genlab))))))
        !            68:             g-labs)
        !            69: 
        !            70:        ; if the test is non nil, we do the test
        !            71:        ; another strange thing, a test form of (pred) will not return
        !            72:        ; the value of pred if it is not nil! it will return nil -- in this
        !            73:        ; way, it is not like a cond clause
        !            74:        (d-clearreg)
        !            75:        (if b-tst then (e-label chklab)
        !            76:           (let ((g-cc (cons nil bodylab)) g-loc g-ret)
        !            77:               (d-exp (car b-tst)))     ; eval test
        !            78:           ; if false, do body
        !            79:           (if (cdr b-tst) 
        !            80:               then (setq oldreguse (copy g-reguse))
        !            81:                    (d-exps (cdr b-tst))
        !            82:                    (setq g-reguse oldreguse)
        !            83:               else  (d-move 'Nil 'reg))
        !            84:           (e-goto (caar g-labs))               ; leave do
        !            85:           (e-label bodylab))           ; begin body
        !            86: 
        !            87:        ; process body
        !            88:        (do ((ll b-body (cdr ll))
        !            89:            (g-cc) (g-loc)(g-ret))
        !            90:           ((null ll))
        !            91:           (if (or (null (car ll)) (not (symbolp (car ll))))
        !            92:               then (d-exp (car ll))
        !            93:               else (e-label (cdr (assoc (car ll) (cdar g-labs))))
        !            94:                    (d-clearreg)))
        !            95: 
        !            96:        (if b-tst
        !            97:           then ; determine all repeat forms which must be
        !            98:                ; evaluated, and all the variables affected.
        !            99:                ; store the results in x-repeat and  x-vrbs
        !           100:                ; if there is just one repeat form, we calculate
        !           101:                ; its value directly into where it is stored,
        !           102:                ; if there is more than one, we stack them
        !           103:                ; and then store them back at once.
        !           104:                (do ((ll b-vrbls (cdr ll)))
        !           105:                    ((null ll))
        !           106:                    (if (and (dtpr (car ll)) (cddar ll))
        !           107:                        then (Push x-repeat (caddar ll))
        !           108:                             (Push x-vrbs   (caar ll))))
        !           109:                (if x-vrbs 
        !           110:                    then (if (null (cdr x-vrbs))  ; if just one repeat
        !           111:                             then (let ((g-loc (d-locv (car x-vrbs)))
        !           112:                                        (g-cc nil))
        !           113:                                      (d-exp (car x-repeat)))
        !           114:                             else (setq x-fst (car x-repeat))
        !           115:                                  (d-pushargs (nreverse
        !           116:                                                  (cdr x-repeat)))
        !           117:                                  (let ((g-loc (d-locv (car x-vrbs)))
        !           118:                                        (g-cc)
        !           119:                                        (g-ret))
        !           120:                                      (d-exp x-fst))
        !           121:                                  (do ((ll (cdr x-vrbs) (cdr ll)))
        !           122:                                      ((null ll))
        !           123:                                      (d-move 'unstack
        !           124:                                              (d-locv (car ll)))
        !           125:                                      (setq g-locs (cdr g-locs))
        !           126:                                      (decr g-loccnt))))
        !           127:                (e-goto chklab))
        !           128: 
        !           129:        (e-label (caar g-labs))                 ; end of do label
        !           130:        (d-clearreg)
        !           131:        (d-unbind)
        !           132:        (setq g-labs (cdr g-labs))))
        !           133: 
        !           134: ;--- d-olddo-to-newdo  :: map old do to new do
        !           135: ;
        !           136: ; form of old do is  (do var tst . body)
        !           137: ; where var is a symbol, not nil
        !           138: ;
        !           139: (defun d-olddo-to-newdo (v-l)
        !           140:   `(do ((,(car v-l) ,(cadr v-l) ,(caddr v-l)))
        !           141:        (,(cadddr v-l))
        !           142:        ,@(cddddr v-l)))
        !           143: 
        !           144: ;--- cc-dtpr :: check for dtprness
        !           145: ;
        !           146: (defun cc-dtpr nil
        !           147:   (d-typesimp (cadr v-form) #.(immed-const 3)))
        !           148: 
        !           149: ;--- cc-eq :: compile an "eq" expression
        !           150: ;
        !           151: (defun cc-eq nil
        !           152:    (let ((arg1 (cadr v-form))
        !           153:         (arg2 (caddr v-form))
        !           154:         arg1loc
        !           155:         arg2loc)
        !           156:        (if (setq arg2loc (d-simple arg2))
        !           157:           then (if (setq arg1loc (d-simple arg1))
        !           158:                    then ; eq <simple> <simple>
        !           159:                         (d-cmp arg1loc arg2loc)
        !           160:                    else ; eq <nonsimple> <simple>
        !           161:                         (let ((g-loc 'reg)     ; put <nonsimple> in reg
        !           162:                               ; must rebind because
        !           163:                               ; cc->& may have modified
        !           164:                               (g-trueop #+for-vax 'jneq #+for-68k 'jne)
        !           165:                               (g-falseop #+for-vax 'jeql #+for-68k 'jeq)
        !           166:                               g-cc
        !           167:                               g-ret)
        !           168:                             (d-exp arg1))
        !           169:                         (d-cmp 'reg arg2loc))
        !           170:           else ; since second is nonsimple, must stack first
        !           171:                ; arg out of harms way
        !           172:                (let ((g-loc 'stack)
        !           173:                      (g-trueop #+for-vax 'jneq #+for-68k 'jne)
        !           174:                      (g-falseop #+for-vax 'jeql #+for-68k 'jeq)
        !           175:                      g-cc
        !           176:                      g-ret)
        !           177:                    (d-exp arg1)
        !           178:                    (push nil g-locs)
        !           179:                    (incr g-loccnt)
        !           180:                    (setq g-loc 'reg)           ; second arg to reg
        !           181:                    (d-exp arg2))
        !           182:                (d-cmp 'unstack 'reg)
        !           183:                (setq g-locs (cdr g-locs))
        !           184:                (decr g-loccnt)))
        !           185:    (d-invert))
        !           186: 
        !           187: ;--- cc-equal :: compile `equal'
        !           188: ;
        !           189: (defun cc-equal nil
        !           190:   (let ((lab1 (d-genlab))
        !           191:        (lab11 (d-genlab))
        !           192:        lab2)
        !           193:        (d-pushargs (cdr v-form))
        !           194:        (e-cmp '(-8 #.np-reg) '(-4 #.np-reg))
        !           195:        (e-gotonil lab1)
        !           196:        (d-calltran 'equal '2)           ; not eq, try equal.
        !           197:        (d-clearreg)
        !           198:        #+for-vax (e-tst (e-cvt 'reg))
        !           199:        #+for-68k (e-cmpnil (e-cvt 'reg))
        !           200:        (e-gotot lab11)         
        !           201:        (if g-loc then (d-move 'Nil g-loc))
        !           202:        (if (cdr g-cc) then (e-goto (cdr g-cc))
        !           203:           else (e-goto (setq lab2 (d-genlab))))
        !           204:        (e-writel lab1)
        !           205:        (e-dropnp 2)
        !           206:        (e-writel lab11)
        !           207:        (if g-loc then (d-move 'T g-loc))
        !           208:        (if (car g-cc) then (e-goto (car g-cc)))
        !           209:        (if lab2 then (e-writel lab2))
        !           210:        (setq g-locs (cddr g-locs))
        !           211:        (setq g-loccnt (- g-loccnt 2))))
        !           212: 
        !           213: ;--- c-errset :: compile an errset expression
        !           214: ;
        !           215: ; the errset has this form: (errset 'value ['tag])
        !           216: ; where tag defaults to t.
        !           217: ;
        !           218: (defun c-errset nil
        !           219:   (let ((g-loc 'reg)
        !           220:        (g-cc nil)
        !           221:        (g-ret nil)
        !           222:        (finlab (d-genlab))
        !           223:        (beglab (d-genlab)))
        !           224:        (d-exp (if (cddr v-form) then (caddr v-form) else t))
        !           225:        (d-pushframe #.F_CATCH (d-loclit 'ER%all nil) 'reg)
        !           226:        (push nil g-labs)               ; disallow labels
        !           227:        ; If retval is non zero then an error has throw us here so we 
        !           228:        ; must recover the value thrown (from _lispretval) and leave
        !           229:        ; If retval is zero then we shoud calculate the expression 
        !           230:        ; into r0  and put a cons cell around it
        !           231:        (e-tst '_retval)
        !           232:        (e-write2 #+for-vax 'jeql #+for-68k 'jeq beglab)
        !           233:        (e-move '_lispretval (e-cvt 'reg))
        !           234:        (e-write2 #+for-vax 'jbr #+for-68k 'jra finlab)
        !           235:        (e-label beglab)
        !           236:        (let ((g-loc 'stack)
        !           237:             (g-cc nil))
        !           238:            (d-exp (cadr v-form)))
        !           239:        (d-move 'Nil 'stack)    ; haven't updated g-loc, g-loccnt but it
        !           240:                                ; shouldn't hurt (famous last words)
        !           241:        (e-quick-call '_qcons)
        !           242:        (e-label finlab)
        !           243:        (d-popframe)
        !           244:        (unpush g-locs)         ; remove (catcherrset . 0)
        !           245:        (unpush g-labs)         ; remove nil
        !           246:        (d-clearreg)))
        !           247: 
        !           248: ;--- cm-fixnum-cxr :: open code a fixnum-cxr expression.
        !           249: ; 
        !           250: ; fixnum-cxr is a compile only hacky function which accesses an element
        !           251: ; of a fixnum space and boxes the resulting fixnum.  It can be used
        !           252: ; for rapid access to user defined structures.
        !           253: ;
        !           254: (defun cm-fixnum-cxr ()
        !           255:   `(internal-fixnum-box (cxr ,@(cdr v-form))))
        !           256: 
        !           257: (defun c-internal-fixnum-box ()
        !           258:   (let ((g-cc nil)
        !           259:        (g-ret nil)
        !           260:        (g-loc '#.fixnum-reg))
        !           261:        #+for-68k (d-regused '#.fixnum-reg)
        !           262:        (d-exp (cadr v-form))
        !           263:        (e-call-qnewint)))
        !           264: 
        !           265: ;--- cc-offset-cxr
        !           266: ; return a pointer to the address of the object instead of the object.
        !           267: ;
        !           268: (defun cc-offset-cxr nil
        !           269:   (d-supercxr nil t))
        !           270: 
        !           271: ;--- cc-fixp :: check for a fixnum or bignum
        !           272: ;
        !           273: (defun cc-fixp nil
        !           274:   (d-typecmplx (cadr v-form) 
        !           275:               '#.(immed-const (plus 1_2 1_9))))
        !           276: 
        !           277: ;--- cc-floatp :: check for a flonum
        !           278: ;
        !           279: (defun cc-floatp nil
        !           280:   (d-typesimp (cadr v-form) #.(immed-const 4)))
        !           281: 
        !           282: ;--- c-funcall :: compile a funcall
        !           283: ;
        !           284: ; we open code a funcall the resulting object is a compiled lambda.
        !           285: ; We don't open code nlambda and macro funcalls since they are
        !           286: ; rarely used and it would waste space to check for them
        !           287: (defun c-funcall nil
        !           288:    (if (null (cdr v-form))
        !           289:       then (comp-err "funcall requires at least one argument " v-form))
        !           290:    (let ((g-locs g-locs)
        !           291:         (g-loccnt g-loccnt)
        !           292:         (args (length (cdr v-form)))
        !           293:         (g-loc nil)
        !           294:         (g-ret nil)
        !           295:         (g-cc nil))
        !           296:       (d-pushargs (cdr v-form))
        !           297:       (rplaca (nthcdr (1- args) g-locs) 'funcallfcn)
        !           298: 
        !           299:       (d-exp '(cond ((and (symbolp funcallfcn)
        !           300:                          (getd funcallfcn))
        !           301:                     (setq funcallfcn (getd funcallfcn)))))
        !           302:             
        !           303:       (d-exp `(cond ((and (bcdp funcallfcn) (eq 'lambda (getdisc funcallfcn)))
        !           304:                        (Internal-bcdcall ,args t))
        !           305:                       (t (Internal-bcdcall  ,args nil))))))
        !           306: 
        !           307: ;--- c-Internal-bcdcall
        !           308: ; this is a compiler internal function call.  when this occurs, there
        !           309: ;  are argnum objects stacked, the first of which is a function name
        !           310: ;  or bcd object.  If dobcdcall is t then we want to do a bcdcall of
        !           311: ;  the first object stacked.  If it is not true then we want to
        !           312: ;  call the interpreter funcall function to handle it.
        !           313: ;
        !           314: (defun c-Internal-bcdcall nil
        !           315:    (let ((argnum (cadr v-form))
        !           316:         (dobcdcall (caddr v-form)))
        !           317:       (cond (dobcdcall (d-bcdcall argnum))
        !           318:            (t (d-calltran 'funcall argnum)))))
        !           319: 
        !           320: ;--- cc-function :: compile a function function
        !           321: ;
        !           322: ; function is an nlambda, which the interpreter treats as 'quote'
        !           323: ; If the argument is a lambda expression, then Liszt will generate
        !           324: ; a new function and generate code to return the name of
        !           325: ; that function.  If the argument is a symbol, then 'symbol
        !           326: ; is compiled.   It would probably be better to return the function
        !           327: ; cell of the symbol, but Maclisp returns the symbol and it
        !           328: ; would cause compatibility problems.
        !           329: ;
        !           330: (defun cc-function nil
        !           331:    (if (or (null (cdr v-form))
        !           332:           (cddr v-form))
        !           333:       then (comp-err "Wrong number of arguments to 'function': " v-form))
        !           334:    (let ((arg (cadr v-form)))
        !           335:       (if (symbolp arg)
        !           336:         then (d-exp `',arg)
        !           337:        elseif (and (dtpr arg)
        !           338:                   (memq (car arg) '(lambda nlambda lexpr)))
        !           339:         then (let ((newname (concat "in-line-lambda:"
        !           340:                                     (setq in-line-lambda-number
        !           341:                                           (add1 in-line-lambda-number)))))
        !           342:                 (Push liszt-process-forms
        !           343:                       `(def ,newname ,arg))
        !           344:                 (d-exp `',newname))
        !           345:         else (comp-err "Illegal argument to 'function': " v-form))))
        !           346: 
        !           347: ;--- c-get :: do a get from the prop list
        !           348: ;
        !           349: (defun c-get nil
        !           350:   (if (not (eq 2 (length (cdr v-form))))
        !           351:       then (comp-err "Wrong number of args to get " v-form))
        !           352:   (d-pushargs (cdr v-form))            ; there better be 2 args
        !           353:   (e-quick-call '_qget)
        !           354:   (d-clearreg)
        !           355:   (setq g-locs (cddr g-locs))
        !           356:   (setq g-loccnt (- g-loccnt 2)))
        !           357: 
        !           358: ;--- cm-getaccess :: compile a getaccess instruction
        !           359: ;
        !           360: (defun cm-getaccess nil `(cdr ,(cadr v-form)))
        !           361: 
        !           362: ;--- cm-getaux :: compile a getaux instruction
        !           363: ;
        !           364: (defun cm-getaux  nil `(car ,(cadr v-form)))
        !           365: 
        !           366: ;--- cm-getd :: compile a getd instruction
        !           367: ;
        !           368: ; the getd function is open coded to look in the third part of a symbol
        !           369: ; cell
        !           370: ;
        !           371: (defun cm-getd nil `(cxr 2 ,(cadr v-form)))
        !           372: 
        !           373: ;--- cm-getdata :: compile a getdata instruction
        !           374: ;
        !           375: ; the getdata function is open coded to look in the third part of an 
        !           376: ; array header.
        !           377: (defun cm-getdata nil `(cxr 2 ,(cadr v-form)))
        !           378: 
        !           379: ;--- cm-getdisc  :: compile a getdisc expression
        !           380: ; getdisc accessed the discipline field of a binary object.
        !           381: ;
        !           382: (defun cm-getdisc nil `(cxr 1 ,(cadr v-form)))
        !           383: 
        !           384: ;--- c-go :: compile a "go" expression
        !           385: ;
        !           386: ; we only compile the (go symbol)type expression, we do not
        !           387: ; allow symbol to be anything by a non null symbol.
        !           388: ;
        !           389: (defun c-go nil
        !           390:    ; find number of frames we have to go down to get to the label
        !           391:    (do ((labs g-labs (cdr labs))
        !           392:        (locs g-locs)
        !           393:        (locals 0)
        !           394:        (specials 0)
        !           395:        (catcherrset 0)
        !           396:        (label))
        !           397:        ((null labs)
        !           398:        (comp-err "go label not found for expression: " (or v-form)))
        !           399: 
        !           400:        (if (car labs)          ; if we have a set of labels to look at...
        !           401:           then (if (setq label
        !           402:                          (do ((lbs (cdar labs) (cdr lbs)))
        !           403:                              ((null lbs))
        !           404:                              (if (eq (caar lbs) (cadr v-form))
        !           405:                                  then (return (cdar lbs)))))
        !           406:                    then (if (not (eq labs g-labs))
        !           407:                             then (comp-note g-fname ": non local go used : "
        !           408:                                             (or v-form)))
        !           409:                         ; three stack to pop: namestack, bindstack
        !           410:                         ;   and execution stack
        !           411:                         (e-pop locals)
        !           412:                         (if (greaterp specials 0)
        !           413:                             then (e-unshallowbind specials))
        !           414:                         (if (greaterp catcherrset 0)
        !           415:                             then (comp-note g-fname
        !           416:                                             ": Go through a catch or errset "
        !           417:                                             v-form)
        !           418:                                  (do ((i 0 (1+ i)))
        !           419:                                      ((=& catcherrset i))
        !           420:                                      (d-popframe)))
        !           421:                         (e-goto label)
        !           422:                         (return)))
        !           423:        ; tally all locals, specials and catcherrsets used in this frame
        !           424:        (do ()
        !           425:           ((dtpr (car locs))
        !           426:            (if (eq 'catcherrset (caar locs))
        !           427:               then (incr catcherrset)
        !           428:             elseif (eq 'progv (caar locs))
        !           429:               then (comp-err "Attempt to 'go' through a progv"))
        !           430:            (setq specials (+ specials (cdar locs))
        !           431:                  locs (cdr locs)))
        !           432:           (setq locs (cdr locs))
        !           433:           (incr locals))))
        !           434:                        
        !           435: ;--- cc-ignore :: just ignore this code
        !           436: ;
        !           437: (defun cc-ignore nil
        !           438:   nil)
        !           439: 
        !           440: ;--- c-lambexp :: compile a lambda expression
        !           441: ;
        !           442: (defun c-lambexp nil
        !           443:   (let ((g-loc (if (or g-loc g-cc) then 'reg))
        !           444:        (g-cc nil)
        !           445:        (g-locs (cons (cons 'lambda 0) g-locs))
        !           446:        (g-labs (cons nil g-labs)))
        !           447:        (d-pushargs (cdr v-form))               ; then push vals
        !           448:        (d-lambbody (car v-form))
        !           449:        (d-clearreg)))
        !           450: 
        !           451: ;--- d-lambbody :: do a lambda body
        !           452: ;      - body : body of lambda expression, eg (lambda () dld)
        !           453: ;
        !           454: (defun d-lambbody (body)
        !           455:    (let ((g-decls g-decls))
        !           456:       (d-scanfordecls (cddr body))             ; look for declarations
        !           457:       (d-bindlamb (cadr body))         ; bind locals
        !           458:       (d-clearreg)
        !           459:       (d-exp (do ((ll (cddr body) (cdr ll))
        !           460:                  (g-loc)
        !           461:                  (g-cc)
        !           462:                  (g-ret))
        !           463:                 ((null (cdr ll)) (car ll))
        !           464:                 (d-exp (car ll))))
        !           465: 
        !           466:       (d-unbind)))                             ; unbind this frame
        !           467: 
        !           468: ;--- d-bindlamb :: bind  variables in lambda list
        !           469: ;      - vrbs : list of lambda variables, may include nil meaning ignore
        !           470: ;
        !           471: (defun d-bindlamb (vrbs)
        !           472:   (let ((res (d-bindlrec (reverse vrbs) g-locs 0 g-loccnt)))
        !           473:        (if res then (e-setupbind)
        !           474:                    (mapc '(lambda (vrb) (e-shallowbind (car vrb) (cdr vrb)))
        !           475:                          res)
        !           476:                    (e-unsetupbind))))
        !           477:   
        !           478: ;--- d-bindlrec :: recusive routine to bind lambda variables
        !           479: ;      - vrb : list of variables yet to bind
        !           480: ;      - locs : current location in g-loc
        !           481: ;      - specs : number of specials seen so far
        !           482: ;      - lev  : how far up from the bottom of stack we are.
        !           483: ; returns: list of elements, one for each special, of this form:
        !           484: ;              (<specialvrbname> stack <n>)
        !           485: ;      where specialvrbname is the name of the special variable, and n is
        !           486: ;      the distance from the top of the stack where its initial value is 
        !           487: ;      located
        !           488: ; also: puts the names of the local variables in the g-locs list, as well
        !           489: ;      as placing the number of special variables in the lambda header.
        !           490: ;
        !           491: (defun d-bindlrec (vrb locs specs lev)
        !           492:    (if vrb 
        !           493:        then (let ((spcflg (d-specialp (car vrb)))
        !           494:                  retv)
        !           495:                (if spcflg then (setq specs (1+ specs)))
        !           496: 
        !           497:                (if (cdr vrb)           ; if more vrbls to go ...
        !           498:                    then (setq retv (d-bindlrec (cdr vrb)
        !           499:                                                (cdr locs)
        !           500:                                                specs
        !           501:                                                (1- lev)))
        !           502:                    else (rplacd (cadr locs)
        !           503:                                 specs))        ; else fix up lambda hdr
        !           504: 
        !           505:                (if (not spcflg) then (rplaca locs (car vrb))
        !           506:                    else (Push retv `(,(car vrb) stack ,lev)))
        !           507: 
        !           508:                retv)))
        !           509: 
        !           510: ;--- d-scanfordecls
        !           511: ; forms - the body of a lambda, prog or do.
        !           512: ;  we look down the form for 'declare' forms.  They should be at the
        !           513: ;  beginning, but there are macros which may unintentionally put forms
        !           514: ;  in front of user written forms.  Thus we check a little further than
        !           515: ;  the first form.
        !           516: (defun d-scanfordecls (forms)
        !           517:    ; look for declarations in the first few forms
        !           518:    (do ((count 3 (1- count)))
        !           519:        ((= 0 count))
        !           520:        (cond ((and (dtpr (car forms))
        !           521:                   (eq 'declare (caar forms))
        !           522:                   (apply 'liszt-declare (cdar forms)))))
        !           523:        (setq forms (cdr forms))))
        !           524: 
        !           525: ;--- c-list :: compile a list expression
        !           526: ;
        !           527: ; this is compiled as a bunch of conses with a nil pushed on the
        !           528: ; top for good measure
        !           529: ;
        !           530: (defun c-list nil
        !           531:   (prog (nargs)
        !           532:        (setq nargs (length (cdr v-form)))
        !           533:        (makecomment '(list expression))
        !           534:        (if (zerop nargs)
        !           535:            then (d-move 'Nil 'reg)     ; (list) ==> nil
        !           536:                 (return))
        !           537:        (d-pushargs (cdr v-form))
        !           538:        #+for-vax (e-write2 'clrl '#.np-plus)   ; stack one nil
        !           539:        #+for-68k (L-push (e-cvt 'Nil))
        !           540: 
        !           541:        ; now do the consing
        !           542:        (do ((i (max 1 nargs) (1- i)))
        !           543:           ((zerop i))
        !           544:           (e-quick-call '_qcons)
        !           545:           (d-clearreg)
        !           546:           (if (> i 1) then (L-push (e-cvt 'reg))))
        !           547: 
        !           548:        (setq g-locs (nthcdr nargs g-locs)
        !           549:             g-loccnt (- g-loccnt nargs))))
        !           550: 
        !           551: ;--- d-mapconvert - access : function to access parts of lists
        !           552: ;                - join         : function to join results
        !           553: ;                - resu         : function to apply to result
        !           554: ;                - form         : mapping form
        !           555: ;      This function converts maps to an equivalent do form.
        !           556: ;
        !           557: ;  in this function, the variable vrbls contains a list of forms, one form
        !           558: ;  per list we are mapping over.  The form of the form is 
        !           559: ;    (dummyvariable  realarg  (cdr dummyvariable))
        !           560: ; realarg may be surrounded by (setq <variable which holds result> realarg)
        !           561: ; in the case that the result is the list to be mapped over (this only occurs
        !           562: ; with the function mapc).
        !           563: ;
        !           564: (defun d-mapconvert (access join resu form )
        !           565:    (prog (vrbls finvar acc accform compform
        !           566:                tmp testform tempvar lastvar)
        !           567: 
        !           568:        (setq finvar (gensym 'X)   ; holds result
        !           569: 
        !           570:             vrbls
        !           571:             (reverse
        !           572:                 (maplist '(lambda (arg)
        !           573:                               ((lambda (temp)
        !           574:                                    (cond ((or resu (cdr arg))
        !           575:                                           `(,temp ,(car arg)
        !           576:                                              (cdr ,temp)))
        !           577:                                          (t `(,temp
        !           578:                                                (setq ,finvar
        !           579:                                                       ,(car arg))
        !           580:                                                (cdr ,temp)))))
        !           581:                                (gensym 'X)))
        !           582:                          (reverse (cdr form))))
        !           583: 
        !           584:             ; the access form will either be nil or car.  If it is
        !           585:             ; nil, then we are doing something like a maplist,
        !           586:             ; if the access form is car, then we are doing something
        !           587:             ; like a mapcar.
        !           588:             acc (mapcar '(lambda (tem)
        !           589:                              (cond (access `(,access ,(car tem)))
        !           590:                                    (t (car tem))))
        !           591:                         vrbls)
        !           592: 
        !           593:             accform (cond ((or (atom (setq tmp (car form)))
        !           594:                                (null (setq tmp (d-macroexpand tmp)))
        !           595:                                (not (member (car tmp) '(quote function))))
        !           596:                            `(funcall ,tmp ,@acc))
        !           597:                           (t `(,(cadr tmp) ,@acc)))
        !           598: 
        !           599:             ; the testform checks if any of the lists we are mapping
        !           600:             ; over is nil, in which case we quit.
        !           601:             testform (cond ((null (cdr vrbls)) `(null ,(caar vrbls)))
        !           602:                            (t `(or ,@(mapcar '(lambda (x)
        !           603:                                                   `(null ,(car  x)))
        !           604:                                              vrbls)))))
        !           605: 
        !           606:        ; in the case of mapcans and mapcons, you need two
        !           607:        ; extra variables to simulate the nconc.
        !           608:        ; testvar gets intermediate results and lastvar
        !           609:        ; points to then end of the list
        !           610:        (if (eq join 'nconc)
        !           611:           then (setq tempvar (gensym 'X)
        !           612:                      lastvar (gensym 'X)
        !           613:                      vrbls `((,tempvar) (,lastvar) ,@vrbls)))
        !           614: 
        !           615:        (return
        !           616:           `((lambda
        !           617:                 (,finvar)
        !           618:                 (liszt-internal-do
        !           619:                     ( ,@vrbls)
        !           620:                     (,testform)
        !           621:                     ,(cond ((eq join 'nconc)
        !           622:                             `(cond ((setq ,tempvar ,accform)
        !           623:                                     (cond (,lastvar
        !           624:                                             (liszt-internal-do
        !           625:                                                 ()
        !           626:                                                 ((null (cdr ,lastvar)))
        !           627:                                                 (setq ,lastvar
        !           628:                                                       (cdr ,lastvar)))
        !           629:                                             (rplacd ,lastvar ,tempvar))
        !           630:                                           (t (setq ,finvar
        !           631:                                                     (setq ,lastvar
        !           632:                                                           ,tempvar)))))))
        !           633:                            (join `(setq ,finvar (,join ,accform ,finvar)))
        !           634:                            (t accform)))
        !           635:                 ,(cond ((eq resu 'identity) finvar)
        !           636:                        (resu `(,resu ,finvar))
        !           637:                        (t finvar)))
        !           638:             nil ))))
        !           639: 
        !           640: ; apply to successive elements, return second arg
        !           641: (defun cm-mapc nil
        !           642:          (d-mapconvert 'car nil nil (cdr v-form)))
        !           643: 
        !           644: ; apply to successive elements, return list of results
        !           645: (defun cm-mapcar nil
        !           646:          (d-mapconvert 'car 'cons 'nreverse (cdr v-form)))
        !           647: 
        !           648: ; apply to successive elements, returned nconc of results
        !           649: (defun cm-mapcan nil
        !           650:          (d-mapconvert 'car 'nconc 'identity (cdr v-form)))
        !           651: 
        !           652: ; apply to successive sublists, return second arg
        !           653: (defun cm-map nil
        !           654:          (d-mapconvert nil nil nil (cdr v-form)))
        !           655: 
        !           656: ; apply to successive sublists, return list of results
        !           657: (defun cm-maplist nil
        !           658:          (d-mapconvert nil 'cons 'reverse (cdr v-form)))
        !           659: 
        !           660: ; apply to successive sublists, return nconc of results
        !           661: (defun cm-mapcon nil
        !           662:          (d-mapconvert nil 'nconc 'identity (cdr v-form)))
        !           663: 
        !           664: ;--- cc-memq :: compile a memq expression
        !           665: ;
        !           666: #+for-vax
        !           667: (defun cc-memq nil
        !           668:   (let ((loc1 (d-simple (cadr v-form)))
        !           669:        (loc2 (d-simple (caddr v-form)))
        !           670:        looploc finlab)
        !           671:        (if loc2
        !           672:           then (d-clearreg 'r1)
        !           673:                (if loc1
        !           674:                    then (d-move loc1 'r1)
        !           675:                    else (let ((g-loc 'r1)
        !           676:                               g-cc
        !           677:                               g-ret)
        !           678:                             (d-exp (cadr v-form))))
        !           679:                (d-move loc2 'reg)
        !           680:           else (let ((g-loc 'stack)
        !           681:                      g-cc
        !           682:                      g-ret)
        !           683:                    (d-exp (cadr v-form)))
        !           684:                (push nil g-locs)
        !           685:                (incr g-loccnt)
        !           686:                (let ((g-loc 'reg)
        !           687:                      g-cc
        !           688:                      g-ret)
        !           689:                    (d-exp (caddr v-form)))
        !           690:                (L-pop 'r1)
        !           691:                (d-clearreg 'r1)
        !           692:                (unpush g-locs)
        !           693:                (decr g-loccnt))
        !           694:        ; now set up the jump addresses
        !           695:        (if (null g-loc)
        !           696:           then (setq loc1 (if (car g-cc) thenret else (d-genlab))
        !           697:                      loc2 (if (cdr g-cc) thenret else (d-genlab)))
        !           698:           else (setq loc1 (d-genlab)
        !           699:                      loc2 (d-genlab)))
        !           700: 
        !           701:        (setq looploc (d-genlab))
        !           702:        (e-tst 'r0)
        !           703:        (e-write2 'jeql loc2)
        !           704:        (e-label looploc)
        !           705:        (e-cmp 'r1 '(4 r0))
        !           706:        (e-write2 'jeql loc1)
        !           707:        (e-move '(0 r0) 'r0)
        !           708:        (e-write2 'jneq looploc)
        !           709:        (if g-loc
        !           710:           then (e-label loc2)          ; nil result
        !           711:                (d-move 'reg g-loc)
        !           712:                (if (cdr g-cc)
        !           713:                    then (e-goto (cdr g-cc))
        !           714:                    else (e-goto (setq finlab (d-genlab))))
        !           715:           else (if (cdr g-cc)
        !           716:                    then (e-goto (cdr g-cc))
        !           717:                    else (e-label loc2)))
        !           718:        (if g-loc
        !           719:           then (e-label loc1)          ; non nil result
        !           720:                (d-move 'reg g-loc)
        !           721:                (if (car g-cc) then (e-goto (car g-cc)))
        !           722:           else (if (null (car g-cc)) then (e-label loc1)))
        !           723:        (if finlab then (e-label finlab))))
        !           724: 
        !           725: #+for-68k
        !           726: (defun cc-memq nil
        !           727:    (let ((loc1 (d-simple (cadr v-form)))
        !           728:         (loc2 (d-simple (caddr v-form)))
        !           729:         looploc finlab
        !           730:         (tmp-data-reg (d-alloc-register 'd nil)))
        !           731:        (d-clearreg tmp-data-reg)
        !           732:        (d-clearreg 'a0)
        !           733:        (if loc2
        !           734:           then (if loc1
        !           735:                    then (d-move loc1 tmp-data-reg)
        !           736:                    else (let ((g-loc tmp-data-reg)
        !           737:                               g-cc
        !           738:                               g-ret)
        !           739:                             (d-exp (cadr v-form))))
        !           740:                (d-move loc2 'reg)
        !           741:           else (let ((g-loc 'stack)
        !           742:                      g-cc
        !           743:                      g-ret)
        !           744:                    (d-exp (cadr v-form)))
        !           745:                (push nil g-locs)
        !           746:                (incr g-loccnt)
        !           747:                (let ((g-loc 'reg)
        !           748:                      g-cc
        !           749:                      g-ret)
        !           750:                    (d-exp (caddr v-form)))
        !           751:                (L-pop tmp-data-reg)
        !           752:                (unpush g-locs)
        !           753:                (decr g-loccnt))
        !           754:        ; now set up the jump addresses
        !           755:        (if (null g-loc)
        !           756:           then (setq loc1 (if (car g-cc) thenret else (d-genlab))
        !           757:                      loc2 (if (cdr g-cc) thenret else (d-genlab)))
        !           758:           else (setq loc1 (d-genlab)
        !           759:                      loc2 (d-genlab)))
        !           760:        (setq looploc (d-genlab))
        !           761:        (e-cmpnil 'd0)
        !           762:        (e-write2 'jeq loc2)
        !           763:        (e-move 'd0 'a0)
        !           764:        (e-label looploc)
        !           765:        (e-cmp tmp-data-reg '(4 a0))
        !           766:        (e-write2 'jeq loc1)
        !           767:        (e-move '(0 a0) 'a0)
        !           768:        (e-cmpnil 'a0)
        !           769:        (e-write2 'jne looploc)
        !           770:        (e-move 'a0 'd0)
        !           771:        (if g-loc
        !           772:           then (e-label loc2)                  ; nil result
        !           773:                (d-move 'reg g-loc)
        !           774:                (if (cdr g-cc)
        !           775:                    then (e-goto (cdr g-cc))
        !           776:                    else (e-goto (setq finlab (d-genlab))))
        !           777:           else (if (cdr g-cc)
        !           778:                    then (e-goto (cdr g-cc))
        !           779:                    else (e-label loc2)))
        !           780:        (if g-loc
        !           781:           then (e-label loc1)                  ; non nil result
        !           782:                (d-move 'a0 g-loc)              ;a0 was cdr of non-nil result
        !           783:                (if (car g-cc) then (e-goto (car g-cc)))
        !           784:           else (if (null (car g-cc)) then (e-label loc1)))
        !           785:        (if finlab then (e-label finlab))))

unix.superglobalmegacorp.com

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