Annotation of 43BSD/ucb/lisp/lisplib/pp.l, revision 1.1.1.1

1.1       root        1: (setq rcs-pp-
                      2:    "$Header: /usr/lib/lisp/RCS/pp.l,v 1.2 83/08/15 22:27:54 jkf Exp $")
                      3: 
                      4: ;;
                      5: ;; pp.l                                        -[Mon Aug 15 10:52:13 1983 by jkf]-
                      6: ;;
                      7: ;; pretty printer for franz lisp
                      8: ;;
                      9: 
                     10: (declare (macros t))
                     11: 
                     12: (declare (special poport pparm1 pparm2 lpar rpar form linel))
                     13: ; (declare (localf $patom1 $prd1 $prdf charcnt condclosefile))
                     14: 
                     15: ; =======================================
                     16: ; pretty printer top level routine pp
                     17: ;
                     18: ;
                     19: ; calling form- (pp arg1 arg2 ... argn)
                     20: ; the args may be names of functions, atoms with associated values
                     21: ; or output descriptors.
                     22: ; if argi is:
                     23: ;    an atom - it is assumed to be a function name, if there is no
                     24: ;             function property associated with it,then it is assumed
                     25: ;              to be an atom with a value
                     26: ;    (P port)-  port is the output port where the results of the
                     27: ;              pretty printing will be sent.
                     28: ;              poport is the default if no (P port) is given.
                     29: ;    (F fname)- fname is  a file name to write the results in
                     30: ;    (A atmname) - means, treat this as an atom with a value, dont
                     31: ;              check if it is the name of a function.
                     32: ;    (E exp)-   evaluate exp without printing anything
                     33: ;    other -   pretty-print the expression as is - no longer an error
                     34: ;
                     35: ;    Also, rather than printing only a function defn or only a value, we will
                     36: ;    let prettyprops decide which props to print.  Finally, prettyprops will
                     37: ;    follow the CMULisp format where each element is either a property
                     38: ;    or a dotted pair of the form (prop . fn) where in order to print the
                     39: ;    given property we call (fn id val prop).  The special properties
                     40: ;    function and value are used to denote those "properties" which
                     41: ;    do not actually appear on the plist.
                     42: ;
                     43: ; [history of this code: originally came from Harvard Lisp, hacked to
                     44: ; work under franz at ucb, hacked to work at cmu and finally rehacked
                     45: ; to work without special cmu macros]
                     46: 
                     47: (declare (special $outport$ $fileopen$ prettyprops))
                     48: 
                     49: (setq prettyprops '((comment . pp-comment)
                     50:                    (function . pp-function)
                     51:                    (value . pp-value)))
                     52: 
                     53: ; printret is like print yet it returns the value printed, this is used
                     54: ; by pp                
                     55: (def printret
                     56:   (macro ($l$)
                     57:         `(progn (print ,@(cdr $l$)) ,(cadr $l$))))
                     58: 
                     59: (def pp
                     60:   (nlambda ($xlist$)
                     61:        (prog ($gcprint $outport$ $cur$ $fileopen$ $prl$ $atm$)
                     62: 
                     63:              (setq $gcprint nil)                       ; don't print
                     64:                                                        ; gc messages in pp.
                     65: 
                     66:              (setq $outport$ poport)                   ; default port
                     67:              ; check if more to do, if not close output file if it is
                     68:              ; open and leave
                     69: 
                     70: 
                     71:    toploop    (cond ((null (setq $cur$ (car $xlist$)))
                     72:                     (condclosefile)
                     73:                     (terpr)
                     74:                     (return t)))
                     75: 
                     76:              (cond ((dtpr $cur$)
                     77:                     (cond ((equal 'P (car $cur$))      ; specifying a port
                     78:                            (condclosefile)             ; close file if open
                     79:                            (setq $outport$ (eval (cadr $cur$))))
                     80: 
                     81:                           ((equal 'F (car $cur$))      ; specifying a file
                     82:                            (condclosefile)             ; close file if open
                     83:                            (setq $outport$ (outfile (cadr $cur$))
                     84:                                  $fileopen$ t))
                     85: 
                     86:                                                
                     87:                           ((equal 'E (car $cur$))
                     88:                            (eval (cadr $cur$)))
                     89: 
                     90:                           (t (pp-form $cur$ $outport$)))       ;-DNC inserted
                     91:                     (go botloop)))
                     92: 
                     93: 
                     94:       (mapc (function
                     95:             (lambda (prop)
                     96:                     (prog (printer)
                     97:                           (cond ((dtpr prop)
                     98:                                  (setq printer (cdr prop))
                     99:                                  (setq prop (car prop)))
                    100:                                 (t (setq printer 'pp-prop)))
                    101:                           (cond ((eq 'value prop)
                    102:                                  (and (boundp $cur$)
                    103:                                       (apply printer
                    104:                                              (list $cur$
                    105:                                                    (eval $cur$)
                    106:                                                    'value))
                    107:                                       (terpr $outport$)))
                    108:                                 ((eq 'function prop)
                    109:                                  (and (getd $cur$)
                    110:                                       (cond ((not (bcdp (getd $cur$)))
                    111:                                              (apply printer
                    112:                                                     (list $cur$
                    113:                                                           (getd $cur$)
                    114:                                                           'function)))
                    115:                                             ; restore message about
                    116:                                             ; bcd since otherwise you
                    117:                                             ; just get nothing and
                    118:                                             ; people were complaining.
                    119:                                             ; - dhl.
                    120:                                             #-cmu
                    121:                                             (t
                    122:                                              (msg N 
                    123:                                                   "pp: function " 
                    124:                                                   (or $cur$)
                    125:                                                   " is machine coded (bcd) "))
                    126:                                             )
                    127:                                       (terpri $outport$)))
                    128:                                 ((get $cur$ prop)
                    129:                                  (apply printer
                    130:                                         (list $cur$
                    131:                                               (get $cur$ prop)
                    132:                                               prop))
                    133:                                  (terpri $outport$))))))
                    134:            prettyprops)
                    135: 
                    136: 
                    137:  botloop      (setq $xlist$ (cdr $xlist$))
                    138: 
                    139:              (go toploop))))
                    140: 
                    141: (setq pparm1 50 pparm2 100)
                    142: 
                    143: ;   -DNC These "prettyprinter parameters" are used to decide when we should
                    144: ;      quit printing down the right margin and move back to the left -
                    145: ;      Do it when the leftmargin > pparm1 and there are more than pparm2
                    146: ;      more chars to print in the expression
                    147: 
                    148: ; cmu prefers dv instead of setq
                    149: 
                    150: #+cmu
                    151: (def pp-value (lambda (i v p)
                    152:                      (terpri $outport$)
                    153:                      (pp-form (list 'dv i v) $outport$)))
                    154: 
                    155: #-cmu
                    156: (def pp-value (lambda (i v p)
                    157:                      ;;(terpr $outport$) ;; pp-form does an initial terpr.
                    158:                      ;;                        we don't need two.
                    159:                      (pp-form `(setq ,i ',v) $outport$)))
                    160: 
                    161: (def pp-function (lambda (i v p)
                    162:                         #+cmu (terpri $outport$)
                    163:                         ;;
                    164:                         ;; add test for traced functions and don't
                    165:                         ;; print the trace mess, just the original
                    166:                         ;; function.  - dhl.
                    167:                         ;;
                    168:                         ;; this test might belong in the main pp
                    169:                         ;; loop but fits in easily here. - dhl
                    170:                         ;;
                    171:                         (cond ((and (dtpr v)
                    172:                                     (dtpr (cadr v))
                    173:                                     (memq (caadr v)
                    174:                                           '(T-nargs T-arglist))
                    175:                                     (cond ((bcdp (get i 'trace-orig-fcn))
                    176:                                            #-cmu
                    177:                                            (msg N 
                    178:                                                 "pp: function " 
                    179:                                                 (or i) 
                    180:                                                 " is machine coded (bcd) ")
                    181:                                            t)
                    182:                                           (t (pp-form 
                    183:                                               (list 'def i 
                    184:                                                     (get i 'trace-orig-fcn))
                    185:                                               $outport$)
                    186:                                              t))))
                    187:                               ; this function need to return t, but
                    188:                               ; pp-form returns nil sometimes.
                    189:                               (t (pp-form (list 'def i v) $outport$)
                    190:                                  t))))
                    191: 
                    192: (def pp-prop (lambda (i v p)
                    193:                     #+cmu (terpri $outport$)
                    194:                     (pp-form (list 'defprop i v p) $outport$)))
                    195: 
                    196: (def condclosefile 
                    197:   (lambda nil
                    198:          (cond ($fileopen$
                    199:                 (terpr $outport$)
                    200:                 (close $outport$)
                    201:                 (setq $fileopen$ nil)))))
                    202: 
                    203: ;
                    204: ; these routines are meant to be used by pp but since
                    205: ; some people insist on using them we will set $outport$ to nil
                    206: ; as the default
                    207: (setq $outport$ nil)
                    208: 
                    209: 
                    210: 
                    211: (defun pp-form (value &optional ($outport$ poport oport-p) (lmar 0))
                    212:  ($prdf value lmar 0))
                    213: 
                    214: ; this is for compatability with old code, will remove soon -- jkf
                    215: (def $prpr (lambda (x) (pp-form x $outport$)))
                    216: 
                    217: 
                    218: 
                    219: (declare (special rmar))       ; -DNC this used to be m - I've tried to
                    220:                                ; to fix up the pretty printer a bit.  It
                    221:                                ; used to mess up regularly on (a b .c) types
                    222:                                ; of lists.  Also printmacros have been added.
                    223: 
                    224: (def $prdf
                    225:   (lambda (l lmar rmar)
                    226:     (prog nil
                    227: ;
                    228: ;                      - DNC - Here we try to fix the tendency to print a
                    229: ;                        thin column down the right margin by allowing it
                    230: ;                        to move back to the left if necessary.
                    231: ;
                    232:          (cond ((and (>& lmar pparm1) (>& (flatc l (1+ pparm2)) pparm2))
                    233:                 (terpri $outport$)
                    234:                 (patom "; <<<<< start back on the left <<<<<" $outport$)
                    235:                 ($prdf l 5 0)
                    236:                 (terpri $outport$)
                    237:                 (patom "; >>>>> continue on the right >>>>>" $outport$)
                    238:                 (terpri $outport$)
                    239:                 (return nil)))
                    240:           (tab lmar $outport$)
                    241:      a    (cond ((and (dtpr l)
                    242:                      (atom (car l))
                    243:                      (or (and (get (car l) 'printmacro)
                    244:                               (funcall (get (car l) 'printmacro)
                    245:                                        l lmar rmar))
                    246:                          (and (get (car l) 'printmacrochar)
                    247:                               (printmacrochar (get (car l) 'printmacrochar)
                    248:                                               l lmar rmar))))
                    249:                 (return nil))
                    250: ;
                    251: ;                              -DNC - a printmacro is a lambda (l lmar rmar)
                    252: ;                              attached to the atom.  If it returns nil then
                    253: ;                              we assume it did not apply and we continue.
                    254: ;                              Otherwise we assume it did the job.
                    255: ;
                    256:                 ((or (not (dtpr l))
                    257: ;                    (*** at the moment we just punt hunks etc)
                    258:                      (and (atom (car l)) (atom (cdr l))))
                    259:                  (return (printret l $outport$)))
                    260:                 ((<& (+ rmar (flatc l (charcnt $outport$)))
                    261:                    (charcnt $outport$))
                    262:                 ;
                    263:                 ;      This is just a heuristic - if print can fit it in then figure that
                    264: ;      the printmacros won't hurt.  Note that despite the pretentions there
                    265: ;      is no guarantee that everything will fit in before rmar - for example
                    266: ;      atoms (and now even hunks) are just blindly printed.    - DNC
                    267: ;
                    268:                  (printaccross l lmar rmar))
                    269:                 ((and ($patom1 lpar)
                    270:                       (atom (car l))
                    271:                       (not (atom (cdr l)))
                    272:                       (not (atom (cddr l))))
                    273:                  (prog (c)
                    274:                        (printret (car l) $outport$)
                    275:                        ($patom1 '" ")
                    276:                        (setq c (nwritn $outport$))
                    277:                   a    ($prd1 (cdr l) c)
                    278:                        (cond
                    279:                         ((not (atom (cdr (setq l (cdr l)))))
                    280:                          (terpr $outport$)
                    281:                          (go a)))))
                    282:                 (t
                    283:                  (prog (c)
                    284:                        (setq c (nwritn $outport$))
                    285:                   a    ($prd1 l c)
                    286:                        (cond
                    287:                         ((not (atom (setq l (cdr l))))
                    288:                          (terpr $outport$)
                    289:                          (go a))))))
                    290:      b    ($patom1 rpar))))
                    291: 
                    292: (def $prd1
                    293:   (lambda (l n)
                    294:     (prog nil
                    295:           ($prdf (car l)
                    296:                  n
                    297:                  (cond ((null (setq l (cdr l))) (|1+| rmar))
                    298:                        ((atom l) (setq n nil) (plus 4 rmar (pntlen l)))
                    299:                        (t rmar)))
                    300:           (cond
                    301:            ((null n) ($patom1 '" . ") (return (printret l $outport$))))
                    302: ;         (*** setting n is pretty disgusting)
                    303: ;         (*** the last arg to $prdf is the space needed for the suffix)
                    304: ;              ;Note that this is still not really right - if the prefix
                    305: ;              takes several lines one would like to use the old rmar 
                    306: ;              until the last line where the " . mumble)" goes.
                    307:        )))
                    308: 
                    309: ; -DNC here's the printmacro for progs - it replaces some hackery that
                    310: ; used to be in the guts of $prdf.
                    311: 
                    312: (def printprog
                    313:   (lambda (l lmar rmar)
                    314:     (prog (col)
                    315:           (cond ((cdr (last l)) (return nil)))
                    316:           (setq col (add1 lmar))
                    317:           (princ '|(| $outport$)
                    318:           (princ (car l) $outport$)
                    319:           (princ '| | $outport$)
                    320:           (print (cadr l) $outport$)
                    321:           (mapc '(lambda (x)
                    322:                         (cond ((atom x)
                    323:                                (tab col $outport$)
                    324:                                (print x $outport$))
                    325:                           (t ($prdf x (+ lmar 6) rmar))))
                    326:                (cddr l))
                    327:           (princ '|)| $outport$)
                    328:           (return t))))
                    329: 
                    330: (putprop 'prog 'printprog 'printmacro)
                    331: 
                    332: ;;
                    333: ;;     simpler version which
                    334: ;;     should look nice for lambda's also.(inside mapcar's) -dhl
                    335: ;;
                    336: (defun print-lambda (l lmar rmar)
                    337:   (prog (col)
                    338:        (cond ((cdr (last l)) (return nil)))
                    339:        (setq col (add1 lmar))
                    340:        (princ '|(| $outport$)
                    341:               (princ (car l) $outport$)
                    342:               (princ '| | $outport$)
                    343:               (print (cadr l) $outport$)
                    344:               (let ((c (cond ((eq (car l) 'lambda)
                    345:                               8)
                    346:                              (t 9))))
                    347:                    (mapc '(lambda (x)
                    348:                                   ($prdf x (+ lmar c) rmar))
                    349:                          (cddr l)))
                    350:               (princ '|)| $outport$)
                    351:        (terpr $outport$)
                    352:        (tab lmar $outport$)
                    353:        (return t)))
                    354: 
                    355: (putprop 'lambda 'print-lambda 'printmacro)
                    356: (putprop 'nlambda 'print-lambda 'printmacro)
                    357: 
                    358: ; Here's the printmacro for def.  The original $prdf had some special code
                    359: ; for lambda and nlambda.
                    360: 
                    361: (def printdef
                    362:   (lambda (l lmar rmar)
                    363:     (cond ((and (zerop lmar)           ; only if we're really printing a defn
                    364:                 (zerop rmar)
                    365:                 (cadr l)
                    366:                 (atom (cadr l))
                    367:                 (dtpr (caddr l))
                    368:                 (null (cdddr l))
                    369:                 (memq (caaddr l) '(lambda nlambda macro lexpr))
                    370:                 (null (cdr (last (caddr l)))))
                    371:            (princ '|(| $outport$)
                    372:            (princ 'def $outport$)
                    373:            (princ '| | $outport$)
                    374:            (princ (cadr l) $outport$)
                    375:            (terpri $outport$)
                    376:            (princ '|  (| $outport$)
                    377:            (princ (caaddr l) $outport$)
                    378:            (princ '| | $outport$)
                    379:            (princ (cadaddr l) $outport$)
                    380:            (terpri $outport$)
                    381:            (mapc  '(lambda (x) ($prdf x 4 0)) (cddaddr l))
                    382:            (princ '|))| $outport$)
                    383:            t))))
                    384: 
                    385: (putprop 'def 'printdef 'printmacro)
                    386: 
                    387: ; There's a version of this hacked into the printer (where it don't belong!)
                    388: ; Note that it must NOT apply to things like (quote a b).
                    389: 
                    390: ;
                    391: ; adding printmacrochar so that it can be used by other read macros
                    392: ; which create things of the form (tag lisp-expr) like quote does,
                    393: ; I know this is restrictive but it is helpful in the frl source. - dhl.
                    394: ;
                    395: ;
                    396: 
                    397: (def printmacrochar
                    398:   (lambda (macrochar l lmar rmar)
                    399:     (cond ((or (null (cdr l)) (cddr l)) nil)
                    400:           (t (princ macrochar $outport$) 
                    401:              ($prdf (cadr l) (add1 lmar) rmar)
                    402:              t))))
                    403: 
                    404: (putprop 'quote '|'| 'printmacrochar)
                    405: 
                    406: (def printaccross
                    407:   (lambda (l lmar rmar)
                    408:     (prog nil
                    409: ;         (*** this is needed to make sure the printmacros are executed)
                    410:           (princ '|(| $outport$)
                    411:      l:   (cond ((null l))
                    412:                 ((atom l) (princ '|. | $outport$) (princ l $outport$))
                    413:                 (t ($prdf (car l) (nwritn $outport$) rmar)
                    414:                    (setq l (cdr l))
                    415:                    (cond (l (princ '| | $outport$)))
                    416:                    (go l:))))))
                    417: 

unix.superglobalmegacorp.com

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