changeset 5471:00e79bbbe48f

Merge with trunk.
author Mats Lidell <matsl@xemacs.org>
date Mon, 14 Feb 2011 22:43:46 +0100
parents 0af042a0c116 (current diff) 5dd1ba5e0113 (diff)
children e79980ee5efe
files lisp/ChangeLog lisp/bytecomp.el lisp/cl-macs.el lisp/cl.el src/ChangeLog src/alloc.c src/faces.c src/fns.c src/lisp.h src/mc-alloc.c tests/ChangeLog tests/automated/lisp-tests.el
diffstat 12 files changed, 160 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Mon Feb 07 21:22:17 2011 +0100
+++ b/lisp/ChangeLog	Mon Feb 14 22:43:46 2011 +0100
@@ -1,3 +1,30 @@
+2011-02-12  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* bytecomp.el:
+	* bytecomp.el (byte-compile-initial-macro-environment):
+	* bytecomp.el (unwind-protect):
+	* bytecomp.el (byte-compile-active-blocks):
+	* bytecomp.el (byte-compile-catch):
+	* bytecomp.el ('return-from-1): Removed.
+	* bytecomp.el ('block-1): Removed.
+	* bytecomp.el (byte-compile-block-1): Removed.
+	* bytecomp.el (byte-compile-return-from-1): Removed.
+	* bytecomp.el (byte-compile-throw):
+	* cl-macs.el (block):
+	* cl-macs.el (return-from):
+	In my last change, the elimination of `block's that were never
+	`return-from'd didn't work if `cl-macroexpand-all' was called
+	explicitly, something much code in cl-macs.el does.  Change the
+	implementation to something that doesn't require shadowing of the
+	macros in `byte-compile-initial-macro-environment', putting a
+	`cl-block-name' property on the gensym'd symbol argument to
+	`catch' instead.
+
+2011-02-09  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl.el (acons): Removed, make the implementation in alloc.c
+	visible to Lisp instead.
+
 2011-02-07  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* bytecomp.el:
--- a/lisp/bytecomp.el	Mon Feb 07 21:22:17 2011 +0100
+++ b/lisp/bytecomp.el	Mon Feb 14 22:43:46 2011 +0100
@@ -509,11 +509,7 @@
 		    "%s is not of type %s" form type)))
 	   (if byte-compile-delete-errors
 	       form
-	     (funcall (cdr (symbol-function 'the)) type form))))
-    (return-from .
-      ,#'(lambda (name &optional result) `(return-from-1 ',name ,result)))
-    (block .
-      ,#'(lambda (name &rest body) `(block-1 ',name ,@body))))
+	     (funcall (cdr (symbol-function 'the)) type form)))))
   "The default macro-environment passed to macroexpand by the compiler.
 Placing a macro here will cause a macro to have different semantics when
 expanded by the compiler as when expanded by the interpreter.")
@@ -4184,8 +4180,6 @@
 ;;; other tricky macro-like special-operators
 
 (byte-defop-compiler-1 catch)
-(byte-defop-compiler-1 block-1)
-(byte-defop-compiler-1 return-from-1)
 (byte-defop-compiler-1 unwind-protect)
 (byte-defop-compiler-1 condition-case)
 (byte-defop-compiler-1 save-excursion)
@@ -4194,44 +4188,33 @@
 (byte-defop-compiler-1 with-output-to-temp-buffer)
 ;; no track-mouse.
 
+(defvar byte-compile-active-blocks nil)
+
 (defun byte-compile-catch (form)
-  (byte-compile-form (car (cdr form)))
-  (byte-compile-push-constant
-    (byte-compile-top-level (cons 'progn (cdr (cdr form))) for-effect))
-  (byte-compile-out 'byte-catch 0))
-
-;; `return-from' and `block' are different from `throw' and `catch' when it
-;; comes to scope and extent. These differences are implemented for
-;; interpreted code in cl-macs.el, in compiled code in bytecomp.el. There's
-;; a certain amount of bootstrapping needed for the latter, and until this
-;; is done return-from and block behave as throw and catch in their scope
-;; and extent. This is only relevant to people working on bytecomp.el.
-
-(defalias 'return-from-1 'throw)
-(defalias 'block-1 'catch)
-
-(defvar byte-compile-active-blocks nil)
-
-(defun byte-compile-block-1 (form)
-  (let* ((name (nth 1 (nth 1 form)))
-	 (elt (list name (copy-symbol name) nil))
-	 (byte-compile-active-blocks (cons elt byte-compile-active-blocks))
-	 (body (byte-compile-top-level (cons 'progn (cddr form)))))
-    (if (nth 2 elt)
-	(byte-compile-catch `(catch ',(nth 1 elt) ,body))
-      (byte-compile-form body))))
-
-(defun byte-compile-return-from-1 (form)
-  (let* ((name (nth 1 (nth 1 form)))
-	 (assq (assq name byte-compile-active-blocks)))
-    (if assq
-	(setf (nth 2 assq) t)
-      (byte-compile-warn
-       "return-from: %S: no current lexical block with this name"
-       name))
-    (byte-compile-throw
-     `(throw ',(or (nth 1 assq) (copy-symbol name))
-             ,@(nthcdr 2 form)))))
+  "Byte-compile and return a `catch' from.
+
+If FORM is the result of macroexpanding a `block' form (the TAG argument is
+a quoted symbol with a non-nil `cl-block-name' property) and there is no
+corresponding `return-from' within the block--or equivalently, it was
+optimized away--just byte compile and return the BODY."
+  (let* ((symbol (car-safe (cdr-safe (nth 1 form))))
+	 (block (and symbol (symbolp symbol) (get symbol 'cl-block-name)))
+	 (elt (and block (cons block nil)))
+	 (byte-compile-active-blocks
+	  (if block
+	      (cons elt byte-compile-active-blocks)
+	    byte-compile-active-blocks))
+	 (body
+	  (byte-compile-top-level (cons 'progn (cddr form))
+				  (if block nil for-effect))))
+    (if (and block (not (cdr elt)))
+	;; A lexical block without any contained return-from clauses:
+	(byte-compile-form body)
+      ;; A normal catch call, or a lexical block with a contained
+      ;; return-from clause.
+      (byte-compile-form (car (cdr form)))
+      (byte-compile-push-constant body)
+      (byte-compile-out 'byte-catch 0))))
 
 (defun byte-compile-unwind-protect (form)
   (byte-compile-push-constant
@@ -4381,6 +4364,12 @@
         (byte-compile-normal-call
          `(signal 'wrong-number-of-arguments '(,(car form)
                                                ,(length (cdr form))))))
+    ;; If this form was macroexpanded from `return-from', mark the
+    ;; corresponding block as having been referenced.
+    (let* ((symbol (car-safe (cdr-safe (nth 1 form))))
+	   (block (and symbol (symbolp symbol) (get symbol 'cl-block-name)))
+	   (assq (and block (assq block byte-compile-active-blocks))))
+      (and assq (setcdr assq t)))
     (byte-compile-form (nth 1 form))  ;; Push the arguments
     (byte-compile-form (nth 2 form))
     (byte-compile-out (get (car form) 'byte-opcode) 0)
--- a/lisp/cl-macs.el	Mon Feb 07 21:22:17 2011 +0100
+++ b/lisp/cl-macs.el	Mon Feb 14 22:43:46 2011 +0100
@@ -745,6 +745,9 @@
   (let ((cl-active-block-names (acons name (copy-symbol name)
 				      cl-active-block-names))
 	(body (cons 'progn body)))
+    ;; Tell the byte-compiler this is a block, not a normal catch call, and
+    ;; as such it can eliminate it if that's appropriate:
+    (put (cdar cl-active-block-names) 'cl-block-name name)
     `(catch ',(cdar cl-active-block-names)
       ,(cl-macroexpand-all body cl-macro-environment))))
 
@@ -761,8 +764,13 @@
 returning RESULT from that form (or nil if RESULT is omitted).
 This is compatible with Common Lisp, but note that `defun' and
 `defmacro' do not create implicit blocks as they do in Common Lisp."
-  `(throw ',(or (cdr (assq name cl-active-block-names)) (copy-symbol name))
-	  ,result))
+  `(throw ',(or (cdr (assq name cl-active-block-names))
+		(prog1 (copy-symbol name)
+		  (and-fboundp 'byte-compile-warn (cl-compiling-file)
+			       (byte-compile-warn
+				"return-from: no enclosing block named `%s'"
+				name))))
+	 ,result))
 
 ;;; The "loop" macro.
 
--- a/lisp/cl.el	Mon Feb 07 21:22:17 2011 +0100
+++ b/lisp/cl.el	Mon Feb 14 22:43:46 2011 +0100
@@ -542,9 +542,7 @@
 (defalias 'cl-round 'round*)
 (defalias 'cl-mod 'mod*)
 
-(defun acons (key value alist)
-  "Return a new alist created by adding (KEY . VALUE) to ALIST."
-  (cons (cons key value) alist))
+;;; XEmacs; #'acons is in C.
 
 (defun pairlis (keys values &optional alist)
   "Make an alist from KEYS and VALUES.
--- a/src/ChangeLog	Mon Feb 07 21:22:17 2011 +0100
+++ b/src/ChangeLog	Mon Feb 14 22:43:46 2011 +0100
@@ -1,3 +1,20 @@
+2011-02-10  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (shortest_length_among_sequences):
+	This was buggy, it always errored if the last argument was
+	circular, even if other arguments were non-circular. Correct that.
+
+2011-02-09  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* alloc.c (Facons):
+	* alloc.c (Fobject_memory_usage):
+	* alloc.c (syms_of_alloc):
+	* faces.c (complex_vars_of_faces):
+	* lisp.h:
+	* mc-alloc.c (Fmc_alloc_memory_usage):
+	Rename acons() to Facons(), make it visible to Lisp. Change uses
+	of the function in C accordingly.
+
 2011-02-07  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* keymap.c (describe_map_sort_predicate): Correct the order of
--- a/src/alloc.c	Mon Feb 07 21:22:17 2011 +0100
+++ b/src/alloc.c	Mon Feb 14 22:43:46 2011 +0100
@@ -1426,8 +1426,10 @@
   return Fcons (obj0, Fcons (obj1, obj2));
 }
 
-Lisp_Object
-acons (Lisp_Object key, Lisp_Object value, Lisp_Object alist)
+DEFUN ("acons", Facons, 3, 3, 0, /*
+Return a new alist created by prepending (KEY . VALUE) to ALIST.
+*/
+       (key, value, alist))
 {
   return Fcons (Fcons (key, value), alist);
 }
@@ -4195,10 +4197,10 @@
   xzero (object_stats);
   lisp_object_storage_size (object, &object_stats);
 
-  val = acons (Qobject_actually_requested,
-	       make_int (object_stats.was_requested), val);
-  val = acons (Qobject_malloc_overhead,
-	       make_int (object_stats.malloc_overhead), val);
+  val = Facons (Qobject_actually_requested,
+		make_int (object_stats.was_requested), val);
+  val = Facons (Qobject_malloc_overhead,
+		make_int (object_stats.malloc_overhead), val);
   assert (!object_stats.dynarr_overhead);
   assert (!object_stats.gap_overhead);
 
@@ -4208,16 +4210,16 @@
       MAYBE_OBJECT_METH (object, memory_usage, (object, &gustats));
 
       val = Fcons (Qt, val);
-      val = acons (Qother_memory_actually_requested,
-		   make_int (gustats.u.was_requested), val);
-      val = acons (Qother_memory_malloc_overhead,
-		   make_int (gustats.u.malloc_overhead), val);
+      val = Facons (Qother_memory_actually_requested,
+		    make_int (gustats.u.was_requested), val);
+      val = Facons (Qother_memory_malloc_overhead,
+		    make_int (gustats.u.malloc_overhead), val);
       if (gustats.u.dynarr_overhead)
-	val = acons (Qother_memory_dynarr_overhead,
-		     make_int (gustats.u.dynarr_overhead), val);
+	val = Facons (Qother_memory_dynarr_overhead,
+		      make_int (gustats.u.dynarr_overhead), val);
       if (gustats.u.gap_overhead)
-	val = acons (Qother_memory_gap_overhead,
-		     make_int (gustats.u.gap_overhead), val);
+	val = Facons (Qother_memory_gap_overhead,
+		      make_int (gustats.u.gap_overhead), val);
       val = Fcons (Qnil, val);
 
       i = 0;
@@ -4228,7 +4230,7 @@
 	      val = Fcons (item, val);
 	    else
 	      {
-		val = acons (item, make_int (gustats.othervals[i]), val);
+		val = Facons (item, make_int (gustats.othervals[i]), val);
 		i++;
 	      }
 	  }
@@ -5699,6 +5701,7 @@
 
   DEFSUBR (Fcons);
   DEFSUBR (Flist);
+  DEFSUBR (Facons);
   DEFSUBR (Fvector);
   DEFSUBR (Fbit_vector);
   DEFSUBR (Fmake_byte_code);
--- a/src/faces.c	Mon Feb 07 21:22:17 2011 +0100
+++ b/src/faces.c	Mon Feb 14 22:43:46 2011 +0100
@@ -2264,22 +2264,22 @@
     Lisp_Object fg_fb = Qnil, bg_fb = Qnil;
 
 #ifdef HAVE_GTK
-    fg_fb = acons (list1 (Qgtk), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qgtk), build_ascstring ("white"), bg_fb);
+    fg_fb = Facons (list1 (Qgtk), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qgtk), build_ascstring ("white"), bg_fb);
 #endif
 #ifdef HAVE_X_WINDOWS
-    fg_fb = acons (list1 (Qx), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qx), build_ascstring ("gray80"), bg_fb);
+    fg_fb = Facons (list1 (Qx), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qx), build_ascstring ("gray80"), bg_fb);
 #endif
 #ifdef HAVE_TTY
-    fg_fb = acons (list1 (Qtty), Fvector (0, 0), fg_fb);
-    bg_fb = acons (list1 (Qtty), Fvector (0, 0), bg_fb);
+    fg_fb = Facons (list1 (Qtty), Fvector (0, 0), fg_fb);
+    bg_fb = Facons (list1 (Qtty), Fvector (0, 0), bg_fb);
 #endif
 #ifdef HAVE_MS_WINDOWS
-    fg_fb = acons (list1 (Qmsprinter), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qmsprinter), build_ascstring ("white"), bg_fb);
-    fg_fb = acons (list1 (Qmswindows), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qmswindows), build_ascstring ("white"), bg_fb);
+    fg_fb = Facons (list1 (Qmsprinter), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qmsprinter), build_ascstring ("white"), bg_fb);
+    fg_fb = Facons (list1 (Qmswindows), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qmswindows), build_ascstring ("white"), bg_fb);
 #endif
     set_specifier_fallback (Fget (Vdefault_face, Qforeground, Qnil), fg_fb);
     set_specifier_fallback (Fget (Vdefault_face, Qbackground, Qnil), bg_fb);
@@ -2517,22 +2517,22 @@
     /* We need to put something in there, or error checking gets
        #%!@#ed up before the styles are set, which override the
        fallbacks. */
-    fg_fb = acons (list1 (Qgtk), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qgtk), build_ascstring ("Gray80"), bg_fb);
+    fg_fb = Facons (list1 (Qgtk), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qgtk), build_ascstring ("Gray80"), bg_fb);
 #endif
 #ifdef HAVE_X_WINDOWS
-    fg_fb = acons (list1 (Qx), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qx), build_ascstring ("Gray80"), bg_fb);
+    fg_fb = Facons (list1 (Qx), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qx), build_ascstring ("Gray80"), bg_fb);
 #endif
 #ifdef HAVE_TTY
-    fg_fb = acons (list1 (Qtty), Fvector (0, 0), fg_fb);
-    bg_fb = acons (list1 (Qtty), Fvector (0, 0), bg_fb);
+    fg_fb = Facons (list1 (Qtty), Fvector (0, 0), fg_fb);
+    bg_fb = Facons (list1 (Qtty), Fvector (0, 0), bg_fb);
 #endif
 #ifdef HAVE_MS_WINDOWS
-    fg_fb = acons (list1 (Qmsprinter), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qmsprinter), build_ascstring ("white"), bg_fb);
-    fg_fb = acons (list1 (Qmswindows), build_ascstring ("black"), fg_fb);
-    bg_fb = acons (list1 (Qmswindows), build_ascstring ("Gray75"), bg_fb);
+    fg_fb = Facons (list1 (Qmsprinter), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qmsprinter), build_ascstring ("white"), bg_fb);
+    fg_fb = Facons (list1 (Qmswindows), build_ascstring ("black"), fg_fb);
+    bg_fb = Facons (list1 (Qmswindows), build_ascstring ("Gray75"), bg_fb);
 #endif
     set_specifier_fallback (Fget (Vgui_element_face, Qforeground, Qnil), fg_fb);
     set_specifier_fallback (Fget (Vgui_element_face, Qbackground, Qnil), bg_fb);
--- a/src/fns.c	Mon Feb 07 21:22:17 2011 +0100
+++ b/src/fns.c	Mon Feb 14 22:43:46 2011 +0100
@@ -7143,7 +7143,7 @@
 static Elemcount
 shortest_length_among_sequences (int nsequences, Lisp_Object *sequences)
 {
-  Elemcount len = EMACS_INT_MAX;
+  Elemcount len = 1 + EMACS_INT_MAX;
   Lisp_Object length = Qnil;
   int i;
 
@@ -7165,7 +7165,7 @@
         }
     }
 
-  if (NILP (length))
+  if (len == 1 + EMACS_INT_MAX)
     {
       signal_circular_list_error (sequences[0]);
     }
--- a/src/lisp.h	Mon Feb 07 21:22:17 2011 +0100
+++ b/src/lisp.h	Mon Feb 14 22:43:46 2011 +0100
@@ -4273,6 +4273,7 @@
 /* Defined in alloc.c */
 MODULE_API EXFUN (Fcons, 2);
 MODULE_API EXFUN (Flist, MANY);
+MODULE_API EXFUN (Facons, 3);
 EXFUN (Fbit_vector, MANY);
 EXFUN (Fmake_byte_code, MANY);
 MODULE_API EXFUN (Fmake_list, 2);
@@ -4297,7 +4298,6 @@
 #ifndef NEW_GC
 void garbage_collect_1 (void);
 #endif /* not NEW_GC */
-MODULE_API Lisp_Object acons (Lisp_Object, Lisp_Object, Lisp_Object);
 MODULE_API Lisp_Object cons3 (Lisp_Object, Lisp_Object, Lisp_Object);
 MODULE_API Lisp_Object list1 (Lisp_Object);
 MODULE_API Lisp_Object list2 (Lisp_Object, Lisp_Object);
--- a/src/mc-alloc.c	Mon Feb 07 21:22:17 2011 +0100
+++ b/src/mc-alloc.c	Mon Feb 14 22:43:46 2011 +0100
@@ -1985,29 +1985,29 @@
   for (i = 0; i < N_FREE_PAGE_LISTS; i++) 
     if (PLH_PAGE_COUNT (FREE_HEAP_PAGES(i)) > 0)
       free_plhs = 
-	acons (make_int (PLH_SIZE (FREE_HEAP_PAGES(i))),
-	       list1 (make_int (PLH_PAGE_COUNT (FREE_HEAP_PAGES(i)))),
-	       free_plhs);
+	Facons (make_int (PLH_SIZE (FREE_HEAP_PAGES(i))),
+		list1 (make_int (PLH_PAGE_COUNT (FREE_HEAP_PAGES(i)))),
+		free_plhs);
 
   for (i = 0; i < N_USED_PAGE_LISTS; i++) 
     if (PLH_PAGE_COUNT (USED_HEAP_PAGES(i)) > 0)
       used_plhs = 
-	acons (make_int (PLH_SIZE (USED_HEAP_PAGES(i))),
-	       list5 (make_int (PLH_PAGE_COUNT (USED_HEAP_PAGES(i))),
-		      make_int (PLH_USED_CELLS (USED_HEAP_PAGES(i))),
-		      make_int (PLH_USED_SPACE (USED_HEAP_PAGES(i))),
-		      make_int (PLH_TOTAL_CELLS (USED_HEAP_PAGES(i))),
-		      make_int (PLH_TOTAL_SPACE (USED_HEAP_PAGES(i)))),
-	       used_plhs);
+	Facons (make_int (PLH_SIZE (USED_HEAP_PAGES(i))),
+		list5 (make_int (PLH_PAGE_COUNT (USED_HEAP_PAGES(i))),
+		       make_int (PLH_USED_CELLS (USED_HEAP_PAGES(i))),
+		       make_int (PLH_USED_SPACE (USED_HEAP_PAGES(i))),
+		       make_int (PLH_TOTAL_CELLS (USED_HEAP_PAGES(i))),
+		       make_int (PLH_TOTAL_SPACE (USED_HEAP_PAGES(i)))),
+		used_plhs);
 
   used_plhs =
-    acons (make_int (0),
-	   list5 (make_int (PLH_PAGE_COUNT(ARRAY_HEAP_PAGES)),
-		  make_int (PLH_USED_CELLS (ARRAY_HEAP_PAGES)),
-		  make_int (PLH_USED_SPACE (ARRAY_HEAP_PAGES)),
-		  make_int (PLH_TOTAL_CELLS (ARRAY_HEAP_PAGES)),
-		  make_int (PLH_TOTAL_SPACE (ARRAY_HEAP_PAGES))),
-	   used_plhs);
+    Facons (make_int (0),
+	    list5 (make_int (PLH_PAGE_COUNT(ARRAY_HEAP_PAGES)),
+		   make_int (PLH_USED_CELLS (ARRAY_HEAP_PAGES)),
+		   make_int (PLH_USED_SPACE (ARRAY_HEAP_PAGES)),
+		   make_int (PLH_TOTAL_CELLS (ARRAY_HEAP_PAGES)),
+		   make_int (PLH_TOTAL_SPACE (ARRAY_HEAP_PAGES))),
+	    used_plhs);
   
   for (i = 0; i < N_HEAP_SECTIONS; i++) {
     used_size += HEAP_SECTION(i).n_pages * PAGE_SIZE;
--- a/tests/ChangeLog	Mon Feb 07 21:22:17 2011 +0100
+++ b/tests/ChangeLog	Mon Feb 14 22:43:46 2011 +0100
@@ -1,3 +1,11 @@
+2011-02-10  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	* automated/lisp-tests.el (mapcar*):
+	If multiple SEQUENCE arguments are passed to #'mapcar*, and the
+	last one is circular while the others aren't, make sure that
+	#'mapcar* doesn't error.
+
 2011-02-07  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* automated/lisp-tests.el:
--- a/tests/automated/lisp-tests.el	Mon Feb 07 21:22:17 2011 +0100
+++ b/tests/automated/lisp-tests.el	Mon Feb 14 22:43:46 2011 +0100
@@ -1044,6 +1044,12 @@
       (car y))
     x)))
 
+(Assert
+ (equal
+  (let ((list (list pi))) (mapcar* #'cons [1 2 3 4] (nconc list list)))
+  `((1 . ,pi) (2 . ,pi) (3 . ,pi) (4 . ,pi)))
+ "checking mapcar* behaves correctly when only one arg is circular")
+
 (Assert (eql
  (length (multiple-value-list
           (car (mapcar #'(lambda (argument) (floor argument)) (list pi e)))))