From 01778b39c53316dda3f757c49276d034039ee9cb Mon Sep 17 00:00:00 2001
From: Mark Wooding <mdw@distorted.org.uk>
Date: Sun, 26 Mar 2017 15:16:18 +0100
Subject: [PATCH] src/c-types-impl.lisp: Reorder `merge-keyword-lists' input
 lists.

Prepend the `what' argument to the front of each argument list, rather
than having a (LIST . WHAT) pair.  Also, internally to
`merge-keyword-lists', keep the entries in the hash table as
(WHAT . ARG) rather than the other way around.
---
 doc/clang.tex         | 10 +++++-----
 src/builtin.lisp      |  8 ++++----
 src/c-types-impl.lisp | 24 ++++++++++++------------
 src/method-impl.lisp  | 12 ++++++------
 src/method-proto.lisp |  4 ++--
 5 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/doc/clang.tex b/doc/clang.tex
index ebe9d4e..18a8e1c 100644
--- a/doc/clang.tex
+++ b/doc/clang.tex
@@ -1020,11 +1020,11 @@ function type is the type of the function's return value.
 \begin{describe}{fun}{merge-keyword-lists @<lists> @> @<list>}
   Merge a number of keyword-argument lists together and return the result.
 
-  The @<lists> parameter is a list consisting of a number of @|(@<args>
-  . @<origin>)| pairs: in each pair, @<args> is a list of
-  \descref{argument}{cls} objects, and @<origin> is either nil or an object
-  whose printed representation describes the origin of the corresponding
-  @<args> list, suitable for inclusion in an error message.
+  The @<lists> parameter is a list consisting of a number of @|(@<origin>
+  . @<args>)| pairs: in each pair, @<origin> is either nil or an object whose
+  printed representation describes the origin of the corresponding @<args>
+  list suitable for inclusion in an error message, and @<args> is a list of
+  \descref{argument}{cls} objects.
 
   The resulting list contains exactly one argument for each distinct argument
   name appearing in the input @<lists>; this argument will contain the
diff --git a/src/builtin.lisp b/src/builtin.lisp
index 4d5b5cd..77eca39 100644
--- a/src/builtin.lisp
+++ b/src/builtin.lisp
@@ -300,10 +300,10 @@ static const SodClass *const ~A__cpl[] = {
 	  (mapcan (lambda (class)
 		    (let ((initargs (sod-class-initargs class)))
 		      (and initargs
-			   (list (cons (mapcar #'sod-initarg-argument
-					       initargs)
-				       (format nil "initargs for ~A"
-					       class))))))
+			   (list (cons (format nil "initargs for ~A"
+					       class)
+				       (mapcar #'sod-initarg-argument
+					       initargs))))))
 		  (sod-class-precedence-list
 		   (effective-method-class method)))))
 
diff --git a/src/c-types-impl.lisp b/src/c-types-impl.lisp
index 6b7c904..e87964c 100644
--- a/src/c-types-impl.lisp
+++ b/src/c-types-impl.lisp
@@ -592,10 +592,10 @@
 (defun merge-keyword-lists (lists)
   "Return the union of keyword argument lists.
 
-   The LISTS parameter consists of pairs (ARGS . WHAT), where ARGS is a list
-   of `argument' objects, and WHAT is either nil or a printable object
-   describing the origin of the corresponding argument list suitable for
-   quoting in an error message.
+   The LISTS parameter consists of pairs (WHAT . ARGS), where WHAT is either
+   nil or a printable object describing the origin of this argument list
+   suitable for inclusion in an error message, and ARGS is a list of
+   `argument' objects.
 
    The resulting list contains exactly one argument for each distinct
    argument name appearing in the input lists; this argument will contain the
@@ -607,24 +607,24 @@
    conflicting pair of arguments."
 
   ;; The easy way through all of this is with a hash table mapping argument
-  ;; names to (ARGUMENT . WHAT) pairs.
+  ;; names to (WHAT . ARG) pairs.
 
   (let ((argmap (make-hash-table :test #'equal)))
 
     ;; Set up the table.  When we find a duplicate, check that the types
     ;; match.
     (dolist (item lists)
-      (let ((args (car item))
-	    (what (cdr item)))
+      (let ((what (car item))
+	    (args (cdr item)))
 	(dolist (arg args)
 	  (let* ((name (argument-name arg))
 		 (other-item (gethash name argmap)))
 	    (if (null other-item)
-		(setf (gethash name argmap) (cons arg what))
+		(setf (gethash name argmap) (cons what arg))
 		(let* ((type (argument-type arg))
-		       (other (car other-item))
-		       (other-type (argument-type other))
-		       (other-what (cdr other-item)))
+		       (other-what (car other-item))
+		       (other (cdr other-item))
+		       (other-type (argument-type other)))
 		  (unless (c-type-equal-p type other-type)
 		    (error "Type mismatch for keyword argument `~A': ~
 			    ~A~@[ (~A)~] doesn't match ~A~@[ (~A)~]"
@@ -636,7 +636,7 @@
     (let ((result nil))
       (maphash (lambda (name item)
 		 (declare (ignore name))
-		 (push (car item) result))
+		 (push (cdr item) result))
 	       argmap)
       (fix-and-check-keyword-argument-list result))))
 
diff --git a/src/method-impl.lisp b/src/method-impl.lisp
index e3fb6ae..16ae56e 100644
--- a/src/method-impl.lisp
+++ b/src/method-impl.lisp
@@ -253,15 +253,15 @@
     ((method effective-method) direct-methods)
   (with-slots (message) method
     (and (keyword-message-p message)
-	 (cons (cons (c-function-keywords (sod-message-type message))
-		     (format nil "message ~A (at ~A)"
-			     message (file-location message)))
+	 (cons (cons (format nil "message ~A (at ~A)"
+			     message (file-location message))
+		     (c-function-keywords (sod-message-type message)))
 	       (mapcar (lambda (m)
-			 (cons (c-function-keywords (sod-method-type m))
-			       (format nil "method for ~A on ~A (at ~A)"
+			 (cons (format nil "method for ~A on ~A (at ~A)"
 				       message
 				       (sod-method-class m)
-				       (file-location m))))
+				       (file-location m))
+			       (c-function-keywords (sod-method-type m))))
 		       direct-methods)))))
 
 (defmethod shared-initialize :after
diff --git a/src/method-proto.lisp b/src/method-proto.lisp
index 2d5f471..a986584 100644
--- a/src/method-proto.lisp
+++ b/src/method-proto.lisp
@@ -69,8 +69,8 @@
    "Returns a list of keyword argument lists to be merged.
 
    This should return a list suitable for passing to `merge-keyword-lists',
-   i.e., each element should be a pair consisting of a list of `argument'
-   objects and a string describing the source of the argument list."))
+   i.e., each element should be a pair consisting of a string describing the
+   source of the argument list, and a list of `argument' objects."))
 
 (export 'compute-sod-effective-method)
 (defgeneric compute-sod-effective-method (message class)
-- 
2.11.0

