source: trunk/source/level-0/l0-def.lisp @ 14325

Last change on this file since 14325 was 14325, checked in by gb, 10 years ago

If DEFUN is used to redefine a macro, just WARN instead of CERRORing
(Procedural redefinition still CERRORs.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1;;;-*- Mode: Lisp; Package: CCL -*-
2;;;
3;;;   Copyright (C) 2009 Clozure Associates
4;;;   Copyright (C) 1994-2001 Digitool, Inc
5;;;   This file is part of Clozure CL. 
6;;;
7;;;   Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
8;;;   License , known as the LLGPL and distributed with Clozure CL as the
9;;;   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
10;;;   which is distributed with Clozure CL as the file "LGPL".  Where these
11;;;   conflict, the preamble takes precedence. 
12;;;
13;;;   Clozure CL is referenced in the preamble as the "LIBRARY."
14;;;
15;;;   The LLGPL is also available online at
16;;;   http://opensource.franz.com/preamble.html
17
18(in-package "CCL")
19
20;;; primitives that manipulate function & variable definitions.
21
22
23
24
25
26(defun functionp (arg)
27  "Return true if OBJECT is a FUNCTION, and NIL otherwise."
28  (functionp arg))
29
30(defun lfunp (arg)
31  (functionp arg))
32
33(defun %proclaim-special (sym &optional initp)
34  (let* ((oldbits (%symbol-bits sym)))
35    (declare (fixnum oldbits))
36    (%symbol-bits sym (bitset $sym_vbit_special oldbits))
37    initp))
38
39(setq *lfun-names* (make-hash-table :test 'eq :weak t))
40
41(defun lookup-lfun-name (lfun) 
42  (gethash lfun *lfun-names*))
43
44
45(defun function-name (fun)
46  (or (and (functionp fun) (lfun-name fun))
47      (if (compiled-function-p (setq fun (closure-function fun)))
48        (lfun-name fun))))
49
50
51(defun bootstrapping-fmakunbound (name)
52  (when (consp name)
53    (unless (eq (%car name) 'setf)
54      (error "Function spec handler not loaded yet"))
55    (setq name (setf-function-name (cadr name))))
56  (%unfhave name)
57  name)
58
59;;; redefined in sysutils.
60(%fhave 'fmakunbound #'bootstrapping-fmakunbound)
61
62(defun bootstrapping-fset (name fn)
63  (fmakunbound name)
64  (%fhave name fn)
65  fn)
66
67;Redefined in sysutils.
68(%fhave 'fset #'bootstrapping-fset)
69
70(defun bootstrapping-record-source-file (fn &optional type)
71  (declare (ignore fn type))
72  nil)
73
74;Redefined in l1-utils.
75(%fhave 'record-source-file #'bootstrapping-record-source-file)
76
77
78(setq *fasload-print* nil)
79(setq *save-doc-strings* t)
80
81
82
83(%fhave '%defun-encapsulated-maybe ;Redefined in encapsulate
84        (qlfun bootstrapping-defun-encapsulated (name fn)
85          (declare (ignore name fn))
86          nil))
87
88(%fhave 'encapsulated-function-name  ;Redefined in encapsulate - used in l1-io
89        (qlfun bootstrapping-encapsulated-function-name (fn)
90          (declare (ignore fn))
91          nil))
92
93(%fhave 'set-function-info (qlfun set-function-info  (name info)
94                                  (if (typep info 'string)
95                                    (set-documentation name 'function info))
96                                  name))
97
98(defun %defun (named-fn &optional info)
99  (unless (typep named-fn 'function)
100    (dbg named-fn))
101  (let* ((name (function-name named-fn)))
102    (unless (and name
103                 (or (symbolp name)
104                     (setf-function-name-p name)))
105      (dbg named-fn))
106  (record-source-file name 'function)
107  (when (not (%defun-encapsulated-maybe name named-fn))
108    (when (and (symbolp name) (macro-function name nil))
109      (warn "The macro ~s is being redefined as a function." name)
110      (fmakunbound name))
111    (fset name named-fn))
112  (set-function-info name info)
113  (when *fasload-print* (format t "~&~S~%" name))
114  name))
115
116(defun validate-function-name (name)
117  (if (symbolp name)
118    name
119    (if (setf-function-name-p name)
120      (setf-function-name (cadr name))
121      (report-bad-arg name 'function-name))))
122
123;;;    There are three kinds of things which can go in the function
124;;;    cell of a symbol: 1) A function.  2) The thing which is the
125;;;    value of %unbound-function%: a 1-element vector whose 0th
126;;;    element is a code vector which causes an "undefined function"
127;;;    error to be signalled.  3) A macro or special-form definition,
128;;;    which is a 2-element vector whose 0th element is a code vector
129;;;    which signals a "can't apply macro or special form" error when
130;;;    executed and whose 1st element is a macro or special-operator
131;;;    name.  It doesn't matter what type of gvector cases 2 and 3
132;;;    are.  Once that's decided, it wouldn't hurt if %FHAVE
133;;;    typechecked its second arg.
134
135(defun %fhave (name def)
136  (let* ((fname (validate-function-name name)))
137    (setf (%svref (symptr->symvector (%symbol->symptr fname)) target::symbol.fcell-cell) def)))
138
139;;; FBOUNDP is true of any symbol whose function-cell contains something other
140;;; than %unbound-function%; we expect FBOUNDP to return that something.
141(defun fboundp (name)
142  "Return true if name has a global function definition."
143  (let* ((fname (validate-function-name name))
144         (def (%svref (symptr->symvector (%symbol->symptr fname)) target::symbol.fcell-cell)))
145    (unless (eq def %unbound-function%)
146      def)))
147
148;;; %UNFHAVE doesn't seem to want to deal with SETF names or function specs.
149;;; Who does ?
150
151(defun %unfhave (sym)
152  (let* ((symvec (symptr->symvector (%symbol->symptr sym)))
153         (old (%svref symvec target::symbol.fcell-cell))
154         (unbound %unbound-function%))
155    (setf (%svref symvec target::symbol.fcell-cell) unbound)
156    (not (eq old unbound))))
157
158;;; It's guaranteed that lfun-bits is a fixnum.  Might be a 30-bit fixnum ...
159
160
161
162
163
164(defun lfun-vector-name (fun &optional (new-name nil set-name-p))
165  (let* ((bits (lfun-bits fun)))
166    (declare (fixnum bits))
167    (if (and (logbitp $lfbits-gfn-bit bits)
168             (not (logbitp $lfbits-method-bit bits)))
169      (progn
170        (if set-name-p
171          (%gf-name fun new-name)
172          (%gf-name fun)))
173      (let* ((has-name-cell (not (logbitp $lfbits-noname-bit bits))))
174        (if has-name-cell
175          (let* ((lfv (lfun-vector fun))
176                 (name-idx (- (the fixnum (uvsize lfv)) 2))
177                 (old-name (%svref lfv name-idx)))
178            (declare (fixnum name-idx))
179            (if (and set-name-p (not (eq old-name new-name)))
180              (setf (%svref lfv name-idx) new-name))
181            old-name))))))
182
183(defun lfun-name (fun &optional (new-name nil set-name-p))
184  (multiple-value-bind (stored-name stored?) (lookup-lfun-name fun)
185    (unless stored?
186      (setq stored-name (lfun-vector-name fun)))
187    (when (and set-name-p (neq new-name stored-name))
188      (if (and stored? (eq new-name (lfun-vector-name fun)))
189        (remhash fun *lfun-names*)
190        (if (logbitp $lfbits-noname-bit (the fixnum (lfun-bits fun)))   ; no name-cell in function vector.
191          (puthash fun *lfun-names* new-name)
192          (lfun-vector-name fun new-name))))
193    stored-name))
194
195(defun lfun-bits (function &optional new)
196  (unless (functionp function)
197    (setq function (require-type function 'function)))
198  (let* ((lfv (lfun-vector function))
199         (idx (1- (the fixnum (uvsize lfv))))
200         (old (%svref lfv idx)))
201    (declare (fixnum idx))
202    (if new
203      (setf (%svref lfv idx) new))
204    old))
205   
206(defun %macro-have (symbol macro-function)
207  (declare (special %macro-code%))      ; magically set by xloader.
208  (%fhave symbol (vector %macro-code% macro-function)))
209
210
211(defun special-operator-p (symbol)
212  "If the symbol globally names a special form, return T, otherwise NIL."
213  (let ((def (fboundp symbol)))
214    (and (typep def 'simple-vector)
215         (not (lfunp (svref def 1))))))
216
217(defun special-form-p (x) (special-operator-p x))
218
219(defun setf-function-name-p (thing)
220  (and (consp thing)
221       (consp (%cdr thing))
222       (null (%cddr thing))
223       (eq (%car thing) 'setf)
224       (symbolp (%cadr thing))))
225
226(defun macro-function (form &optional env)
227  "If SYMBOL names a macro in ENV, returns the expansion function,
228   else returns NIL. If ENV is unspecified or NIL, use the global
229   environment only."
230  (setq form (require-type form 'symbol))
231  (when env
232    ; A definition-environment isn't a lexical environment, but it can
233    ; be an ancestor of one.
234    (unless (istruct-typep env 'lexical-environment)
235        (report-bad-arg env 'lexical-environment))
236      (let ((cell nil))
237        (tagbody
238          top
239          (if (setq cell (%cdr (assq form (lexenv.functions env))))
240            (return-from macro-function 
241              (if (eq (car cell) 'macro) (%cdr cell))))
242          (unless (listp (setq env (lexenv.parent-env env)))
243            (go top)))))
244      ; Not found in env, look in function cell.
245  (%global-macro-function form))
246
247(defun %fixnum-ref-macptr (fixnum &optional (offset 0))
248  (%int-to-ptr (%fixnum-ref-natural fixnum offset)))
249
250(defun %fixnum-set-macptr (fixnum offset &optional (newval offset newval-p))
251  (%fixnum-set-natural fixnum (if newval-p offset 0) (%ptr-to-int newval))
252  newval)
253
254;;; end of l0-def.lisp
Note: See TracBrowser for help on using the repository browser.