X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Flexenv.lisp;h=0b1f956ee4c2d13d868b5bb10046e62fc07ed20f;hb=369029d73f198b59135c6c005b7a70ae5a753650;hp=ae3ffba4f4650ddebe9063c31b06daa528c17950;hpb=64bf93a97814ea1caf62bbdcc7ef43e2fbfc8f73;p=sbcl.git diff --git a/src/compiler/lexenv.lisp b/src/compiler/lexenv.lisp index ae3ffba..0b1f956 100644 --- a/src/compiler/lexenv.lisp +++ b/src/compiler/lexenv.lisp @@ -17,18 +17,16 @@ ;;; (This is also what shows up as an ENVIRONMENT value in macroexpansion.) #!-sb-fluid (declaim (inline internal-make-lexenv)) ; only called in one place (def!struct (lexenv - ;; FIXME: should probably be called MAKE-EMPTY-LEXENV or - ;; MAKE-NULL-LEXENV (:constructor make-null-lexenv ()) (:constructor internal-make-lexenv - (functions variables blocks tags type-restrictions - lambda cleanup policy - interface-policy options))) - ;; Alist (NAME . WHAT), where WHAT is either a Functional (a local function), - ;; a DEFINED-FUNCTION, representing an INLINE/NOTINLINE declaration, or - ;; a list (MACRO . ) (a local macro, with the specifier - ;; expander.) Note that NAME may be a (SETF ) function. - (functions nil :type list) + (funs vars blocks tags type-restrictions + lambda cleanup policy options))) + ;; an alist of (NAME . WHAT), where WHAT is either a FUNCTIONAL (a + ;; local function), a DEFINED-FUN, representing an + ;; INLINE/NOTINLINE declaration, or a list (MACRO . ) (a + ;; local macro, with the specifier expander). Note that NAME may be + ;; a (SETF ) list, not necessarily a single symbol. + (funs nil :type list) ;; an alist translating variable names to LEAF structures. A special ;; binding is indicated by a :SPECIAL GLOBAL-VAR leaf. Each special ;; binding within the code gets a distinct leaf structure, as does @@ -38,7 +36,7 @@ ;; ;; If the CDR is (MACRO . ), then is the expansion of a ;; symbol macro. - (variables nil :type list) + (vars nil :type list) ;; BLOCKS and TAGS are alists from block and go-tag names to 2-lists ;; of the form ( ), where is the ;; continuation to exit to, and is the corresponding ENTRY node. @@ -48,7 +46,7 @@ ;; "pervasive" type declarations. When THING is a leaf, this is for ;; type declarations that pertain to the type in a syntactic extent ;; which does not correspond to a binding of the affected name. When - ;; Thing is a continuation, this is used to track the innermost THE + ;; THING is a continuation, this is used to track the innermost THE ;; type declaration. (type-restrictions nil :type list) ;; the lexically enclosing lambda, if any @@ -57,16 +55,35 @@ ;; to get CLAMBDA defined in time for the cross-compiler. (lambda nil) ;; the lexically enclosing cleanup, or NIL if none enclosing within Lambda - ;; - ;; FIXME: This should be :TYPE (OR CLEANUP NULL), but it was too hard - ;; to get CLEANUP defined in time for the cross-compiler. (cleanup nil) ;; the current OPTIMIZE policy - (policy *default-policy* :type policy) - ;; the policy that takes effect in XEPs and related syntax parsing - ;; functions. Slots in this policy may be null to indicate that the - ;; normal value in effect. - (interface-policy *default-interface-policy* :type policy) + (policy *policy* :type policy) ;; an alist of miscellaneous options that are associated with the ;; lexical environment (options nil :type list)) + +;;; support for the idiom (in MACROEXPAND and elsewhere) that NIL is +;;; to be taken as a null lexical environment +(defun coerce-to-lexenv (x) + (etypecase x + (null (make-null-lexenv)) + (lexenv x))) + +;;; Is it safe to just grab the lambda expression LAMBDA in isolation, +;;; ignoring the LEXENV? +;;; +;;; Note: The corresponding CMU CL code did something hairier so that +;;; it could save inline definitions of DEFUNs in nontrivial lexical +;;; environments. If it's ever important to try to do that, take a +;;; look at the old CMU CL #'INLINE-SYNTACTIC-CLOSURE. +(defun lambda-independent-of-lexenv-p (lambda lexenv) + (declare (type list lambda) (type lexenv lexenv)) + (aver (eql (first lambda) 'lambda)) ; basic sanity check + ;; This is a trivial implementation that just makes sure that LEXENV + ;; doesn't have anything interesting in it. A more sophisticated + ;; implementation could skip things in LEXENV which aren't captured + ;; by LAMBDA, but this implementation doesn't try. + (and (null (lexenv-blocks lexenv)) + (null (lexenv-tags lexenv)) + (null (lexenv-vars lexenv)) + (null (lexenv-funs lexenv))))