Code Search for Developers
 
 
  

pprint.scm from Gdb at Krugle


Show pprint.scm syntax highlighted

;;;; pprint.scm --- pretty-printing objects for CGEN
;;;; Copyright (C) 2005 Red Hat, Inc.
;;;; This file is part of CGEN.
;;;; See file COPYING.CGEN for details.

;;; This file defines a printing function PPRINT, and some hooks to
;;; let you print certain kind of objects in a summary way, and get at
;;; their full values later.

;;; PPRINT is a printer for Scheme objects that prints lists or
;;; vectors that contain shared structure or cycles and prints them in
;;; a finite, legible way.
;;;
;;; Ordinary values print in the usual way:
;;;
;;;   guile> (pprint '(1 #(2 3) 4))
;;;   (1 #(2 3) 4)
;;;
;;; Values can share structure:
;;; 
;;;   guile> (let* ((c (list 1 2))
;;;                 (d (list c c)))
;;;            (write d)
;;;            (newline))
;;;   ((1 2) (1 2))
;;;
;;; In that list, the two instances of (1 2) are actually the same object;
;;; the top-level list refers to the same object twice.
;;;
;;; Printing that structure with PPRINT shows the sharing:
;;; 
;;;   guile> (let* ((c (list 1 2))
;;;                 (d (list c c)))
;;;            (pprint d))
;;;   (#0=(1 2) #0#)
;;;
;;; Here the "#0=" before the list (1 2) labels it with the number
;;; zero.  Then, the "#0#" as the second element of the top-level list
;;; indicates that the object appears here, too, referring to it by
;;; its label.
;;;
;;; If you have several objects that appear more than once, they each
;;; get a separate label:
;;;
;;;   guile> (let* ((a (list 1 2))
;;;                 (b (list 3 4))
;;;                 (c (list a b a b)))
;;;            (pprint c))
;;;   (#0=(1 2) #1=(3 4) #0# #1#)
;;;
;;; Cyclic values just share structure with themselves:
;;;
;;;   guile> (let* ((a (list 1 #f)))
;;;            (set-cdr! a a)
;;;            (pprint a))
;;;   #0=(1 . #0#)
;;;
;;;
;;; PPRINT also consults the function ELIDE? and ELIDED-NAME to see
;;; whether it should print a value in a summary form.  You can
;;; re-define those functions to customize PPRINT's behavior;
;;; cos-pprint.scm defines them to handle COS objects and classes
;;; nicely.
;;;
;;; (ELIDE? OBJ) should return true if OBJ should be elided.
;;; (ELIDED-NAME OBJ) should return a (non-cyclic!) object to be used
;;; as OBJ's abbreviated form.
;;;
;;; PPRINT prints an elided object as a list ($ N NAME), where NAME is
;;; the value returned by ELIDED-NAME to stand for the object, and N
;;; is a number; each elided object gets its own number.  You can refer
;;; to the elided object number N as ($ N).
;;;
;;; For example, if you've loaded CGEN, pprint.scm, and cos-pprint.scm
;;; (you must load cos-pprint.scm *after* loading pprint.scm), you can
;;; print a list containing the <insn> and <ident> classes:
;;;
;;;   guile> (pprint (list <insn> <ident>))
;;;   (($ 1 (class <insn>)) ($ 2 (class <ident>)))
;;;   guile> (class-name ($ 1))
;;;   <insn>
;;;   guile> (class-name ($ 2))
;;;   <ident>
;;;
;;; As a special case, PPRINT never elides the object that was passed
;;; to it directly.  So you can look inside an elided object by doing
;;; just that:
;;;
;;;   guile> (pprint ($ 2))
;;;   #0=#("class" <ident> () ((name #:unbound #f . 0) ...
;;;


;;; A list of elided objects, larger numbers first, and the number of
;;; the first element.
(define elide-table '())
(define elide-table-last -1)

;;; Add OBJ to the elided object list, and return its number.
(define (add-elided-object obj)
  (set! elide-table (cons obj elide-table))
  (set! elide-table-last (+ elide-table-last 1))
  elide-table-last)

;;; Referencing elided objects.
(define ($ n)
  (if (<= 0 n elide-table-last)
      (list-ref elide-table (- elide-table-last n))
      "no such object"))

;;; A default predicate for elision.
(define (elide? obj) #f)

;;; If (elide? OBJ) is true, return some sort of abbreviated list
;;; structure that might be helpful to the user in identifying the
;;; elided object.
;;; A default definition.
(define (elided-name obj) "")

;;; This is a pretty-printer that handles cyclic and shared structure.
(define (pprint original-obj)

  ;; Return true if OBJ should be elided in this call to pprint.
  ;; (We never elide the object we were passed itself.)
  (define (elide-this-call? obj)
    (and (not (eq? obj original-obj))
	 (elide? obj)))

  ;; First, traverse OBJ and build a hash table mapping objects
  ;; referenced more than once to #t, and everything else to #f.
  ;; (Only include entries for objects that might be interior nodes:
  ;; pairs and vectors.)
  (let ((shared
	 ;; Guile's stupid hash tables don't resize the table; the
	 ;; chains just get longer and longer.  So we need a big value here.
	 (let ((seen   (make-hash-table 65521))
	       (shared (make-hash-table 4093)))
	   (define (walk! obj)
	     (if (or (pair? obj) (vector? obj))
		 (if (hashq-ref seen obj)
		     (hashq-set! shared obj #t)
		     (begin
		       (hashq-set! seen obj #t)
		       (cond ((elide-this-call? obj))
			     ((pair? obj) (begin (walk! (car obj))
						 (walk! (cdr obj))))
			     ((vector? obj) (do ((i 0 (+ i 1)))
						 ((>= i (vector-length obj)))
					       (walk! (vector-ref obj i))))
			     (else (error "unhandled interior type")))))))
	   (walk! original-obj)
	   shared)))

    ;; A counter for shared structure labels.
    (define fresh-shared-label
      (let ((n 0))
	(lambda ()
	  (let ((l n))
	    (set! n (+ n 1))
	    l))))

    (define (print obj)
      (print-with-label obj (hashq-ref shared obj)))

    ;; Print an object OBJ, which SHARED maps to L.
    ;; L is always (hashq-ref shared obj), but we have that value handy
    ;; at times, so this entry point lets us avoid looking it up again.
    (define (print-with-label obj label)
      (if (number? label)
	  ;; If we've already visited this object, just print a
	  ;; reference to its label.
	  (map display `("#" ,label "#"))
	  (begin
	    ;; If it needs a label, attach one now.
	    (if (eqv? label #t) (let ((label (fresh-shared-label)))
				  (hashq-set! shared obj label)
				  (map display `("#" ,label "="))))
	    ;; Print the object.
	    (cond ((elide-this-call? obj)
		   (write (list '$ (add-elided-object obj) (elided-name obj))))
		  ((pair? obj) (begin (display "(")
				      (print-tail obj)))
		  ((vector? obj) (begin (display "#(")
					(do ((i 0 (+ i 1)))
					    ((>= i (vector-length obj)))
					  (print (vector-ref obj i))
					  (if (< (+ i 1) (vector-length obj))
					      (display " ")))
					(display ")")))
		  (else (write obj))))))

    ;; Print a pair P as if it were the tail of a list; assume the
    ;; opening paren and any previous elements have been printed.
    (define (print-tail obj)
      (print (car obj))
      (force-output)
      (let ((tail (cdr obj)))
	(if (null? tail)
	    (display ")")
	    ;; We use the dotted pair syntax if the cdr isn't a pair, but
	    ;; also if it needs to be labeled.
	    (let ((tail-label (hashq-ref shared tail)))
	      (if (or (not (pair? tail)) tail-label)
		  (begin (display " . ")
			 (print-with-label tail tail-label)
			 (display ")"))
		  (begin (display " ")
			 (print-tail tail)))))))

    (print original-obj)
    (newline)))





See more files for this project here

Gdb

GDB, the GNU Project debugger, allows you to see what is going on `inside' another program while it executes -- or what another program was doing at the moment it crashed.

Project homepage: http://sources.redhat.com/gdb/
Programming language(s): Assembly,C,C++,Expect
License: other

  cpu/
    arm.cpu
    arm.sim
    arm7.cpu
    fr30.cpu
    fr30.opc
    i960.cpu
    i960.opc
    ia32.cpu
    ia64.cpu
    ip2k.cpu
    ip2k.opc
    iq10.cpu
    iq2000.cpu
    iq2000.opc
    iq2000m.cpu
    m32r.cpu
    m32r.opc
    m68k.cpu
    openrisc.cpu
    openrisc.opc
    play.cpu
    powerpc.cpu
    sh-sid.cpu
    sh-sim.cpu
    sh.cpu
    sh.opc
    sh64-compact.cpu
    sh64-media.cpu
    simplify.inc
    sparc.cpu
    sparc.opc
    sparc32.cpu
    sparc64.cpu
    sparccom.cpu
    sparcfpu.cpu
    thumb.cpu
    xc16x.cpu
    xc16x.opc
    xstormy16.cpu
    xstormy16.opc
  doc/
    Makefile.am
    Makefile.in
    app.texi
    cgen.texi
    credits.texi
    glossary.texi
    internals.texi
    intro.texi
    notes.texi
    opcodes.texi
    pmacros.texi
    porting.texi
    rtl.texi
    running.texi
    sim.texi
    stamp-vti
    version.texi
  slib/
    genwrite.scm
    logical.scm
    pp.scm
    random.scm
    sort.scm
  AUTHORS
  COPYING.CGEN
  ChangeLog
  INSTALL
  Makefile.am
  Makefile.in
  NEWS
  README
  aclocal.m4
  attr.scm
  cgen-doc.scm
  cgen-gas.scm
  cgen-opc.scm
  cgen-sid.scm
  cgen-sim.scm
  cgen-stest.scm
  configure
  configure.in
  cos-pprint.scm
  cos.scm
  decode.scm
  desc-cpu.scm
  desc.scm
  dev.scm
  enum.scm
  gas-test.scm
  gen-all-doc
  gen-all-opcodes
  gen-all-sid
  gen-all-sim
  guile.scm
  hardware.scm
  html.scm
  ifield.scm
  iformat.scm
  insn.scm
  mach.scm
  minsn.scm
  mode.scm
  model.scm
  opc-asmdis.scm
  opc-ibld.scm
  opc-itab.scm
  opc-opinst.scm
  opcodes.scm
  operand.scm
  pgmr-tools.scm
  pmacros.scm
  pprint.scm
  profile.scm
  read.scm
  rtl-c.scm
  rtl-traverse.scm
  rtl.scm
  rtx-funcs.scm
  sem-frags.scm
  semantics.scm
  sid-cpu.scm
  sid-decode.scm
  sid-model.scm
  sid.scm
  sim-arch.scm
  sim-cpu.scm
  sim-decode.scm
  sim-model.scm
  sim-test.scm
  sim.scm
  stamp-h.in
  types.scm
  utils-cgen.scm
  utils-gen.scm
  utils-sim.scm
  utils.scm