From: Mark Wooding Date: Sun, 30 Aug 2015 09:58:38 +0000 (+0100) Subject: src/c-types-parse.lisp: Handle `...' in prefix-`(' disambiguation. X-Git-Tag: 0.2.0~12 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/commitdiff_plain/c28f6ae9d1bb9027ce143714b66673a5208cf5fe src/c-types-parse.lisp: Handle `...' in prefix-`(' disambiguation. 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.) --- diff --git a/src/c-types-parse.lisp b/src/c-types-parse.lisp index e0cfc88..45336a1 100644 --- a/src/c-types-parse.lisp +++ b/src/c-types-parse.lisp @@ -336,13 +336,18 @@ (defun parse-declarator (scanner base-type &key kernel abstractp) (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: `(' @@ -357,7 +362,7 @@ (defun parse-declarator (scanner base-type &key kernel abstractp) ;; 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 #\))))))