home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-18 | 9.3 KB | 117 lines | [TEXT/gamI] |
- ; Graphical display of trees (on a text oriented output device)
- ;
- ; try: (tree-display '((the dog) ate (the cat)))
-
- (define (tree-display tree . optional)
-
- ; how many space characters between branches of tree
- (define tree-spacing 1)
-
- ; print tree with all leaves at bottom level?
- (define leaves-at-bottom? #f)
-
- ; define what a tree is (leaf & internal node) and how to get its components
- (define (leaf? tree) (not (pair? tree)))
- (define (leaf-name tree) (string->symbol "."))
- (define (leaf-info tree) tree)
- (define (int-node-name tree) (string->symbol "."))
- (define (int-node-children tree) (list (car tree) (cdr tree)))
-
- (define (make-augm-leaf width root name info)
- (vector 'leaf width root name info))
-
- (define (make-augm-pad width)
- (vector 'pad width))
-
- (define (make-augm-int-node width root name lpad rpad children)
- (vector #f width root name lpad rpad children))
-
- (define (augm-tree-int-node? x) (not (vector-ref x 0)))
- (define (augm-tree-pad? x) (eq? (vector-ref x 0) 'pad))
- (define (augm-tree-width x) (vector-ref x 1))
- (define (augm-tree-root x) (vector-ref x 2))
- (define (augm-tree-name x) (vector-ref x 3))
- (define (augm-leaf-info x) (vector-ref x 4))
- (define (augm-int-node-lpad x) (vector-ref x 4))
- (define (augm-int-node-rpad x) (vector-ref x 5))
- (define (augm-int-node-children x) (vector-ref x 6))
-
- (define (pad width l)
- (if (> width 0)
- (cons (make-augm-pad width) l)
- l))
-
- (define (field-width x) ; return number of chars in the written repr of `x'
- (cond ((boolean? x) 2)
- ((symbol? x) (string-length (symbol->string x)))
- ((char? x) (case x ((#\space) 7) ((#\newline) 9) (else 3)))
- ((number? x) (string-length (number->string x)))
- ((vector? x) (+ (field-width (vector->list x)) 1))
- ((null? x) 2)
- ((pair? x) (let loop ((l (cdr x)) (w (+ (field-width (car x)) 2)))
- (cond ((null? l)
- w)
- ((pair? l)
- (loop (cdr l) (+ w (field-width (car l)) 1)))
- (else
- (+ w (field-width l) 3)))))
- ((string? x) (let loop ((i (- (string-length x) 1)) (w 2))
- (if (>= i 0)
- (let ((c (string-ref x i)))
- (loop (- i 1)
- (+ w (case c ((#\\ #\") 2) (else 1)))))
- w)))
- (else 0)))
-
- (define (augment-tree tree)
- (if (leaf? tree)
-
- (let* ((name (leaf-name tree))
- (info (leaf-info tree))
- (name-width (field-width name))
- (info-width (field-width info))
- (tree-width (max name-width info-width)))
- (make-augm-leaf tree-width (quotient tree-width 2) name info))
-
- (let* ((children (map augment-tree (int-node-children tree)))
- (name (int-node-name tree))
- (name-width (field-width name))
- (name-left (quotient name-width 2))
- (name-right (- name-width name-left)))
- (if (null? children)
- (make-augm-int-node name-width name-left name 0 0 '())
- (let* ((first-child (car children))
- (last-child (list-ref children (- (length children) 1)))
- (width
- (+ (* (- (length children) 1) tree-spacing)
- (apply + (map augm-tree-width children))))
- (left
- (quotient (+ (- width (augm-tree-width last-child))
- (+ (augm-tree-root first-child)
- (augm-tree-root last-child)))
- 2))
- (right
- (- width left))
- (max-left
- (max name-left left))
- (max-right
- (max name-right right)))
- (make-augm-int-node (+ max-left max-right) max-left name
- (- max-left left) (- max-right right)
- children))))))
-
- (define (any-int-nodes? trees)
- (if (null? trees)
- #f
- (or (augm-tree-int-node? (car trees))
- (any-int-nodes? (cdr trees)))))
-
- (define (all-done? trees)
- (if (null? trees)
- #t
- (and (augm-tree-pad? (car trees))
- (all-done? (cdr trees)))))
-
- (define (seq c n port)
- (if (> n 0)
- (begi