source: CGBLisp/trunk/src/infix-printer.lisp@ 41

Last change on this file since 41 was 41, checked in by Marek Rychlik, 15 years ago

* empty log message *

File size: 4.3 KB
Line 
1#|
2 $Id: infix-printer.lisp,v 1.18 2002/03/29 14:00:18 marek Exp $
3 *--------------------------------------------------------------------------*
4 | Copyright (C) 1994, Marek Rychlik (e-mail: rychlik@math.arizona.edu) |
5 | Department of Mathematics, University of Arizona, Tucson, AZ 85721 |
6 | |
7 | Everyone is permitted to copy, distribute and modify the code in this |
8 | directory, as long as this copyright note is preserved verbatim. |
9 *--------------------------------------------------------------------------*
10|#
11
12(defpackage "INFIX-PRINTER"
13 (:use "COMMON-LISP"
14 "INFIX" ;for operator-lessp
15 )
16 (:export infix-print))
17
18(in-package "INFIX-PRINTER")
19
20(proclaim '(optimize (speed 0) (debug 3)))
21
22(defun infix-print-separated-list (lst sep stream op print-level
23 &optional (alt-op nil) (alt-sep alt-op)
24 &aux
25 (beg t)
26 (count 0)
27 true-sep)
28 (cond
29 ((endp lst) nil)
30
31 ;; Handle *print-level*
32 ((and (numberp *print-level*)
33 (> print-level *print-level*))
34 (format stream "#"))
35
36 (t
37 (dolist (arg lst)
38 (setf true-sep sep)
39 (incf count)
40
41 (when (and alt-op
42 (> count 1)
43 (consp arg)
44 (eq alt-op (car arg)))
45 (setf arg (cadr arg)
46 true-sep alt-sep))
47 (if beg
48 (setf beg nil)
49 (format stream "~a" true-sep))
50
51 ;; If *print-length* exceeded, print ellipsis
52 (when (and (numberp *print-length*) (> count *print-length*))
53 (format stream "...")
54 (return-from infix-print-separated-list (values)))
55
56 (infix-print arg stream op print-level))))
57 (values))
58
59
60(defun infix-print-arg-list (lst stream print-level
61 &aux (count 0))
62 "Print a comma-separated list"
63
64 ;; Arguments never need to be parenthesized?
65 (dolist (e (butlast lst))
66 (infix-print e stream (1+ print-level))
67 (when (and (numberp *print-length*)
68 (> count *print-length*))
69 (format stream "...")
70 (return-from infix-print-arg-list (values)))
71 (format stream ","))
72 (infix-print (car (last lst)) stream (1+ print-level)))
73
74
75(defun infix-print (expr &optional (stream t) (op nil) (print-level 0))
76 "Print an expression EXPR in infix notation to stream STREAM.
77If OP is not nil, the expression is parenthesized if its operator
78has lower precedence than OP."
79 (cond
80 ;; Handle *print-level*
81 ((and (numberp *print-level*)
82 (> print-level *print-level*))
83 (format stream "#"))
84
85 ;; Null expression is an error
86 ((null expr)
87 (error "Null expression."))
88
89 ;; Atoms are printed using ~A format directive
90 ((atom expr)
91 (format stream "~a" expr))
92
93 ;; Check if the operator of this expression has lower precedence
94 ;; than the surrounding operator, and parenthesize if necessary
95 ((and op (operator-lessp (car expr) op))
96 (format stream "(")
97 (infix-print expr stream nil (1+ print-level))
98 (format stream ")"))
99
100 ;; Unary minus needs special handling
101 ((and (eq (car expr) '-) (endp (cddr expr)))
102 (format stream "-")
103 ;; Print the second element in product context
104 (infix-print (cadr expr) stream '* (1+ print-level)))
105
106 ;; All other operators
107 (t
108 (case (car expr)
109
110 ;; Arithmetic operators
111 ((+ - * /)
112 (infix-print-separated-list
113 (cdr expr)
114 (car expr)
115 stream
116 (car expr)
117 (1+ print-level)
118 (cond ((eq (car expr) '+) '-)
119 ((eq (car expr) '-) '-)
120 (t nil))))
121
122 ;; Exponentials
123 (expt
124 (unless (= (length (cdr expr)) 2)
125 (error "expt must take 2 arguments."))
126 (infix-print-separated-list
127 (cdr expr)
128 '^
129 stream
130 '^
131 (1+ print-level)))
132
133 ;; Assuming function call
134 (otherwise
135 (cond
136 ;; Handle array references
137 ((eq (car expr) 'aref)
138 ;; Special syntax for subscripted variables
139 ;; consistent with the infix package.
140 (format stream "~a[" (cadr expr))
141 (infix-print-separated-list (cddr expr) '\, stream '\, (1+ print-level))
142 (format stream "]"))
143
144 ;; Handle lists
145 ((and (symbolp (car expr))
146 (string= (symbol-name (car expr)) "["))
147 (format stream "[")
148 (infix-print-separated-list (cdr expr) '\, stream '\, (1+ print-level))
149 (format stream "]"))
150
151
152 ;; Handle generic function call syntax
153 (t
154
155 (format stream "~a(" (car expr))
156 (infix-print-arg-list (cdr expr) stream (1+ print-level))
157 (format stream ")")))))))
158 (values))
Note: See TracBrowser for help on using the repository browser.