1
;; Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
3
;; This file is part of GNU Common Lisp, herein referred to as GCL
5
;; GCL is free software; you can redistribute it and/or modify it under
6
;; the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
7
;; the Free Software Foundation; either version 2, or (at your option)
10
;; GCL is distributed in the hope that it will be useful, but WITHOUT
11
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13
;; License for more details.
15
;; You should have received a copy of the GNU Library General Public License
16
;; along with GCL; see the file COPYING. If not, write to the Free Software
17
;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25
(export '(defvar defparameter defconstant))
30
(eval-when (compile) (proclaim '(optimize (safety 2) (space 3))))
31
(eval-when (eval compile) (defun si:clear-compiler-properties (symbol)))
32
(eval-when (eval compile) (setq si:*inhibit-macro-special* nil))
35
(defmacro defvar (var &optional (form nil form-sp) doc-string)
36
`(progn (si:*make-special ',var)
38
`(si:putprop ',var ,doc-string 'variable-documentation))
45
(defmacro defparameter (var form &optional doc-string)
47
`(progn (si:*make-special ',var)
48
(si:putprop ',var ,doc-string 'variable-documentation)
51
`(progn (si:*make-special ',var)
55
(defmacro defconstant (var form &optional doc-string)
57
`(progn (si:*make-constant ',var ,form)
58
(si:putprop ',var ,doc-string 'variable-documentation)
60
`(progn (si:*make-constant ',var ,form)
64
;;; Each of the following macros is also defined as a special form.
65
;;; Thus their names need not be exported.
67
(defmacro and (&rest forms)
70
(let ((x (reverse forms)))
71
(do ((forms (cdr x) (cdr forms))
72
(form (car x) `(if ,(car forms) ,form)))
73
((endp forms) form))))
76
(defmacro or (&rest forms)
79
(let ((x (reverse forms)))
80
(do ((forms (cdr x) (cdr forms))
82
(let ((temp (gensym)))
83
`(let ((,temp ,(car forms)))
84
(if ,temp ,temp ,form)))))
85
((endp forms) form))))
88
(defmacro locally (&rest body) `(let () ,@body))
90
(defmacro loop (&rest body &aux (tag (gensym)))
91
`(block nil (tagbody ,tag (progn ,@body) (go ,tag))))
93
(defmacro defmacro (name vl &rest body)
94
`(si:define-macro ',name (si:defmacro* ',name ',vl ',body)))
96
(defmacro defun (name lambda-list &rest body)
97
(multiple-value-bind (doc decl body)
100
`(progn (setf (get ',name 'si:function-documentation) ,doc)
101
(setf (symbol-function ',name)
102
#'(lambda ,lambda-list
103
,@decl (block ,name ,@body)))
105
`(progn (setf (symbol-function ',name)
106
#'(lambda ,lambda-list
107
,@decl (block ,name ,@body)))
112
(defmacro psetq (&rest args)
113
(do ((l args (cddr l))
116
((endp l) (list* 'let* (reverse bindings) (reverse (cons nil forms))))
118
(let ((sym (gensym)))
119
(push (list sym (cadr l)) bindings)
120
(push (list 'setq (car l) sym) forms)))
125
(defmacro cond (&rest clauses &aux (form nil))
126
(dolist (l (reverse clauses) form)
128
(cond ((endp (cdr l))
131
(let ((sym (gensym)))
132
(setq form `(let ((,sym ,(car l)))
133
(if ,sym ,sym ,form))))))
135
(setq form (if (endp (cddr l))
137
`(progn ,@(cdr l)))))
138
(t (setq form (if (endp (cddr l))
139
`(if ,(car l) ,(cadr l) ,form)
140
`(if ,(car l) (progn ,@(cdr l)) ,form))))))
143
(defmacro when (pred &rest body)
144
`(if ,pred (progn ,@body)))
146
(defmacro unless (pred &rest body)
147
`(if (not ,pred) (progn ,@body)))
151
(defmacro prog (vl &rest body &aux (decl nil))
154
(not (consp (car body)))
155
(not (eq (caar body) 'declare)))
156
`(block nil (let ,vl ,@decl (tagbody ,@body)))
158
(push (car body) decl)
162
(defmacro prog* (vl &rest body &aux (decl nil))
165
(not (consp (car body)))
166
(not (eq (caar body) 'declare)))
167
`(block nil (let* ,vl ,@decl (tagbody ,@body)))
169
(push (car body) decl)
175
(defmacro prog1 (first &rest body &aux (sym (gensym)))
176
`(let ((,sym ,first)) ,@body ,sym))
178
(defmacro prog2 (first second &rest body &aux (sym (gensym)))
179
`(progn ,first (let ((,sym ,second)) ,@body ,sym)))
183
(defmacro multiple-value-list (form)
184
`(multiple-value-call 'list ,form))
186
(defmacro multiple-value-setq (vars form)
187
(do ((vl vars (cdr vl))
191
((endp vl) `(let ((,sym (multiple-value-list ,form))) ,@forms))
192
(declare (fixnum n) (object vl))
193
(push `(setq ,(car vl) (nth ,n ,sym)) forms))
196
(defmacro multiple-value-bind (vars form &rest body)
197
(do ((vl vars (cdr vl))
201
((endp vl) `(let* ((,sym (multiple-value-list ,form)) ,@(reverse bind))
203
(declare (fixnum n) (object vl))
204
(push `(,(car vl) (nth ,n ,sym)) bind))
207
(defmacro do (control (test . result) &rest body
208
&aux (decl nil) (label (gensym)) (vl nil) (step nil))
211
(not (consp (car body)))
212
(not (eq (caar body) 'declare))))
213
(push (car body) decl)
217
(if(symbolp c) (setq c (list c)))
218
(push (list (car c) (cadr c)) vl)
219
(unless (endp (cddr c))
221
(push (caddr c) step)))
226
,label (if ,test (return (progn ,@result)))
228
(psetq ,@(reverse step))
231
(defmacro do* (control (test . result) &rest body
232
&aux (decl nil) (label (gensym)) (vl nil) (step nil))
235
(not (consp (car body)))
236
(not (eq (caar body) 'declare))))
237
(push (car body) decl)
241
(if(symbolp c) (setq c (list c)))
242
(push (list (car c) (cadr c)) vl)
243
(unless (endp (cddr c))
245
(push (caddr c) step)))
250
,label (if ,test (return (progn ,@result)))
252
(setq ,@(reverse step))
256
(defmacro case (keyform &rest clauses &aux (form nil) (key (gensym)))
257
(dolist (clause (reverse clauses) `(let ((,key ,keyform)) ,form))
258
(declare (object clause))
259
(cond ((or (eq (car clause) 't) (eq (car clause) 'otherwise))
260
(setq form `(progn ,@(cdr clause))))
261
((consp (car clause))
262
(setq form `(if (member ,key ',(car clause))
263
(progn ,@(cdr clause))
266
(setq form `(if (eql ,key ',(car clause))
267
(progn ,@(cdr clause))
272
(defmacro return (&optional (val nil)) `(return-from nil ,val))
274
(defmacro dolist ((var form &optional (val nil)) &rest body
275
&aux (temp (gensym)))
276
`(do* ((,temp ,form (cdr ,temp)) (,var (car ,temp) (car ,temp)))
280
;; In principle, a more complete job could be done here by trying to
281
;; capture fixnum type declarations from the surrounding context or
282
;; environment, or from within the compiler's internal structures at
283
;; compile time. See gcl-devel archives for examples. This
284
;; implementation relies on the fact that the gcc optimizer will
285
;; eliminate the bignum branch if the supplied form is a symbol
286
;; declared to be fixnum, as the comparison of a long integer variable
287
;; with most-positive-fixnum is then vacuous. Care must be taken in
288
;; making comparisons with most-negative-fixnum, as the C environment
289
;; appears to treat this as positive or negative depending on the sign
290
;; of the other argument in the comparison, apparently to symmetrize
291
;; the long integer range. 20040403 CM.
292
(defmacro dotimes ((var form &optional (val nil)) &rest body)
293
(cond ((symbolp form)
296
(declare (fixnum ,var) (ignorable ,var))
298
((<= ,form most-positive-fixnum)
300
(declare (fixnum ,form))
301
(do* ((,var 0 (1+ ,var))) ((>= ,var ,form) ,val)
302
(declare (fixnum ,var))
305
(do* ((,var 0 (1+ ,var))) ((>= ,var ,form) ,val)
310
(declare (fixnum ,var) (ignorable ,var))
312
((<= form most-positive-fixnum)
313
`(do* ((,var 0 (1+ ,var))) ((>= ,var ,form) ,val)
314
(declare (fixnum ,var))
317
`(do* ((,var 0 (1+ ,var))) ((>= ,var ,form) ,val)
320
(let ((temp (gensym)))
321
`(let ((,temp ,form))
324
(declare (fixnum ,var) (ignorable ,var))
326
((<= ,temp most-positive-fixnum)
328
(declare (fixnum ,temp))
329
(do* ((,var 0 (1+ ,var))) ((>= ,var ,temp) ,val)
330
(declare (fixnum ,var))
333
(do* ((,var 0 (1+ ,var))) ((>= ,var ,temp) ,val)
336
(defmacro declaim (&rest l)
337
`(eval-when (compile eval load)
338
,@(mapcar #'(lambda (x) `(proclaim ',x)) l)))
340
(defmacro lambda ( &rest l) `(function (lambda ,@l)))