<<>> <<;;; PPrint.scheme>> <<;;; Copyright Ó 1988, 1989, 1991 by Xerox Corporation. All rights reserved.>> <<;;; Last changed by Pavel on August 30, 1989 11:38:37 am PDT>> <<;;; Michael Plass, January 20, 1989 9:45:17 pm PST>> <<;;; NOTE: Eval this syntax definition before trying to compile this file!>> (extend-syntax (define-pretty-printer) ( (define-pretty-printer (name keys ...) (pattern function) ...) (with ((form (gensym)) (port (gensym))) (add-pretty-printer! 'name (lambda (form port) (cond ((syntax-match? '(name keys ...) 'pattern form) (function form port)) ... (else (default-pair-printer form port)))))))) (define pprint-routines '()) ; An AList of pretty-printing routines (define (add-pretty-printer! name function) (let ((lookup (assq name pprint-routines))) (if lookup (set-cdr! lookup function) (set! pprint-routines (cons (cons name function) pprint-routines))) name)) (define (pprint expr . rest) "Prettily print EXPR on the given port (or (CURRENT-OUTPUT-PORT))" (let* ((backing-port (if (null? rest) (current-output-port) (car rest))) (structured-port (if (structured-port? backing-port) backing-port (make-structured-port backing-port)))) (cond ((pair? expr) (if (primitive-syntax-marker? (car expr)) (set! expr (cons (primitive-syntax-marker->symbol (car expr)) (cdr expr)))) (cond ((and (proper-list? expr) (symbol? (car expr)) (assq (car expr) pprint-routines)) => (lambda (lookup) ((cdr lookup) expr structured-port))) (else (default-pair-printer expr structured-port)))) (else (write expr structured-port))))) (define (pprint-file input-name output-name) (let* ((in (open-input-file input-name)) (writer (make-writer)) (out (make-structured-port writer))) (let loop ((form (read in))) (cond ((eof-object? form) (close-output-port out) (write-file-from-writer writer output-name)) (else (pprint form out) (newline out) (newline out) (loop (read in))))))) (define (begin-list p) (begin-structure p) (display "(" p)) (define (end-list p) (display ")" p) (end-structure p)) (define (default-pair-printer expr p) (begin-list p) (pprint (car expr) p) (cond ((not (null? (cdr expr))) (if (pair? (car expr)) (breakpoint p 'always 1 " ") (display " " p)) (begin-structure p) (let loop ((tail (cdr expr))) (cond ((pair? tail) (pprint (car tail) p) (cond ((not (null? (cdr tail))) ; There's more (if (and (pair? (car tail)) (not (memq (caar tail) '(quote unquote unquote-splicing quasiquote)))) (newline p) (breakpoint p 'width 0 " ")) (loop (cdr tail))))) (else (display ". " p) (pprint tail p)))) (end-structure p))) (end-list p)) (define (pprint-vertical-list l p) (begin-structure p) (iterate* ((tail (list-tails l)) (arg (each-time (car tail)))) (pprint arg p) (if (not (null? (cdr tail))) ; There's more (newline p))) (end-structure p)) (define (pprint-bindings bindings p) (cond ((syntax-match? '() '((v e) ...) bindings) (display "(" p) (pprint-vertical-list bindings p) (display ")" p)) (else (default-pair-printer bindings p)))) (define (pprint-binder form p) (begin-list p) (write (car form) p) (display " " p) (pprint-bindings (cadr form) p) (breakpoint p 'look-left 3 " ") (pprint-vertical-list (cddr form) p) (end-list p)) (define-pretty-printer (let) ( (let (binding ...) e1 e2 ...) pprint-binder) ( (let name bindings e1 e2 ...) (lambda (form p) (begin-list p) (display "let " p) (pprint (cadr form) p) (display " " p) (pprint-bindings (caddr form) p) (breakpoint p 'look-left 3 " ") (pprint-vertical-list (cdddr form) p) (end-list p)))) (define-pretty-printer (let*) ( (let* bindings e1 e2 ...) pprint-binder)) (define-pretty-printer (iterate) ( (iterate bindings e1 e2 ...) pprint-binder)) (define-pretty-printer (iterate*) ( (iterate* bindings e1 e2 ...) pprint-binder)) (define-pretty-printer (letrec) ( (letrec bindings e1 e2 ...) pprint-binder)) (define-pretty-printer (if) ( (if pred cons alt) (lambda (form p) (begin-list p) (display "if " p) (pprint (cadr form) p) (breakpoint p 'united 3 " ") (pprint (caddr form) p) (breakpoint p 'united 3 " ") (pprint (cadddr form) p) (end-list p))) ( (if pred cons) (lambda (form p) (begin-list p) (display "if " p) (pprint (cadr form) p) (breakpoint p 'look-left 3 " ") (pprint (caddr form) p) (end-list p)))) (define-pretty-printer (define) ( (define (form ...) e1 e2 ...) (lambda (form p) (begin-list p) (display "define " p) (pprint (cadr form) p) (breakpoint p 'always 3) (pprint-vertical-list (cddr form) p) (end-list p))) ( (define name expr) (lambda (form p) (begin-list p) (display "define " p) (pprint (cadr form) p) (breakpoint p 'width 3 " ") (pprint (caddr form) p) (end-list p)))) (define-pretty-printer (quote) ( (quote e) (lambda (form p) (display "'" p) (pprint (cadr form) p)))) (define-pretty-printer (quasiquote) ( (quasiquote e) (lambda (form p) (display "`" p) (pprint (cadr form) p)))) (define-pretty-printer (unquote) ( (unquote e) (lambda (form p) (display "," p) (pprint (cadr form) p)))) (define-pretty-printer (unquote-splicing) ( (unquote-splicing e) (lambda (form p) (display ",@" p) (pprint (cadr form) p)))) (define-pretty-printer (extend-syntax) ( (extend-syntax (name keys ...) (pattern fender-or-expansion more ...) ...) pprint-extend-syntax)) (define-pretty-printer (define-pretty-printer) ( (define-pretty-printer (name keys ...) (pattern function) ...) pprint-extend-syntax)) (define (pprint-extend-syntax form p) (begin-list p) (write (car form) p) (display " " p) (pprint (cadr form) p) (breakpoint p 'always 3) (begin-structure p) (display "(" p) (pprint-vertical-list (caddr form) p) (display ")" p) (for-each (lambda (clause) (newline p) (newline p) (display "(" p) (pprint-vertical-list clause p) (display ")" p)) (cdddr form)) (end-structure p) (end-list p)) (define-pretty-printer (with) ; For use inside EXTEND-SYNTAX forms ( (with bindings e1 e2 ...) pprint-binder)) (define-pretty-printer (lambda) ( (lambda args e1 e2 ...) (lambda (form p) (begin-list p) (display "lambda " p) (pprint (cadr form) p) (breakpoint p 'width 3 " ") (pprint-vertical-list (cddr form) p) (end-list p)))) (define-pretty-printer (begin) ( (begin e1 e2 ...) (lambda (form p) (begin-list p) (display "begin" p) (breakpoint p 'width 3 " ") (pprint-vertical-list (cdr form) p) (end-list p)))) (define (pprint-call/cc form p) (begin-list p) (write (car form) p) (breakpoint p 'width 3 " ") (pprint-vertical-list (cdr form) p) (end-list p)) (define-pretty-printer (call-with-current-continuation) ( (call-with-current-continuation e) pprint-call/cc)) (define-pretty-printer (call/cc) ( (call/cc e) pprint-call/cc)) (define (pprint-env-ref form p) (define (ok-env-ref? form) (or (symbol? form) (and (syntax-match? '(environment-ref) '(environment-ref env 'name) form) (symbol? (cadr (caddr form))) (ok-env-ref? (cadr form))))) (if (ok-env-ref? form) (let loop ((form form)) (cond ((symbol? form) (write form p)) (else (loop (cadr form)) (display ":" p) (write (cadr (caddr form)) p)))) (default-pair-printer form p))) (define-pretty-printer (environment-ref) ((environment-ref env name) pprint-env-ref))