src/c-types-parse.lisp: Hoist up the `ds-FOO' methods for raw types.
[sod] / src / c-types-parse.lisp
index 0a6b5ab..4475c72 100644 (file)
@@ -77,8 +77,8 @@
   (:documentation
    "Represents the important components of a declaration specifier.
 
-    The only interesting instances of this class are in the table
-    `*declspec-map*'."))
+   The only interesting instances of this class are in the table
+   `*declspec-map*'."))
 
 (defmethod shared-initialize :after ((ds declspec) slot-names &key)
   "If no name is provided then derive one from the label.
@@ -90,9 +90,9 @@
 (defparameter *declspec-map*
   (let ((map (make-hash-table :test #'equal)))
     (dolist (item '((type :void :char :int :float :double
-                         (:bool :name "_Bool"))
-                   (complexity (:complex :name "_Complex")
-                               (:imaginary :name "_Imaginary"))
+                         (:bool :compat "_Bool"))
+                   (complexity (:complex :compat "_Complex")
+                               (:imaginary :compat "_Imaginary"))
                    ((type :taggedp t) :enum :struct :union)
                    (size :short :long (:long-long :name "long long"))
                    (sign :signed :unsigned)
          (destructuring-bind (label
                               &key
                               (name (string-downcase label))
+                              compat
                               (taggedp taggedp))
              (if (consp spec) spec (list spec))
            (let ((ds (make-instance 'declspec
                                     :label label
-                                    :name name
+                                    :name (or compat name)
                                     :kind kind
                                     :taggedp taggedp)))
              (setf (gethash name map) ds
-                   (gethash label map) ds))))))
-    (dolist (label '(:complex :imaginary :bool))
-      (setf (gethash (string-downcase label) map) (gethash label map)))
+                   (gethash label map) ds)
+             (when compat
+               (setf (gethash compat map) ds)))))))
     map)
   "Maps symbolic labels and textual names to `declspec' instances.")
 
+(defmethod ds-label ((ty c-type)) :c-type)
+(defmethod ds-name ((ty c-type)) (princ-to-string ty))
+(defmethod ds-kind ((ty c-type)) 'type)
+
 ;; A collection of declaration specifiers, and how to merge them together.
 
 (defclass declspecs ()
    (sign :initform nil :initarg :sign :reader ds-sign)
    (size :initform nil :initarg :size :reader ds-size)
    (qualifier :initform nil :initarg :qualifiers :reader ds-qualifiers))
-  (:documentation
-   "Represents a collection of declaration specifiers.
+  (:documentation "Represents a collection of declaration specifiers.
 
-    This is used during type parsing to represent the type under
-    construction.  Instances are immutable: we build new ones rather than
-    modifying existing ones.  This leads to a certain amount of churn, but
-    we'll just have to live with that.
+   This is used during type parsing to represent the type under construction.
+   Instances are immutable: we build new ones rather than modifying existing
+   ones.  This leads to a certain amount of churn, but we'll just have to
+   live with that.
 
-    (Why are instances immutable?  Because it's much easier to merge a new
-    specifier into an existing collection and then check that the resulting
-    thing is valid, rather than having to deal with all of the possible
-    special cases of what the new thing might be.  And if the merged
-    collection isn't good, I must roll back to the previous version.  So I
-    don't get to take advantage of a mutable structure.)"))
-
-(defmethod ds-label ((ty c-type)) :c-type)
-(defmethod ds-name ((ty c-type)) (princ-to-string ty))
-(defmethod ds-kind ((ty c-type)) 'type)
+   (Why are instances immutable?  Because it's much easier to merge a new
+   specifier into an existing collection and then check that the resulting
+   thing is valid, rather than having to deal with all of the possible
+   special cases of what the new thing might be.  And if the merged
+   collection isn't good, I must roll back to the previous version.  So I
+   don't get to take advantage of a mutable structure.)"))
 
 (defparameter *good-declspecs*
   '(((:int) (:signed :unsigned) (:short :long :long-long) ())
   ;; Turns out to be easier to do this by hand.
   (let ((ds (and (eq (token-type scanner) :id)
                 (let ((kw (token-value scanner)))
-                  (or (gethash kw *module-type-map*)
+                  (or (and (boundp '*module-type-map*)
+                           (gethash kw *module-type-map*))
                       (gethash kw *declspec-map*))))))
     (cond ((or (not ds) (and predicate (not (funcall predicate ds))))
           (values (list indicator) nil nil))