src/c-types-parse.lisp: Handle `...' in prefix-`(' disambiguation.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 30 Aug 2015 09:58:38 +0000 (10:58 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 6 Sep 2015 20:36:25 +0000 (21:36 +0100)
Now that we've actually got the machinery to parse ellipses in function
argument lists, it'd be nice to do it properly.

(I think -- but I might be wrong -- that the reason this wasn't done
before is that C doesn't let you put `...' as the only thing in an
argument list, because you need to have a named argument to initialize
the `va_list'.  But Sod can, and does, because there's always at least a
receiver argument.)

src/c-types-parse.lisp

index e0cfc88..45336a1 100644 (file)
                                             (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 #\))))))