Cosmetic improvements in PCL code
[sbcl.git] / src / code / eval.lisp
blobaae834e73d084585252923556854f4496a30269c
1 ;;;; EVAL and friends
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!IMPL")
14 (!defparameter *eval-calls* 0)
16 (defvar *eval-source-context* nil)
18 (defvar *eval-tlf-index* nil)
19 (defvar *eval-source-info* nil)
21 ;;;; Turns EXPR into a lambda-form we can pass to COMPILE. Returns
22 ;;;; a secondary value of T if we must call the resulting function
23 ;;;; to evaluate EXPR -- if EXPR is already a lambda form, there's
24 ;;;; no need.
25 (defun make-eval-lambda (expr)
26 (flet ((lexpr-p (x)
27 (typep x '(cons (member lambda named-lambda lambda-with-lexenv)))))
28 (cond ((lexpr-p expr)
29 (values expr nil))
31 (when (typep expr '(cons (eql function) (cons t null)))
32 (let ((inner (second expr)))
33 (when (lexpr-p inner)
34 (return-from make-eval-lambda (values inner nil)))))
35 (values `(lambda ()
36 ;; why PROGN? So that attempts to eval free declarations
37 ;; signal errors rather than return NIL. -- CSR, 2007-05-01
38 (progn ,expr))
39 t)))))
41 ;;; FIXME: what does "except in that it can't handle toplevel ..." mean?
42 ;;; Is there anything wrong with the implementation, or is the comment obsolete?
43 ;;; general case of EVAL (except in that it can't handle toplevel
44 ;;; EVAL-WHEN magic properly): Delegate to #'COMPILE.
45 (defun %simple-eval (expr lexenv)
46 (multiple-value-bind (lambda call) (make-eval-lambda expr)
47 (let ((fun
48 ;; This tells the compiler where the lambda comes from, in case it
49 ;; wants to report any problems.
50 (let ((sb!c::*source-form-context-alist*
51 (acons lambda *eval-source-context*
52 sb!c::*source-form-context-alist*)))
53 (handler-bind (;; Compiler notes just clutter up the REPL:
54 ;; anyone caring about performance should not
55 ;; be using EVAL.
56 (compiler-note #'muffle-warning))
57 (sb!c:compile-in-lexenv
58 nil lambda lexenv *eval-source-info* *eval-tlf-index* (not call))))))
59 (declare (function fun))
60 (if call
61 (funcall fun)
62 fun))))
64 ;;; Handle PROGN and implicit PROGN.
65 #!-sb-fasteval
66 (progn
67 (defun simple-eval-progn-body (progn-body lexenv)
68 (unless (list-with-length-p progn-body)
69 (let ((*print-circle* t))
70 (error 'simple-program-error
71 :format-control
72 "~@<not a proper list in PROGN or implicit PROGN: ~2I~_~S~:>"
73 :format-arguments (list progn-body))))
74 ;; Note:
75 ;; * We can't just use (MAP NIL #'EVAL PROGN-BODY) here, because we
76 ;; need to take care to return all the values of the final EVAL.
77 ;; * It's left as an exercise to the reader to verify that this
78 ;; gives the right result when PROGN-BODY is NIL, because
79 ;; (FIRST NIL) = (REST NIL) = NIL.
80 (do* ((i progn-body rest-i)
81 (rest-i (rest i) (rest i)))
82 (nil)
83 (if rest-i ; if not last element of list
84 (simple-eval-in-lexenv (first i) lexenv)
85 (return (simple-eval-in-lexenv (first i) lexenv)))))
87 (defun simple-eval-locally (exp lexenv &key vars)
88 (multiple-value-bind (body decls) (parse-body (rest exp) nil)
89 (let ((lexenv
90 ;; KLUDGE: Uh, yeah. I'm not anticipating
91 ;; winning any prizes for this code, which was
92 ;; written on a "let's get it to work" basis.
93 ;; These seem to be the variables that need
94 ;; bindings for PROCESS-DECLS to work
95 ;; (*FREE-FUNS* and *FREE-VARS* so that
96 ;; references to free functions and variables
97 ;; in the declarations can be noted;
98 ;; *UNDEFINED-WARNINGS* so that warnings about
99 ;; undefined things can be accumulated [and
100 ;; then thrown away, as it happens]). -- CSR,
101 ;; 2002-10-24
102 (let* ((sb!c:*lexenv* lexenv)
103 (sb!c::*free-funs* (make-hash-table :test 'equal))
104 (sb!c::*free-vars* (make-hash-table :test 'eq))
105 (sb!c::*undefined-warnings* nil))
106 ;; FIXME: VALUES declaration
107 (sb!c::process-decls decls
108 vars
110 :lexenv lexenv
111 :context :eval))))
112 (simple-eval-progn-body body lexenv))))
113 ) ; end PROGN
115 ;;;; EVAL-ERROR
116 ;;;;
117 ;;;; Analogous to COMPILER-ERROR, but simpler.
119 (define-condition eval-error (encapsulated-condition)
121 (:report (lambda (condition stream)
122 (print-object (encapsulated-condition condition) stream))))
124 (defun eval-error (condition)
125 (signal 'eval-error :condition condition)
126 (bug "Unhandled EVAL-ERROR"))
128 ;;; Pick off a few easy cases, and the various top level EVAL-WHEN
129 ;;; magical cases, and call %SIMPLE-EVAL for the rest.
130 #!-sb-fasteval
131 (defun simple-eval-in-lexenv (original-exp lexenv)
132 (declare (optimize (safety 1)))
133 ;; (aver (lexenv-simple-p lexenv))
134 (incf *eval-calls*)
135 (sb!c:with-compiler-error-resignalling
136 (let ((exp (macroexpand original-exp lexenv)))
137 (handler-bind ((eval-error
138 (lambda (condition)
139 (error 'interpreted-program-error
140 :condition (encapsulated-condition condition)
141 :form exp))))
142 (typecase exp
143 (symbol
144 (ecase (info :variable :kind exp)
145 ((:special :global :constant :unknown)
146 (symbol-value exp))
147 ;; FIXME: This special case here is a symptom of non-ANSI
148 ;; weirdness in SBCL's ALIEN implementation, which could
149 ;; cause problems for e.g. code walkers. It'd probably be
150 ;; good to ANSIfy it by making alien variable accessors
151 ;; into ordinary forms, e.g. (SB-UNIX:ENV) and (SETF
152 ;; SB-UNIX:ENV), instead of magical symbols, e.g. plain
153 ;; SB-UNIX:ENV. Then if the old magical-symbol syntax is to
154 ;; be retained for compatibility, it can be implemented
155 ;; with DEFINE-SYMBOL-MACRO, keeping the code walkers
156 ;; happy.
157 (:alien
158 (sb!alien-internals:alien-value exp))))
159 (list
160 (let ((name (first exp))
161 (n-args (1- (length exp))))
162 (case name
163 ((function)
164 (unless (= n-args 1)
165 (error "wrong number of args to FUNCTION:~% ~S" exp))
166 (let ((name (second exp)))
167 (if (and (legal-fun-name-p name)
168 (not (consp (let ((sb!c:*lexenv* lexenv))
169 (sb!c:lexenv-find name funs)))))
170 (%coerce-name-to-fun name)
171 ;; FIXME: This is a bit wasteful: it would be nice to call
172 ;; COMPILE-IN-LEXENV with the lambda-form directly, but
173 ;; getting consistent source context and muffling compiler notes
174 ;; is easier this way.
175 (%simple-eval original-exp lexenv))))
176 ((quote)
177 (unless (= n-args 1)
178 (error "wrong number of args to QUOTE:~% ~S" exp))
179 (second exp))
180 (setq
181 (unless (evenp n-args)
182 (error "odd number of args to SETQ:~% ~S" exp))
183 (unless (zerop n-args)
184 (do ((name (cdr exp) (cddr name)))
185 ((null name)
186 (do ((args (cdr exp) (cddr args)))
187 ((null (cddr args))
188 ;; We duplicate the call to SET so that the
189 ;; correct value gets returned.
190 (set (first args)
191 (simple-eval-in-lexenv (second args) lexenv)))
192 (set (first args)
193 (simple-eval-in-lexenv (second args) lexenv))))
194 (let ((symbol (first name)))
195 (case (info :variable :kind symbol)
196 (:special)
197 (t (return (%simple-eval original-exp lexenv))))
198 (unless (type= (info :variable :type symbol)
199 *universal-type*)
200 ;; let the compiler deal with type checking
201 (return (%simple-eval original-exp lexenv)))))))
202 ((progn)
203 (simple-eval-progn-body (rest exp) lexenv))
204 ((eval-when)
205 ;; FIXME: DESTRUCTURING-BIND returns ARG-COUNT-ERROR
206 ;; instead of PROGRAM-ERROR when there's something wrong
207 ;; with the syntax here (e.g. missing SITUATIONS). This
208 ;; could be fixed by hand-crafting clauses to catch and
209 ;; report each possibility, but it would probably be
210 ;; cleaner to write a new macro
211 ;; DESTRUCTURING-BIND-PROGRAM-SYNTAX which does
212 ;; DESTRUCTURING-BIND and promotes any mismatch to
213 ;; PROGRAM-ERROR, then to use it here and in (probably
214 ;; dozens of) other places where the same problem
215 ;; arises.
216 (destructuring-bind (eval-when situations &rest body) exp
217 (declare (ignore eval-when))
218 (multiple-value-bind (ct lt e)
219 (sb!c:parse-eval-when-situations situations)
220 ;; CLHS 3.8 - Special Operator EVAL-WHEN: The use of
221 ;; the situation :EXECUTE (or EVAL) controls whether
222 ;; evaluation occurs for other EVAL-WHEN forms; that
223 ;; is, those that are not top level forms, or those
224 ;; in code processed by EVAL or COMPILE. If the
225 ;; :EXECUTE situation is specified in such a form,
226 ;; then the body forms are processed as an implicit
227 ;; PROGN; otherwise, the EVAL-WHEN form returns NIL.
228 (declare (ignore ct lt))
229 (when e
230 (simple-eval-progn-body body lexenv)))))
231 ((locally)
232 (simple-eval-locally exp lexenv))
233 ((macrolet)
234 (destructuring-bind (definitions &rest body)
235 (rest exp)
236 (let ((lexenv
237 (let ((sb!c:*lexenv* lexenv))
238 (sb!c::funcall-in-macrolet-lexenv
239 definitions
240 (lambda (&key funs)
241 (declare (ignore funs))
242 sb!c:*lexenv*)
243 :eval))))
244 (simple-eval-locally `(locally ,@body) lexenv))))
245 ((symbol-macrolet)
246 (destructuring-bind (definitions &rest body) (rest exp)
247 (multiple-value-bind (lexenv vars)
248 (let ((sb!c:*lexenv* lexenv))
249 (sb!c::funcall-in-symbol-macrolet-lexenv
250 definitions
251 (lambda (&key vars)
252 (values sb!c:*lexenv* vars))
253 :eval))
254 (simple-eval-locally `(locally ,@body) lexenv :vars vars))))
255 ((if)
256 (destructuring-bind (test then &optional else) (rest exp)
257 (eval-in-lexenv (if (eval-in-lexenv test lexenv)
258 then
259 else)
260 lexenv)))
261 ((let let*)
262 (%simple-eval exp lexenv))
264 (if (and (symbolp name)
265 (eq (info :function :kind name) :function))
266 (collect ((args))
267 (dolist (arg (rest exp))
268 (args (eval-in-lexenv arg lexenv)))
269 (apply (symbol-function name) (args)))
270 (%simple-eval exp lexenv))))))
272 exp))))))
274 ;;; This definition will be replaced after the interpreter is compiled.
275 ;;; Until then we just always compile.
276 #!+sb-fasteval
277 (defun sb!interpreter:eval-in-environment (exp lexenv)
278 (let ((exp (macroexpand exp lexenv)))
279 (if (symbolp exp)
280 (symbol-value exp)
281 (%simple-eval exp (or lexenv (make-null-lexenv))))))
283 (defun eval-in-lexenv (exp lexenv)
284 #!+sb-eval
285 (let ((lexenv (or lexenv (make-null-lexenv))))
286 (if (eq *evaluator-mode* :compile)
287 (simple-eval-in-lexenv exp lexenv)
288 (sb!eval:eval-in-native-environment exp lexenv)))
289 #!+sb-fasteval
290 (sb!c:with-compiler-error-resignalling
291 (sb!interpreter:eval-in-environment exp lexenv))
292 #!-(or sb-eval sb-fasteval)
293 (simple-eval-in-lexenv exp (or lexenv (make-null-lexenv))))
295 (defun eval (original-exp)
296 #!+sb-doc
297 "Evaluate the argument in a null lexical environment, returning the
298 result or results."
299 (let ((*eval-source-context* original-exp)
300 (*eval-tlf-index* nil)
301 (*eval-source-info* nil))
302 (eval-in-lexenv original-exp nil)))
304 (defun eval-tlf (original-exp tlf-index &optional lexenv)
305 (let ((*eval-source-context* original-exp)
306 (*eval-tlf-index* tlf-index)
307 (*eval-source-info* sb!c::*source-info*))
308 (eval-in-lexenv original-exp lexenv)))
310 ;;; miscellaneous full function definitions of things which are
311 ;;; ordinarily handled magically by the compiler
313 (defun apply (function arg &rest arguments)
314 #!+sb-doc
315 "Apply FUNCTION to a list of arguments produced by evaluating ARGUMENTS in
316 the manner of LIST*. That is, a list is made of the values of all but the
317 last argument, appended to the value of the last argument, which must be a
318 list."
319 (cond ((atom arguments)
320 (apply function arg))
321 ((atom (cdr arguments))
322 (apply function (cons arg (car arguments))))
323 (t (do* ((a1 arguments a2)
324 (a2 (cdr arguments) (cdr a2)))
325 ((atom (cdr a2))
326 (rplacd a1 (car a2))
327 (apply function (cons arg arguments)))))))
329 (defun funcall (function &rest arguments)
330 #!+sb-doc
331 "Call FUNCTION with the given ARGUMENTS."
332 (apply function arguments))
334 (defun values (&rest values)
335 #!+sb-doc
336 "Return all arguments, in order, as values."
337 (declare (truly-dynamic-extent values))
338 (values-list values))
340 (defun values-list (list)
341 #!+sb-doc
342 "Return all of the elements of LIST, in order, as values."
343 (values-list list))