1.0.48.3: source-locations from LOAD of source files, and EVAL-WHEN :COMPILE-TOPLEVEL
* Bind *SOURCE-INFO* and bind and populate *SOURCE-PATHS* in
LOAD-AS-SOURCE.
* EVAL-TLF provides a way to evaluate things while providing the
toplevel form number. It also captures the current *SOURCE-INFO*
and passes it onwards to be reused by ACTUALLY-COMPILE.
* In ACTUALLY-COMPILE, when asked to reuse a source-info object,
also retain the old *SOURCE-PATHS*.
| 1 | ;;;; EVAL and friends |
| 2 | |
| 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. |
| 11 | |
| 12 | (in-package "SB!IMPL") |
| 13 | |
| 14 | (defparameter *eval-calls* 0) |
| 15 | |
| 16 | (defun !eval-cold-init () |
| 17 | (setf *eval-calls* 0 |
| 18 | *evaluator-mode* :compile) |
| 19 | #!+sb-eval |
| 20 | (setf sb!eval::*eval-level* -1 |
| 21 | sb!eval::*eval-verbose* nil)) |
| 22 | |
| 23 | (defvar *eval-source-context* nil) |
| 24 | |
| 25 | (defvar *eval-tlf-index* nil) |
| 26 | (defvar *eval-source-info* nil) |
| 27 | |
| 28 | (defun make-eval-lambda (expr) |
| 29 | `(named-lambda |
| 30 | ;; This name is used to communicate the original context |
| 31 | ;; for the compiler, and identifies the lambda for use of |
| 32 | ;; EVAL-LAMBDA-SOURCE-LAMBDA below. |
| 33 | (eval ,(sb!c::source-form-context *eval-source-context*)) () |
| 34 | (declare (muffle-conditions compiler-note)) |
| 35 | ;; why PROGN? So that attempts to eval free declarations |
| 36 | ;; signal errors rather than return NIL. -- CSR, 2007-05-01 |
| 37 | (progn ,expr))) |
| 38 | |
| 39 | (defun eval-lambda-p (form) |
| 40 | (when (and (consp form) (eq 'named-lambda (first form))) |
| 41 | (let ((name (second form))) |
| 42 | (when (and (consp name) (eq 'eval (first name))) |
| 43 | t)))) |
| 44 | |
| 45 | (defun eval-lambda-source-lambda (eval-lambda) |
| 46 | (if (eval-lambda-p eval-lambda) |
| 47 | (destructuring-bind (named-lambda name lambda-list decl (progn expr)) |
| 48 | eval-lambda |
| 49 | (declare (ignore named-lambda name lambda-list decl progn)) |
| 50 | (when (and (consp expr) (member (car expr) '(lambda named-lambda))) |
| 51 | expr)) |
| 52 | eval-lambda)) |
| 53 | |
| 54 | ;;; general case of EVAL (except in that it can't handle toplevel |
| 55 | ;;; EVAL-WHEN magic properly): Delegate to #'COMPILE. |
| 56 | (defun %simple-eval (expr lexenv) |
| 57 | ;; FIXME: It might be nice to quieten the toplevel by muffling |
| 58 | ;; warnings generated by this compilation (since we're about to |
| 59 | ;; execute the results irrespective of the warnings). We might want |
| 60 | ;; to be careful about not muffling warnings arising from inner |
| 61 | ;; evaluations/compilations, though [e.g. the ignored variable in |
| 62 | ;; (DEFUN FOO (X) 1)]. -- CSR, 2003-05-13 |
| 63 | ;; |
| 64 | ;; As of 1.0.21.6 we muffle compiler notes lexically here, which seems |
| 65 | ;; always safe. --NS |
| 66 | (let* ((lambda (make-eval-lambda expr)) |
| 67 | (fun (sb!c:compile-in-lexenv |
| 68 | nil lambda lexenv *eval-source-info* *eval-tlf-index*))) |
| 69 | (funcall fun))) |
| 70 | |
| 71 | ;;; Handle PROGN and implicit PROGN. |
| 72 | (defun simple-eval-progn-body (progn-body lexenv) |
| 73 | (unless (list-with-length-p progn-body) |
| 74 | (let ((*print-circle* t)) |
| 75 | (error 'simple-program-error |
| 76 | :format-control |
| 77 | "~@<not a proper list in PROGN or implicit PROGN: ~2I~_~S~:>" |
| 78 | :format-arguments (list progn-body)))) |
| 79 | ;; Note: |
| 80 | ;; * We can't just use (MAP NIL #'EVAL PROGN-BODY) here, because we |
| 81 | ;; need to take care to return all the values of the final EVAL. |
| 82 | ;; * It's left as an exercise to the reader to verify that this |
| 83 | ;; gives the right result when PROGN-BODY is NIL, because |
| 84 | ;; (FIRST NIL) = (REST NIL) = NIL. |
| 85 | (do* ((i progn-body rest-i) |
| 86 | (rest-i (rest i) (rest i))) |
| 87 | (nil) |
| 88 | (if rest-i ; if not last element of list |
| 89 | (simple-eval-in-lexenv (first i) lexenv) |
| 90 | (return (simple-eval-in-lexenv (first i) lexenv))))) |
| 91 | |
| 92 | (defun simple-eval-locally (exp lexenv &key vars) |
| 93 | (multiple-value-bind (body decls) |
| 94 | (parse-body (rest exp) :doc-string-allowed nil) |
| 95 | (let ((lexenv |
| 96 | ;; KLUDGE: Uh, yeah. I'm not anticipating |
| 97 | ;; winning any prizes for this code, which was |
| 98 | ;; written on a "let's get it to work" basis. |
| 99 | ;; These seem to be the variables that need |
| 100 | ;; bindings for PROCESS-DECLS to work |
| 101 | ;; (*FREE-FUNS* and *FREE-VARS* so that |
| 102 | ;; references to free functions and variables |
| 103 | ;; in the declarations can be noted; |
| 104 | ;; *UNDEFINED-WARNINGS* so that warnings about |
| 105 | ;; undefined things can be accumulated [and |
| 106 | ;; then thrown away, as it happens]). -- CSR, |
| 107 | ;; 2002-10-24 |
| 108 | (let* ((sb!c:*lexenv* lexenv) |
| 109 | (sb!c::*free-funs* (make-hash-table :test 'equal)) |
| 110 | (sb!c::*free-vars* (make-hash-table :test 'eq)) |
| 111 | (sb!c::*undefined-warnings* nil)) |
| 112 | ;; FIXME: VALUES declaration |
| 113 | (sb!c::process-decls decls |
| 114 | vars |
| 115 | nil |
| 116 | :lexenv lexenv |
| 117 | :context :eval)))) |
| 118 | (simple-eval-progn-body body lexenv)))) |
| 119 | |
| 120 | ;;;; EVAL-ERROR |
| 121 | ;;;; |
| 122 | ;;;; Analogous to COMPILER-ERROR, but simpler. |
| 123 | |
| 124 | (define-condition eval-error (encapsulated-condition) |
| 125 | () |
| 126 | (:report (lambda (condition stream) |
| 127 | (print-object (encapsulated-condition condition) stream)))) |
| 128 | |
| 129 | (defun eval-error (condition) |
| 130 | (signal 'eval-error :condition condition) |
| 131 | (bug "Unhandled EVAL-ERROR")) |
| 132 | |
| 133 | ;;; Pick off a few easy cases, and the various top level EVAL-WHEN |
| 134 | ;;; magical cases, and call %SIMPLE-EVAL for the rest. |
| 135 | (defun simple-eval-in-lexenv (original-exp lexenv) |
| 136 | (declare (optimize (safety 1))) |
| 137 | ;; (aver (lexenv-simple-p lexenv)) |
| 138 | (incf *eval-calls*) |
| 139 | (handler-bind |
| 140 | ((sb!c:compiler-error |
| 141 | (lambda (c) |
| 142 | (if (boundp 'sb!c::*compiler-error-bailout*) |
| 143 | ;; if we're in the compiler, delegate either to a higher |
| 144 | ;; authority or, if that's us, back down to the |
| 145 | ;; outermost compiler handler... |
| 146 | (progn |
| 147 | (signal c) |
| 148 | nil) |
| 149 | ;; ... if we're not in the compiler, better signal the |
| 150 | ;; error straight away. |
| 151 | (invoke-restart 'sb!c::signal-error))))) |
| 152 | (let ((exp (macroexpand original-exp lexenv))) |
| 153 | (handler-bind ((eval-error |
| 154 | (lambda (condition) |
| 155 | (error 'interpreted-program-error |
| 156 | :condition (encapsulated-condition condition) |
| 157 | :form exp)))) |
| 158 | (typecase exp |
| 159 | (symbol |
| 160 | (ecase (info :variable :kind exp) |
| 161 | ((:special :global :constant :unknown) |
| 162 | (symbol-value exp)) |
| 163 | ;; FIXME: This special case here is a symptom of non-ANSI |
| 164 | ;; weirdness in SBCL's ALIEN implementation, which could |
| 165 | ;; cause problems for e.g. code walkers. It'd probably be |
| 166 | ;; good to ANSIfy it by making alien variable accessors |
| 167 | ;; into ordinary forms, e.g. (SB-UNIX:ENV) and (SETF |
| 168 | ;; SB-UNIX:ENV), instead of magical symbols, e.g. plain |
| 169 | ;; SB-UNIX:ENV. Then if the old magical-symbol syntax is to |
| 170 | ;; be retained for compatibility, it can be implemented |
| 171 | ;; with DEFINE-SYMBOL-MACRO, keeping the code walkers |
| 172 | ;; happy. |
| 173 | (:alien |
| 174 | (%simple-eval original-exp lexenv)))) |
| 175 | (list |
| 176 | (let ((name (first exp)) |
| 177 | (n-args (1- (length exp)))) |
| 178 | (case name |
| 179 | ((function) |
| 180 | (unless (= n-args 1) |
| 181 | (error "wrong number of args to FUNCTION:~% ~S" exp)) |
| 182 | (let ((name (second exp))) |
| 183 | (if (and (legal-fun-name-p name) |
| 184 | (not (consp (let ((sb!c:*lexenv* lexenv)) |
| 185 | (sb!c:lexenv-find name funs))))) |
| 186 | (%coerce-name-to-fun name) |
| 187 | ;; FIXME: This is a bit wasteful: it would be nice to call |
| 188 | ;; COMPILE-IN-LEXENV with the lambda-form directly, but |
| 189 | ;; getting consistent source context and muffling compiler notes |
| 190 | ;; is easier this way. |
| 191 | (%simple-eval original-exp lexenv)))) |
| 192 | ((quote) |
| 193 | (unless (= n-args 1) |
| 194 | (error "wrong number of args to QUOTE:~% ~S" exp)) |
| 195 | (second exp)) |
| 196 | (setq |
| 197 | (unless (evenp n-args) |
| 198 | (error "odd number of args to SETQ:~% ~S" exp)) |
| 199 | (unless (zerop n-args) |
| 200 | (do ((name (cdr exp) (cddr name))) |
| 201 | ((null name) |
| 202 | (do ((args (cdr exp) (cddr args))) |
| 203 | ((null (cddr args)) |
| 204 | ;; We duplicate the call to SET so that the |
| 205 | ;; correct value gets returned. |
| 206 | (set (first args) |
| 207 | (simple-eval-in-lexenv (second args) lexenv))) |
| 208 | (set (first args) |
| 209 | (simple-eval-in-lexenv (second args) lexenv)))) |
| 210 | (let ((symbol (first name))) |
| 211 | (case (info :variable :kind symbol) |
| 212 | (:special) |
| 213 | (t (return (%simple-eval original-exp lexenv)))) |
| 214 | (unless (type= (info :variable :type symbol) |
| 215 | *universal-type*) |
| 216 | ;; let the compiler deal with type checking |
| 217 | (return (%simple-eval original-exp lexenv))))))) |
| 218 | ((progn) |
| 219 | (simple-eval-progn-body (rest exp) lexenv)) |
| 220 | ((eval-when) |
| 221 | ;; FIXME: DESTRUCTURING-BIND returns ARG-COUNT-ERROR |
| 222 | ;; instead of PROGRAM-ERROR when there's something wrong |
| 223 | ;; with the syntax here (e.g. missing SITUATIONS). This |
| 224 | ;; could be fixed by hand-crafting clauses to catch and |
| 225 | ;; report each possibility, but it would probably be |
| 226 | ;; cleaner to write a new macro |
| 227 | ;; DESTRUCTURING-BIND-PROGRAM-SYNTAX which does |
| 228 | ;; DESTRUCTURING-BIND and promotes any mismatch to |
| 229 | ;; PROGRAM-ERROR, then to use it here and in (probably |
| 230 | ;; dozens of) other places where the same problem |
| 231 | ;; arises. |
| 232 | (destructuring-bind (eval-when situations &rest body) exp |
| 233 | (declare (ignore eval-when)) |
| 234 | (multiple-value-bind (ct lt e) |
| 235 | (sb!c:parse-eval-when-situations situations) |
| 236 | ;; CLHS 3.8 - Special Operator EVAL-WHEN: The use of |
| 237 | ;; the situation :EXECUTE (or EVAL) controls whether |
| 238 | ;; evaluation occurs for other EVAL-WHEN forms; that |
| 239 | ;; is, those that are not top level forms, or those |
| 240 | ;; in code processed by EVAL or COMPILE. If the |
| 241 | ;; :EXECUTE situation is specified in such a form, |
| 242 | ;; then the body forms are processed as an implicit |
| 243 | ;; PROGN; otherwise, the EVAL-WHEN form returns NIL. |
| 244 | (declare (ignore ct lt)) |
| 245 | (when e |
| 246 | (simple-eval-progn-body body lexenv))))) |
| 247 | ((locally) |
| 248 | (simple-eval-locally exp lexenv)) |
| 249 | ((macrolet) |
| 250 | (destructuring-bind (definitions &rest body) |
| 251 | (rest exp) |
| 252 | (let ((lexenv |
| 253 | (let ((sb!c:*lexenv* lexenv)) |
| 254 | (sb!c::funcall-in-macrolet-lexenv |
| 255 | definitions |
| 256 | (lambda (&key funs) |
| 257 | (declare (ignore funs)) |
| 258 | sb!c:*lexenv*) |
| 259 | :eval)))) |
| 260 | (simple-eval-locally `(locally ,@body) lexenv)))) |
| 261 | ((symbol-macrolet) |
| 262 | (destructuring-bind (definitions &rest body) (rest exp) |
| 263 | (multiple-value-bind (lexenv vars) |
| 264 | (let ((sb!c:*lexenv* lexenv)) |
| 265 | (sb!c::funcall-in-symbol-macrolet-lexenv |
| 266 | definitions |
| 267 | (lambda (&key vars) |
| 268 | (values sb!c:*lexenv* vars)) |
| 269 | :eval)) |
| 270 | (simple-eval-locally `(locally ,@body) lexenv :vars vars)))) |
| 271 | ((if) |
| 272 | (destructuring-bind (test then &optional else) (rest exp) |
| 273 | (eval-in-lexenv (if (eval-in-lexenv test lexenv) |
| 274 | then |
| 275 | else) |
| 276 | lexenv))) |
| 277 | ((let let*) |
| 278 | (destructuring-bind (definitions &rest body) (rest exp) |
| 279 | (if (null definitions) |
| 280 | (simple-eval-locally `(locally ,@body) lexenv) |
| 281 | (%simple-eval exp lexenv)))) |
| 282 | (t |
| 283 | (if (and (symbolp name) |
| 284 | (eq (info :function :kind name) :function)) |
| 285 | (collect ((args)) |
| 286 | (dolist (arg (rest exp)) |
| 287 | (args (eval-in-lexenv arg lexenv))) |
| 288 | (apply (symbol-function name) (args))) |
| 289 | (%simple-eval exp lexenv)))))) |
| 290 | (t |
| 291 | exp)))))) |
| 292 | |
| 293 | (defun eval-in-lexenv (exp lexenv) |
| 294 | #!+sb-eval |
| 295 | (if (eq *evaluator-mode* :compile) |
| 296 | (simple-eval-in-lexenv exp lexenv) |
| 297 | (sb!eval:eval-in-native-environment exp lexenv)) |
| 298 | #!-sb-eval |
| 299 | (simple-eval-in-lexenv exp lexenv)) |
| 300 | |
| 301 | (defun eval (original-exp) |
| 302 | #!+sb-doc |
| 303 | "Evaluate the argument in a null lexical environment, returning the |
| 304 | result or results." |
| 305 | (let ((*eval-source-context* original-exp) |
| 306 | (*eval-tlf-index* nil) |
| 307 | (*eval-source-info* nil)) |
| 308 | (eval-in-lexenv original-exp (make-null-lexenv)))) |
| 309 | |
| 310 | (defun eval-tlf (original-exp tlf-index &optional (lexenv (make-null-lexenv))) |
| 311 | (let ((*eval-source-context* original-exp) |
| 312 | (*eval-tlf-index* tlf-index) |
| 313 | (*eval-source-info* sb!c::*source-info*)) |
| 314 | (eval-in-lexenv original-exp lexenv))) |
| 315 | |
| 316 | ;;; miscellaneous full function definitions of things which are |
| 317 | ;;; ordinarily handled magically by the compiler |
| 318 | |
| 319 | (defun apply (function arg &rest arguments) |
| 320 | #!+sb-doc |
| 321 | "Apply FUNCTION to a list of arguments produced by evaluating ARGUMENTS in |
| 322 | the manner of LIST*. That is, a list is made of the values of all but the |
| 323 | last argument, appended to the value of the last argument, which must be a |
| 324 | list." |
| 325 | (cond ((atom arguments) |
| 326 | (apply function arg)) |
| 327 | ((atom (cdr arguments)) |
| 328 | (apply function (cons arg (car arguments)))) |
| 329 | (t (do* ((a1 arguments a2) |
| 330 | (a2 (cdr arguments) (cdr a2))) |
| 331 | ((atom (cdr a2)) |
| 332 | (rplacd a1 (car a2)) |
| 333 | (apply function (cons arg arguments))))))) |
| 334 | |
| 335 | (defun funcall (function &rest arguments) |
| 336 | #!+sb-doc |
| 337 | "Call FUNCTION with the given ARGUMENTS." |
| 338 | (apply function arguments)) |
| 339 | |
| 340 | (defun values (&rest values) |
| 341 | #!+sb-doc |
| 342 | "Return all arguments, in order, as values." |
| 343 | (declare (truly-dynamic-extent values)) |
| 344 | (values-list values)) |
| 345 | |
| 346 | (defun values-list (list) |
| 347 | #!+sb-doc |
| 348 | "Return all of the elements of LIST, in order, as values." |
| 349 | (values-list list)) |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use