home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacHaskell 2.2 / printers / util.scm < prev   
Encoding:
Text File  |  1994-09-27  |  5.4 KB  |  215 lines  |  [TEXT/CCL2]

  1. ;;; util.scm -- utilities for printing AST structures
  2. ;;;
  3. ;;; author :  Sandra Loosemore
  4. ;;; date   :  15 Jan 1992
  5. ;;;
  6. ;;;
  7.  
  8.  
  9. ;;; The AST syntax printers are only used if this variable is true.
  10.  
  11. (define *print-ast-syntax* '#t)
  12.  
  13.  
  14. ;;; Here's a macro for defining AST printers.
  15.  
  16. (define-syntax (define-ast-printer type lambda-list . body)
  17.   (let ((printer  (symbol-append 'write- type)))
  18.     `(begin
  19.        (define (,printer ,@lambda-list) ,@body)
  20.        (define-struct-printer ,type ,printer))
  21.     ))
  22.  
  23.  
  24. ;;; This variable controls how much indentation to perform on block
  25. ;;; bodies.
  26.  
  27. (define *print-ast-indent* 2)
  28.  
  29.  
  30. ;;; Begin a logical block with the default indentation.
  31.  
  32. (define-syntax (with-ast-block xp-stuff . body)
  33.   (let ((xp  (car xp-stuff)))
  34.     `(pprint-logical-block (,xp '() "" "")
  35.        (pprint-indent 'block (dynamic *print-ast-indent*) ,xp)
  36.        (pprint-pop)  ; prevents unused variable warning
  37.        ,@body)))
  38.  
  39.  
  40. ;;; Write a space and maybe a fill line break.
  41.  
  42. (define (write-whitespace xp)
  43.   (write-char #\space xp)
  44.   (pprint-newline 'fill xp))
  45.  
  46.  
  47. ;;; Write a space and maybe a mandatory line break.
  48.  
  49. (define (write-newline xp)
  50.   (write-char #\space xp)
  51.   (pprint-newline 'mandatory xp))
  52.  
  53.  
  54.  
  55. ;;; Write a list of things separated by delimiters and maybe
  56. ;;; surrounded by delimiters.
  57.  
  58. (define (write-delimited-list objects xp fn delim prefix suffix)
  59.   (pprint-logical-block (xp '() prefix suffix)
  60.     (do ((objects objects (cdr objects)))
  61.     ((null? objects) '#f)
  62.     (pprint-pop)
  63.     (funcall fn (car objects) xp)
  64.     (when (cdr objects)
  65.       (write-string delim xp)
  66.       (write-whitespace xp)))))
  67.  
  68.  
  69. ;;; Here's a couple common special cases of the above.
  70.  
  71. (define (write-commaized-list objects xp)
  72.   (write-delimited-list objects xp (function write) "," "(" ")"))
  73.  
  74. (define (write-ordinary-list objects xp)
  75.   (write-delimited-list objects xp (function write) "" "" ""))
  76.  
  77.  
  78. ;;; Here's another helper function that's used to implement the layout
  79. ;;; rule.  The layout rule is only used to format output if *print-pretty*
  80. ;;; is true.
  81. ;;; *** should do pprint-indent here?
  82.  
  83. (define (write-layout-rule objects xp fn)
  84.   (pprint-logical-block (xp '()
  85.                 (if (dynamic *print-pretty*) "" "{")
  86.                 (if (dynamic *print-pretty*) "" "}"))
  87.     (do ((objects objects (cdr objects)))
  88.     ((null? objects) '#f)
  89.     (pprint-pop)
  90.     (funcall fn (car objects) xp)
  91.     (when (cdr objects)
  92.       (if (dynamic *print-pretty*)
  93.           (pprint-newline 'mandatory xp)
  94.           (write-string "; " xp))))))
  95.  
  96.  
  97. ;;; This filters a list of decls, removing the recursive marker added by
  98. ;;; dependency analysis.
  99.  
  100. (define (remove-recursive-grouping decls)
  101.   (cond ((null? decls) '())
  102.     ((is-type? 'recursive-decl-group (car decls))
  103.      (append (recursive-decl-group-decls (car decls))
  104.          (remove-recursive-grouping (cdr decls))))
  105.     (else
  106.      (cons (car decls) (remove-recursive-grouping (cdr decls))))))
  107.  
  108. ;;; Write where-decls, using the layout rule if appropriate.
  109.  
  110. (define (write-wheredecls decls xp)
  111.   (when (not (null? decls))
  112.     (write-whitespace xp)
  113.     (write-string "where" xp)
  114.     (write-whitespace xp)
  115.     (write-layout-rule (remove-recursive-grouping decls) xp (function write))))
  116.  
  117.  
  118. ;;; Write an ordinary variable name.
  119.  
  120. (define (write-avarid name xp)
  121.   (write-string (symbol->string name) xp))
  122.   
  123.  
  124. ;;; Constructor name symbols have a funny prefix attached; have to strip
  125. ;;; this off, so can't just print the symbol using write-avarid.
  126.  
  127. (define (write-aconid name xp)
  128.   (let ((s  (symbol->string name)))
  129.     (write-string (substring s 1 (string-length s)) xp)))
  130.  
  131.  
  132. ;;; There are a couple places where conids and varids are mixed up
  133. ;;; together.
  134.  
  135. (define (conid? name)
  136.   (eqv? (string-ref (symbol->string name) 0) #\;))
  137.  
  138. (define (write-varop-conop name xp)
  139.   (if (conid? name)
  140.       (write-conop name xp)
  141.       (write-varop name xp)))
  142.  
  143. (define (write-varid-conid name xp)
  144.   (if (conid? name)
  145.       (write-conid name xp)
  146.       (write-varid name xp)))
  147.  
  148.  
  149.  
  150. ;;; Stuff for writing a variable name as either an operator or an ordinary
  151. ;;; variable ID.  This is necessary because some kinds of symbol names
  152. ;;; default to being operators and others default to being ordinary names.
  153. ;;; Bleah....
  154.  
  155.  
  156. (define (write-varop name xp)
  157.   (if (avarid? name)
  158.       (begin
  159.         (write-char #\` xp)
  160.     (write-avarid name xp)
  161.     (write-char #\` xp))
  162.       (write-avarid name xp)))
  163.  
  164. (define (write-varid name xp)
  165.   (if (avarid? name)
  166.       (write-avarid name xp)
  167.       (begin
  168.         (write-char #\( xp)
  169.     (write-avarid name xp)
  170.     (write-char #\) xp))))
  171.  
  172.  
  173. ;;; This tests for alphabetic rather than lower-case characters
  174. ;;; so that gensym'ed variables with uppercase names don't print funny.
  175.  
  176. (define (avarid? name)
  177.   (let ((ch  (string-ref (symbol->string name) 0)))
  178.     (char-alphabetic? ch)))
  179.  
  180.  
  181. ;;; Similar stuff for doing constructor names.  Moby bleah....
  182.  
  183. (define (write-conop name xp)
  184.   (if (aconid? name)
  185.       (begin
  186.         (write-char #\` xp)
  187.     (write-aconid name xp)
  188.     (write-char #\` xp))
  189.       (write-aconid name xp)))
  190.  
  191. (define (write-conid name xp)
  192.   (if (aconid? name)
  193.       (write-aconid name xp)
  194.       (begin
  195.         (write-char #\( xp)
  196.     (write-aconid name xp)
  197.     (write-char #\) xp))))
  198.  
  199. (define (aconid? name)
  200.   (let ((ch  (string-ref (symbol->string name) 1)))
  201.     (char-upper-case? ch)))
  202.  
  203.  
  204. ;;; These are officially aconid in the syntax, but they aren't
  205. ;;; prefixed so write them using write-avarid instead.  Barf.
  206.  
  207. (define (write-modid name xp)
  208.   (write-avarid name xp))
  209.  
  210. (define (write-tyconid name xp)
  211.   (write-avarid name xp))
  212.  
  213. (define (write-tyclsid name xp)
  214.   (write-avarid name xp))
  215.