break infinite recursion in GENERATE-SLOTD-TYPECHECK
[sbcl.git] / src / code / full-eval.lisp
index 56208a0..718f5f1 100644 (file)
                    nil nil nil nil nil
                    (sb!c::lexenv-handled-conditions old-lexenv)
                    (sb!c::lexenv-disabled-package-locks old-lexenv)
                    nil nil nil nil nil
                    (sb!c::lexenv-handled-conditions old-lexenv)
                    (sb!c::lexenv-disabled-package-locks old-lexenv)
-                   (sb!c::lexenv-policy old-lexenv))))
+                   (sb!c::lexenv-policy old-lexenv)
+                   (sb!c::lexenv-user-data old-lexenv))))
       (dolist (declaration declarations)
         (unless (consp declaration)
           (ip-error "malformed declaration specifier ~S in ~S"
       (dolist (declaration declarations)
         (unless (consp declaration)
           (ip-error "malformed declaration specifier ~S in ~S"
              (sb!c::internal-make-lexenv
               nil nil
               nil nil nil nil nil nil nil
              (sb!c::internal-make-lexenv
               nil nil
               nil nil nil nil nil nil nil
-              sb!c::*policy*)))
+              sb!c::*policy*
+              nil)))
 
 ;;; Augment ENV with a special or lexical variable binding
 (declaim (inline push-var))
 
 ;;; Augment ENV with a special or lexical variable binding
 (declaim (inline push-var))
 
 ;;; Augment ENV with a local function binding
 (declaim (inline push-fun))
 
 ;;; Augment ENV with a local function binding
 (declaim (inline push-fun))
-(defun push-fun (name value env)
+(defun push-fun (name value calling-env body-env)
   (when (fboundp name)
   (when (fboundp name)
-    (let ((sb!c:*lexenv* (env-native-lexenv env)))
+    (let ((sb!c:*lexenv* (env-native-lexenv calling-env)))
       (program-assert-symbol-home-package-unlocked
        :eval name "binding ~A as a local function")))
       (program-assert-symbol-home-package-unlocked
        :eval name "binding ~A as a local function")))
-  (push (cons name value) (env-funs env))
-  (push (cons name :bogus) (sb!c::lexenv-funs (env-native-lexenv env))))
+  (push (cons name value) (env-funs body-env))
+  (push (cons name :bogus) (sb!c::lexenv-funs (env-native-lexenv body-env))))
 
 (sb!int:def!method print-object ((env env) stream)
   (print-unreadable-object (env stream :type t :identity t)))
 
 (sb!int:def!method print-object ((env env) stream)
   (print-unreadable-object (env stream :type t :identity t)))
     (cond
       ((eq type :constant)
        ;; Horrible place for this, but it works.
     (cond
       ((eq type :constant)
        ;; Horrible place for this, but it works.
-       (ip-error "Can't bind constant symbol ~S" symbol))
+       (ip-error "Can't bind constant symbol: ~S" symbol))
+      ((eq type :global)
+       ;; Ditto...
+       (ip-error "Can't bind a global variable: ~S" symbol))
       ((eq type :special) t)
       ((member symbol declared-specials :test #'eq)
        t)
       ((eq type :special) t)
       ((member symbol declared-specials :test #'eq)
        t)
 (defun parse-arguments (arguments lambda-list)
   (multiple-value-bind (required optional rest-p rest keyword-p
                         keyword allow-other-keys-p aux-p aux)
 (defun parse-arguments (arguments lambda-list)
   (multiple-value-bind (required optional rest-p rest keyword-p
                         keyword allow-other-keys-p aux-p aux)
-      (sb!int:parse-lambda-list lambda-list)
+      (handler-bind ((style-warning #'muffle-warning))
+        (sb!int:parse-lambda-list lambda-list))
     (let* ((original-arguments arguments)
            (arguments-present (length arguments))
            (required-length (length required))
     (let* ((original-arguments arguments)
            (arguments-present (length arguments))
            (required-length (length required))
 
 ;;; Return true if EXP is a lambda form.
 (defun lambdap (exp)
 
 ;;; Return true if EXP is a lambda form.
 (defun lambdap (exp)
-  (case (car exp) ((lambda
-                    sb!int:named-lambda
-                    sb!kernel:instance-lambda)
-                   t)))
+  (case (car exp)
+    ((lambda sb!int:named-lambda) t)))
 
 ;;; Split off the declarations (and the docstring, if
 ;;; DOC-STRING-ALLOWED is true) from the actual forms of BODY.
 
 ;;; Split off the declarations (and the docstring, if
 ;;; DOC-STRING-ALLOWED is true) from the actual forms of BODY.
 ;;; in the environment ENV.
 (defun eval-lambda (exp env)
   (case (car exp)
 ;;; in the environment ENV.
 (defun eval-lambda (exp env)
   (case (car exp)
-    ((lambda sb!kernel:instance-lambda)
+    ((lambda)
      (multiple-value-bind (body documentation declarations)
          (parse-lambda-headers (cddr exp) :doc-string-allowed t)
        (make-interpreted-function :lambda-list (second exp)
      (multiple-value-bind (body documentation declarations)
          (parse-lambda-headers (cddr exp) :doc-string-allowed t)
        (make-interpreted-function :lambda-list (second exp)
           (push-fun (car function-def)
                     ;; Evaluate the function definitions in ENV.
                     (eval-local-function-def function-def env)
           (push-fun (car function-def)
                     ;; Evaluate the function definitions in ENV.
                     (eval-local-function-def function-def env)
+                    ;; Do package-lock checks in ENV.
+                    env
                     ;; But add the bindings to the child environment.
                     new-env))
         (eval-progn body new-env)))))
                     ;; But add the bindings to the child environment.
                     new-env))
         (eval-progn body new-env)))))
         (dolist (function-def local-functions)
           (push-fun (car function-def)
                     (eval-local-function-def function-def env)
         (dolist (function-def local-functions)
           (push-fun (car function-def)
                     (eval-local-function-def function-def env)
+                    old-env
                     env))
         ;; And then add an environment for the body of the LABELS.  A
         ;; separate environment from the one where we added the
                     env))
         ;; And then add an environment for the body of the LABELS.  A
         ;; separate environment from the one where we added the
          (do ((form body (cdr form)))
              ((null form) nil)
            (when (atom (car form))
          (do ((form body (cdr form)))
              ((null form) nil)
            (when (atom (car form))
-             ;; FIXME: detect duplicate tags
+             (when (assoc (car form) tags)
+               (ip-error "The tag :A appears more than once in a tagbody."))
              (push (cons (car form) (cdr form)) tags)
              (push (cons (car form) #'go-to-tag) (env-tags env)))))
        ;; And then evaluate the forms in the body, starting from the
              (push (cons (car form) (cdr form)) tags)
              (push (cons (car form) #'go-to-tag) (env-tags env)))))
        ;; And then evaluate the forms in the body, starting from the
           (%eval form env))
       (compiler-environment-too-complex-error (condition)
         (declare (ignore condition))
           (%eval form env))
       (compiler-environment-too-complex-error (condition)
         (declare (ignore condition))
-        ;; FIXME: this could be a really annoying warning. It should
-        ;; have its own class.
-        (sb!int:style-warn
-         "~@<Native lexical environment too complex for SB-EVAL ~
-       to evaluate ~S, falling back to SIMPLE-EVAL-IN-LEXENV.  ~
-       Lexenv: ~S~:@>"
-         form lexenv)
+        (sb!int:style-warn 'sb!kernel:lexical-environment-too-complex
+                           :form form :lexenv lexenv)
         (sb!int:simple-eval-in-lexenv form lexenv)))))
         (sb!int:simple-eval-in-lexenv form lexenv)))))