;;;----- Licensing notice ---------------------------------------------------
;;;
-;;; This file is part of the Sensble Object Design, an object system for C.
+;;; This file is part of the Sensible Object Design, an object system for C.
;;;
;;; SOD is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
(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)
: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.")
;; 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))
(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.
- 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?"
- (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)
(make-pointer-type type quals)))
(cdr state))))))
- (next-declspec-p ()
- ;; Ansert whether the next token is a valid declaration
- ;; specifier, without consuming it.
- (and (eq (token-type scanner) :id)
- (let ((id (token-value scanner)))
- (or (gethash id *module-type-map*)
- (gethash id *declspec-map*)))))
+ (predict-argument-list-p ()
+ ;; See `prefix-lparen'. Predict an argument list rather
+ ;; than a nested declarator if (a) abstract declarators are
+ ;; permitted and (b) the next token is a declaration
+ ;; specifier or ellipsis.
+ (let ((type (token-type scanner))
+ (value (token-value scanner)))
+ (and abstractp
+ (or (eq type :ellipsis)
+ (and (eq type :id)
+ (or (gethash value *module-type-map*)
+ (gethash value *declspec-map*)))))))
(prefix-lparen ()
;; Prefix: `('
;; specifier, then we have a postfix argument list.
(parse
(peek (seq (#\(
- (nil (if (and abstractp (next-declspec-p))
+ (nil (if (predict-argument-list-p)
(values nil nil nil)
(values t t nil))))
(lparen #\))))))
(cons #'identity name))))
(argument-list ()
- ;; [ argument [ `,' argument ]* [ `,' `...' ] ] | `...'
+ ;; [argument [`,' argument]* [`,' `...']] | `...'
;;
;; The possibility of a trailing `,' `...' means that we
;; can't use the standard `list' parser. Note that, unlike