Annotation of 42BSD/ucb/lisp/liszt/expr.l, revision 1.1

1.1     ! root        1: (include-if (null (get 'chead 'version)) "../chead.l")
        !             2: (Liszt-file expr
        !             3:    "$Header: expr.l,v 1.12 83/09/06 21:46:46 layer Exp $")
        !             4: 
        !             5: ;;; ----       e x p r                         expression compilation
        !             6: ;;;
        !             7: ;;;                            -[Fri Sep  2 22:10:20 1983 by layer]-
        !             8: 
        !             9: 
        !            10: ;--- d-exp :: compile a lisp expression
        !            11: ;      v-form : a lisp expression to compile
        !            12: ; returns an IADR which tells where the value was located.
        !            13: ;
        !            14: 
        !            15: (defun d-exp (v-form)
        !            16:   (prog (first resloc tmp ftyp nomacrop)
        !            17:     begin
        !            18:        (if (atom v-form)
        !            19:            then (setq tmp (d-loc v-form))              ;locate vrble
        !            20:                 (if (null g-loc)
        !            21:                     then (if g-cc then (d-cmpnil tmp))
        !            22:                    else (d-move tmp g-loc)
        !            23:                         #+for-68k (if g-cc then (d-cmpnil tmp)))
        !            24:                 (d-handlecc)
        !            25:                 (return tmp)
        !            26: 
        !            27:         elseif (atom (setq first (car v-form)))
        !            28:           then ; the form (*no-macroexpand* <expr>)
        !            29:                ; turns into <expr>, and prevents <expr> from
        !            30:                ; being macroexpanded (at the top level)
        !            31:                (if (eq '*no-macroexpand* first)
        !            32:                   then (setq v-form (cadr v-form)
        !            33:                              nomacrop t)
        !            34:                        (go begin))
        !            35:                (if (and fl-xref (not (get first g-refseen)))
        !            36:                     then (Push g-reflst first)
        !            37:                          (putprop first t g-refseen))
        !            38:                 (setq ftyp (d-functyp first (if nomacrop then nil
        !            39:                                                else 'macros-ok)))
        !            40:                 ; if nomacrop is t, then under no circumstances
        !            41:                 ; permit the form to be macroexpanded
        !            42:                 (if (and nomacrop (eq ftyp 'macro))
        !            43:                     then (setq ftyp 'lambda))
        !            44:                 ; If the resulting form is type macro or cmacro,
        !            45:                 ; then call the appropriate function to macro-expand
        !            46:                 ; it.
        !            47:                 (if (memq ftyp '(macro cmacro))
        !            48:                    then (setq tmp v-form)      ; remember original form
        !            49:                         (if (eq 'macro ftyp)
        !            50:                             then (setq v-form (apply first v-form))
        !            51:                           elseif (eq 'cmacro ftyp)
        !            52:                             then (setq v-form (apply (get first 'cmacro)
        !            53:                                                      v-form)))
        !            54:                          ; If the resulting form is the same as
        !            55:                          ; the original form, then we don't want to
        !            56:                          ; macro expand again.  We call d-functyp and tell
        !            57:                          ; it that we want a second opinion
        !            58:                          (if (and (eq (car v-form) first)
        !            59:                                   (equal tmp v-form))
        !            60:                             then (setq ftyp (d-functyp first nil))
        !            61:                             else (go begin))) ; retry with what we have
        !            62: 
        !            63:                 (if (and (setq tmp (get first 'if-fixnum-args))
        !            64:                              (d-allfixnumargs (cdr v-form)))
        !            65:                    then (setq v-form (cons tmp (cdr v-form)))
        !            66:                         (go begin)
        !            67:                  elseif (setq tmp (get first 'fl-exprcc))
        !            68:                    then (d-argnumchk 'hard)
        !            69:                         (return (funcall tmp))
        !            70:                  elseif (setq tmp (get first 'fl-exprm))
        !            71:                    then (d-argnumchk 'hard)
        !            72:                         (setq v-form (funcall tmp))
        !            73:                         (go begin)
        !            74:                  elseif (setq tmp (get first 'fl-expr))
        !            75:                    then (d-argnumchk 'hard)
        !            76:                         (funcall tmp)
        !            77:                  elseif (setq tmp (or (and (eq 'car first)
        !            78:                                            '( a ))
        !            79:                                       (and (eq 'cdr first)
        !            80:                                            '( d ))
        !            81:                                       (d-cxxr first)))
        !            82:                    then (d-argcheckit '(1 . 1) (length (cdr v-form)) 'hard)
        !            83:                         (return (cc-cxxr (cadr v-form) tmp))
        !            84:                   elseif (eq 'nlambda ftyp)
        !            85:                    then (d-argnumchk 'soft)
        !            86:                         (d-callbig first `(',(cdr v-form)) nil)
        !            87:                   elseif (or (eq 'lambda ftyp) (eq 'lexpr ftyp))
        !            88:                     then (setq tmp (length v-form))
        !            89:                          (d-argnumchk 'soft)
        !            90:                          (d-callbig first (cdr v-form) nil)
        !            91:                   elseif (eq 'array ftyp)
        !            92:                    then (d-handlearrayref)
        !            93:                  elseif (eq 'macro ftyp)
        !            94:                    then (comp-err "infinite macro expansion " v-form)
        !            95:                    else (comp-err "internal liszt err in d-exp" v-form))
        !            96: 
        !            97:         elseif (eq 'lambda (car first))
        !            98:            then (c-lambexp)
        !            99: 
        !           100:         elseif (or (eq 'quote (car first)) (eq 'function (car first)))
        !           101:            then (comp-warn "bizzare function name " (or first))
        !           102:                 (setq v-form (cons (cadr first) (cdr v-form)))
        !           103:                 (go begin)
        !           104:                
        !           105:         else (comp-err "bad expression" (or v-form)))
        !           106: 
        !           107:        (if (null g-loc)
        !           108:            then (if g-cc then (d-cmpnil 'reg))
        !           109:         elseif (memq g-loc '(reg #+for-vax r0 #+for-68k d0))
        !           110:            then (if g-cc then (d-cmpnil 'reg))
        !           111:           else (d-move 'reg g-loc)
        !           112:                #+for-68k (if g-cc then (d-cmpnil 'reg)))
        !           113:        (if g-cc then (d-handlecc))))
        !           114: 
        !           115: ;--- d-exps :: compile a list of expressions
        !           116: ;      - exps : list of expressions
        !           117: ; the last expression is evaluated according to g-loc and g-cc, the others
        !           118: ; are evaluated with g-loc and g-cc nil.
        !           119: ;
        !           120: (defun d-exps (exps)
        !           121:   (d-exp (do ((ll exps (cdr ll))
        !           122:              (g-loc nil)
        !           123:              (g-cc  nil)
        !           124:              (g-ret nil))
        !           125:             ((null (cdr ll)) (car ll))
        !           126:             (d-exp (car ll)))))
        !           127: 
        !           128: 
        !           129: ;--- d-argnumchk :: check that the correct number of arguments are given
        !           130: ; v-form (global) contains the expression to check
        !           131: ; class: hard or soft, hard means that failure is an error, soft means
        !           132: ;      warning
        !           133: (defun d-argnumchk (class)
        !           134:    (let ((info (car (get (car v-form) 'fcn-info)))
        !           135:         (argsize (length (cdr v-form))))
        !           136:       (if info then (d-argcheckit info argsize class))))
        !           137: 
        !           138: ;--- d-argcheckit
        !           139: ; info - arg information form:  (min# . max#)  max# of nil means no max
        !           140: ; numargs - number of arguments given
        !           141: ; class - hard or soft
        !           142: ; v-form(global) - expression begin checked
        !           143: ;
        !           144: (defun d-argcheckit (info numargs class)
        !           145:    (if (and (car info) (< numargs (car info)))
        !           146:       then (if (eq class 'hard)
        !           147:              then (comp-err
        !           148:                      (difference (car info) numargs)
        !           149:                      " too few argument(s) given in this expression:" N
        !           150:                      v-form)
        !           151:              else (comp-warn
        !           152:                      (difference (car info) numargs)
        !           153:                      " too few argument(s) given in this expression:" N
        !           154:                      v-form))
        !           155:     elseif (and (cdr info) (> numargs (cdr info)))
        !           156:       then (if (eq class 'hard)
        !           157:              then (comp-err
        !           158:                      (difference numargs (cdr info))
        !           159:                      " too many argument(s) given in this expression:" N
        !           160:                      v-form)
        !           161:              else (comp-warn
        !           162:                      (difference numargs (cdr info))
        !           163:                      " too many argument(s) given in this expression:" N
        !           164:                      v-form))))
        !           165: 
        !           166: ;--- d-pushargs :: compile and push a list of expressions
        !           167: ;      - exps : list of expressions
        !           168: ; compiles and stacks a list of expressions
        !           169: ;
        !           170: (defun d-pushargs (args)
        !           171:    (if args then
        !           172:        (do ((ll args (cdr ll))
        !           173:            (g-loc 'stack)
        !           174:            (g-cc nil)
        !           175:            (g-ret nil))
        !           176:           ((null ll))
        !           177:           (d-exp (car ll))
        !           178:           (push nil g-locs)
        !           179:           (incr g-loccnt))))
        !           180: 
        !           181: ;--- d-cxxr :: split apart a cxxr function name
        !           182: ;      - name : a possible cxxr function name
        !           183: ; returns the a's and d's between c and r in reverse order, or else
        !           184: ;  returns nil if this is not a cxxr name
        !           185: ;
        !           186: (defun d-cxxr (name)
        !           187:   (let ((expl (explodec name)))
        !           188:        (if (eq 'c (car expl))                  ; must begin with c
        !           189:           then (do ((ll (cdr expl) (cdr ll))
        !           190:                     (tmp)
        !           191:                     (res))
        !           192:                    (nil)
        !           193:                    (setq tmp (car ll))
        !           194:                    (if (null (cdr ll)) 
        !           195:                        then (if (eq 'r tmp)    ; must end in r
        !           196:                                 then (return res)
        !           197:                                 else (return nil))
        !           198:                     elseif (or (eq 'a tmp)     ; and contain only a's and d's
        !           199:                                (eq 'd tmp))
        !           200:                        then (setq res (cons tmp res))
        !           201:                     else (return nil))))))
        !           202: 
        !           203: 
        !           204: ;--- d-callbig :: call a local, global or bcd  function        
        !           205: ;
        !           206: ; name is the name of the function we are to call
        !           207: ; args are the arguments to evaluate and call the function with
        !           208: ; if bcdp is t then we are calling through a binary object and thus
        !           209: ; name is ingored.
        !           210: ;
        !           211: #+for-vax
        !           212: (defun d-callbig (name args bcdp)
        !           213:   (let ((tmp (get name g-localf))
        !           214:        c)
        !           215:        (forcecomment `(calling ,name))
        !           216:        (if (d-dotailrecursion name args) thenret
        !           217:         elseif tmp then ;-- local function call
        !           218:                    (d-pushargs args)
        !           219:                    (e-quick-call (car tmp))
        !           220:                    (setq g-locs (nthcdr (setq c (length args)) g-locs))
        !           221:                    (setq g-loccnt (- g-loccnt c))
        !           222:        else (if bcdp           ;-- bcdcall
        !           223:                 then (d-pushargs args)
        !           224:                      (setq c (length args))
        !           225:                      (d-bcdcall c)
        !           226:               elseif fl-tran   ;-- transfer table linkage
        !           227:                 then (d-pushargs args)
        !           228:                    (setq c (length args))
        !           229:                    (d-calltran name c)
        !           230:                    (putprop name t g-stdref)   ; remember we've called this
        !           231:               else ;--- shouldn't get here
        !           232:                    (comp-err " bad args to d-callbig : "
        !           233:                              (or name args)))
        !           234:             (setq g-locs (nthcdr c g-locs))
        !           235:             (setq g-loccnt (- g-loccnt c)))
        !           236:        (d-clearreg)))
        !           237: 
        !           238: #+for-68k
        !           239: (defun d-callbig (name args bcdp)
        !           240:   (let ((tmp (get name g-localf))
        !           241:        c)
        !           242:        (forcecomment `(calling ,name))
        !           243:        (if (d-dotailrecursion name args)
        !           244:           thenret
        !           245:         elseif tmp then ;-- local function call
        !           246:                    (d-pushargs args)
        !           247:                    (setq c (length args))
        !           248:                    (if (null $global-reg$) then
        !           249:                        (e-write3 'lea `(,(* -4 c) #.np-reg) 'a5)
        !           250:                        (e-move 'a5 '#.lbot-sym)
        !           251:                        (e-move '#.np-reg '#.np-sym))
        !           252:                    (e-quick-call (car tmp))
        !           253:                    (setq g-locs (nthcdr c g-locs))
        !           254:                    (setq g-loccnt (- g-loccnt c))
        !           255:        else (if bcdp           ;-- bcdcall
        !           256:                 then (d-pushargs args)
        !           257:                      (setq c (length args))
        !           258:                      (d-bcdcall c)
        !           259:               elseif fl-tran   ;-- transfer table linkage
        !           260:                 then (d-pushargs args)
        !           261:                    (setq c (length args))
        !           262:                    (d-calltran name c)
        !           263:                    (putprop name t g-stdref)   ; remember we've called this
        !           264:               else ;--- shouldn't get here
        !           265:                    (comp-err " bad args to d-callbig : "
        !           266:                              (or name args)))
        !           267:             (setq g-locs (nthcdr c g-locs))
        !           268:             (setq g-loccnt (- g-loccnt c)))
        !           269:        (d-clearreg)))
        !           270: 
        !           271: ;--- d-calltran :: call a function through the transfer table
        !           272: ;  name - name of function to call
        !           273: ;  c - number of arguments to the function
        !           274: ;
        !           275: #+for-vax
        !           276: (defun d-calltran (name c)
        !           277:    (if $global-reg$
        !           278:        then (e-write3 'movab `(,(* -4 c) #.np-reg) '#.lbot-reg)
        !           279:        else (e-write3 'movab `(,(* -4 c) #.np-reg) '#.lbot-sym)
        !           280:            (e-move '#.np-reg '#.np-sym))
        !           281:    (e-write3 'calls '$0 (concat "*trantb+" (d-tranloc name)))
        !           282:    (if $global-reg$
        !           283:        then (e-move '#.lbot-reg '#.np-reg)
        !           284:        else (e-write3 'movab `(,(* -4 c) #.np-reg) '#.np-reg)))
        !           285: 
        !           286: #+for-68k
        !           287: (defun d-calltran (name c)
        !           288:    (if $global-reg$
        !           289:        then (e-write3 'lea `(,(* -4 c) #.np-reg) 'a5)
        !           290:            (e-move 'a5 '#.lbot-reg)
        !           291:        else (e-write3 'lea `(,(* -4 c) #.np-reg) 'a5)
        !           292:            (e-move 'a5 '#.lbot-sym)
        !           293:            (e-move '#.np-reg '#.np-sym))
        !           294:    (e-move (concat "trantb+" (d-tranloc name)) 'a5)
        !           295:    (e-quick-call '(0 a5))
        !           296:    (if $global-reg$
        !           297:        then (e-move '#.lbot-reg '#.np-reg)
        !           298:        else (e-write3 'lea `(,(* -4 c) #.np-reg) '#.np-reg)))
        !           299: 
        !           300: ;--- d-calldirect :: call a function directly
        !           301: ;
        !           302: ;  name - name of a function in the C code (known about by fasl)
        !           303: ;    c  - number of args
        !           304: ;
        !           305: #+for-vax
        !           306: (defun d-calldirect (name c)
        !           307:    (if $global-reg$
        !           308:        then (e-write3 'movab `(,(* -4 c) #.np-reg) '#.lbot-reg)
        !           309:        else (e-write3 'movab `(,(* -4 c) #.np-reg) '#.lbot-sym)
        !           310:            (e-move '#.np-reg '#.np-sym))
        !           311:    (e-write3 'calls '$0  name)
        !           312:    (if $global-reg$
        !           313:        then (e-move '#.lbot-reg '#.np-reg)
        !           314:        else (e-write3 'movab `(,(* -4 c) #.np-reg) '#.np-reg)))
        !           315: 
        !           316: #+for-68k
        !           317: (defun d-calldirect (name c)
        !           318:    (if $global-reg$
        !           319:        then (e-write3 'lea `(,(* -4 c) #.np-reg) 'a5)
        !           320:            (e-move 'a5 '#.lbot-reg)
        !           321:        else (e-write3 'lea `(,(* -4 c) #.np-reg) 'a5)
        !           322:            (e-move 'a5 '#.lbot-sym)
        !           323:            (e-move '#.np-reg '#.np-sym))
        !           324:    (e-quick-call name)
        !           325:    (if $global-reg$
        !           326:        then (e-move '#.lbot-reg '#.np-reg)
        !           327:        else (e-write3 'lea `(,(* -4 c) #.np-reg) '#.np-reg)))
        !           328: 
        !           329: ;--- d-bcdcall :: call a function through a binary data object
        !           330: ;  
        !           331: ; at this point the stack contains n-1 arguments and a binary object which
        !           332: ; is the address of the compiled lambda expression to go to.  We set
        !           333: ; up lbot right above the binary on the stack and call the function.
        !           334: ;
        !           335: #+for-vax
        !           336: (defun d-bcdcall (n)
        !           337:    (if $global-reg$
        !           338:        then (e-write3 'movab `(,(* -4 (- n 1)) #.np-reg) '#.lbot-reg)
        !           339:        else (e-write3 'movab `(,(* -4 (- n 1)) #.np-reg) '#.lbot-sym)
        !           340:            (e-move '#.np-reg '#.np-sym))
        !           341:    (e-move  `(* ,(* -4 n) #.np-reg) 'r0)    ;get address to call to
        !           342:    (e-write3 'calls '$0 "(r0)")
        !           343:    (if $global-reg$
        !           344:        then (e-write3 'movab '(-4 #.lbot-reg) '#.np-reg)
        !           345:        else (e-write3 'movab `(,(* -4 n) #.np-reg) '#.np-reg)))
        !           346: 
        !           347: #+for-68k
        !           348: (defun d-bcdcall (n)
        !           349:    (if $global-reg$
        !           350:        then (e-write3 'lea `(,(* -4 (- n 1)) #.np-reg) 'a5)
        !           351:            (e-move 'a5 '#.lbot-reg)
        !           352:        else (e-write3 'lea `(,(* -4 (- n 1)) #.np-reg) 'a5)
        !           353:            (e-move 'a5 '#.lbot-sym)
        !           354:            (e-move '#.np-reg '#.np-sym))
        !           355:    (e-move `(,(* -4 n) #.np-reg) 'a5)  ; get address to call to
        !           356:    (e-move `(0 a5) 'a5)
        !           357:    (e-quick-call '(0 a5))
        !           358:    (if $global-reg$
        !           359:        then (e-move '#.lbot-reg 'a5)
        !           360:            (e-write3 'lea '(-4 a5) '#.np-reg)
        !           361:        else (e-write3 'lea `(,(* -4 n) #.np-reg) '#.np-reg)))
        !           362: 
        !           363: ;--- d-dotailrecursion :: do tail recursion if possible
        !           364: ; name - function name we are to call
        !           365: ; args - arguments to give to function
        !           366: ;
        !           367: ; return t iff we were able to do tail recursion
        !           368: ; We can do tail recursion if:
        !           369: ;  g-ret is set indicating that the result of this call will be returned
        !           370: ;       as the value of the function we are compiling
        !           371: ;  the function we are calling, name, is the same as the function we are
        !           372: ;       compiling, g-fname
        !           373: ;  there are no variables shallow bound, since we would have to unbind
        !           374: ;       them, which may cause problems in the function.
        !           375: ;
        !           376: (defun d-dotailrecursion (name args)
        !           377:    (prog (nargs lbot)
        !           378:        (if (null (and g-ret
        !           379:                      (eq name g-fname)
        !           380:                      (do ((loccnt 0)
        !           381:                           (ll g-locs (cdr ll)))
        !           382:                          ((null ll) (return t))
        !           383:                          (if (dtpr (car ll))
        !           384:                              then (if (or (eq 'catcherrset (caar ll))
        !           385:                                           (greaterp (cdar ll) 0))
        !           386:                                       then (return nil))
        !           387:                              else (incr loccnt)))))
        !           388:           then (return nil))
        !           389: 
        !           390:        (makecomment '(tail merging))
        !           391:        (comp-note g-fname ": Tail merging being done: " v-form)
        !           392: 
        !           393:        (setq nargs (length args))
        !           394:        
        !           395:        ; evalate the arguments, putting them above the arguments to the
        !           396:        ; function we are executing...
        !           397:        (let ((g-locs g-locs)
        !           398:             (g-loccnt g-loccnt))
        !           399:           (d-pushargs args))
        !           400: 
        !           401:        (if $global-reg$
        !           402:           then (setq lbot #+for-68k 'a5 #+for-vax '#.lbot-reg)
        !           403:                #+for-68k (e-move '#.lbot-reg lbot)
        !           404:           else (setq lbot #+for-68k 'a5 #+for-vax '#.fixnum-reg)
        !           405:                (e-move '#.lbot-sym lbot))
        !           406: 
        !           407:        ; setup lbot-reg to point to the bottom of the original
        !           408:        ;args...
        !           409:        (if (eq 'lexpr g-ftype)
        !           410:           then #+for-vax
        !           411:                (e-write4 'ashl '($ 2) '(* -4 #.olbot-reg) lbot)
        !           412:                #+for-68k
        !           413:                (progn
        !           414:                 (d-regused 'd6)
        !           415:                 (e-move '(* -4 #.olbot-reg) 'd6)
        !           416:                 (e-write3 'asll '($ 2) 'd6)
        !           417:                 (e-move 'd6 lbot))
        !           418:                (e-sub lbot '#.olbot-reg)
        !           419:                (e-sub3 '($ 4) '#.olbot-reg lbot)
        !           420:           else (e-move '#.olbot-reg lbot))
        !           421: 
        !           422:        ; copy the new args down into the place of the original ones...
        !           423:        (do ((i nargs (1- i))
        !           424:            (off-top (* nargs -4) (+ off-top 4))
        !           425:            (off-bot 0 (+ off-bot 4)))
        !           426:           ((zerop i))
        !           427:           (e-move `(,off-top #.np-reg) `(,off-bot ,lbot)))
        !           428: 
        !           429:        ; setup np for the coming call...
        !           430:        (e-add3 `($ ,(* 4 nargs)) lbot '#.np-reg)
        !           431: 
        !           432:        (e-goto g-topsym)
        !           433:        ;return t to indicate that tailrecursion was successful
        !           434:        (return t)))

unix.superglobalmegacorp.com

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