src/c-types-impl.lisp: Refactor pretty-printing of function types.
[sod] / src / c-types-parse.lisp
index 42a23d3..b9a53db 100644 (file)
@@ -70,7 +70,7 @@
   ;; accessor functions later.
   ((label :type keyword :initarg :label :reader ds-label)
    (name :type string :initarg :name :reader ds-name)
   ;; accessor functions later.
   ((label :type keyword :initarg :label :reader ds-label)
    (name :type string :initarg :name :reader ds-name)
-   (kind :type (member type sign size qualifier)
+   (kind :type (member type complexity sign size qualifier)
         :initarg :kind :reader ds-kind)
    (taggedp :type boolean :initarg :taggedp
            :initform nil :reader ds-taggedp))
         :initarg :kind :reader ds-kind)
    (taggedp :type boolean :initarg :taggedp
            :initform nil :reader ds-taggedp))
 
 (defparameter *declspec-map*
   (let ((map (make-hash-table :test #'equal)))
 
 (defparameter *declspec-map*
   (let ((map (make-hash-table :test #'equal)))
-    (dolist (item '((type :void :char :int :float :double)
+    (dolist (item '((type :void :char :int :float :double
+                         (:bool :name "_Bool"))
+                   (complexity (:complex :name "_Complex")
+                               (:imaginary :name "_Imaginary"))
                    ((type :taggedp t) :enum :struct :union)
                    (size :short :long (:long-long :name "long long"))
                    (sign :signed :unsigned)
                    ((type :taggedp t) :enum :struct :union)
                    (size :short :long (:long-long :name "long long"))
                    (sign :signed :unsigned)
                                     :taggedp taggedp)))
              (setf (gethash name map) ds
                    (gethash label map) ds))))))
                                     :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)))
     map)
   "Maps symbolic labels and textual names to `declspec' instances.")
 
     map)
   "Maps symbolic labels and textual names to `declspec' instances.")
 
   ;; This could have been done with `defstruct' just as well, but a
   ;; `defclass' can be tweaked interactively, which is a win at the moment.
   ((type :initform nil :initarg :type :reader ds-type)
   ;; This could have been done with `defstruct' just as well, but a
   ;; `defclass' can be tweaked interactively, which is a win at the moment.
   ((type :initform nil :initarg :type :reader ds-type)
+   (complexity :initform nil :initarg :complexity :reader ds-complexity)
    (sign :initform nil :initarg :sign :reader ds-sign)
    (size :initform nil :initarg :size :reader ds-size)
    (qualifier :initform nil :initarg :qualifiers :reader ds-qualifiers))
    (sign :initform nil :initarg :sign :reader ds-sign)
    (size :initform nil :initarg :size :reader ds-size)
    (qualifier :initform nil :initarg :qualifiers :reader ds-qualifiers))
 (defmethod ds-kind ((ty c-type)) 'type)
 
 (defparameter *good-declspecs*
 (defmethod ds-kind ((ty c-type)) 'type)
 
 (defparameter *good-declspecs*
-  '(((:int) (:signed :unsigned) (:short :long :long-long))
-    ((:char) (:signed :unsigned) ())
-    ((:double) () (:long))
-    (t () ()))
+  '(((:int) (:signed :unsigned) (:short :long :long-long) ())
+    ((:char) (:signed :unsigned) () ())
+    ((:double) () (:long) (:complex :imaginary))
+    (t () () ()))
   "List of good collections of declaration specifiers.
 
   "List of good collections of declaration specifiers.
 
-   Each item is a list of the form (TYPES SIGNS SIZES).  Each of TYPES, SIGNS
-   and SIZES is either a list of acceptable specifiers of the appropriate
-   kind, or T, which matches any specifier.")
+   Each item is a list of the form (TYPES SIGNS SIZES COMPLEXITIES).  Each of
+   TYPES, SIGNS, SIZES, and COMPLEXITIES, is either a list of acceptable
+   specifiers of the appropriate kind, or T, which matches any specifier.")
 
 (defun good-declspecs-p (specs)
   "Are SPECS a good collection of declaration specifiers?"
 
 (defun good-declspecs-p (specs)
   "Are SPECS a good collection of declaration specifiers?"
-  (let ((speclist (list (ds-type specs) (ds-sign specs) (ds-size specs))))
+  (let ((speclist (list (ds-type specs)
+                       (ds-sign specs)
+                       (ds-size specs)
+                       (ds-complexity specs))))
     (some (lambda (it)
            (every (lambda (spec pat)
                     (or (eq pat t) (null spec)
     (some (lambda (it)
            (every (lambda (spec pat)
                     (or (eq pat t) (null spec)
   (let ((type (ds-type specs))
        (size (ds-size specs))
        (sign (ds-sign specs))
   (let ((type (ds-type specs))
        (size (ds-size specs))
        (sign (ds-sign specs))
+       (cplx (ds-complexity specs))
        (quals (mapcar #'ds-label (ds-qualifiers specs))))
     (cond ((typep type 'c-type)
           (qualify-c-type type quals))
        (quals (mapcar #'ds-label (ds-qualifiers specs))))
     (cond ((typep type 'c-type)
           (qualify-c-type type quals))
-         ((or type size sign)
+         ((or type size sign cplx)
           (when (and sign (eq (ds-label sign) :signed)
                      (eq (ds-label type) :int))
             (setf sign nil))
           (when (and sign (eq (ds-label sign) :signed)
                      (eq (ds-label type) :int))
             (setf sign nil))
           (make-simple-type (format nil "~{~@[~A~^ ~]~}"
                                     (mapcar #'ds-name
                                             (remove nil
           (make-simple-type (format nil "~{~@[~A~^ ~]~}"
                                     (mapcar #'ds-name
                                             (remove nil
-                                                    (list sign size type))))
+                                                    (list sign cplx
+                                                          size type))))
                             quals))
          (t
           nil))))
                             quals))
          (t
           nil))))
   ;; Turns out to be easier to do this by hand.
   (let ((ds (and (eq (token-type scanner) :id)
                 (let ((kw (token-value scanner)))
   ;; 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))
                       (gethash kw *declspec-map*))))))
     (cond ((or (not ds) (and predicate (not (funcall predicate ds))))
           (values (list indicator) nil nil))