From: Mark Wooding Date: Sun, 30 Aug 2015 09:58:38 +0000 (+0100) Subject: src/c-types-parse.lisp: Parse `...' in argument lists. X-Git-Tag: 0.2.0~30 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/commitdiff_plain/b0ff693c25bf81f935efa15a44fdad6ce95e9f91 src/c-types-parse.lisp: Parse `...' in argument lists. Somehow this got missed out. There are a number of bugs elsewhere, where things can't cope with the `:ellipsis' marker, to be fixed in subsequent commits. --- diff --git a/src/c-types-parse.lisp b/src/c-types-parse.lisp index 4a8e1d7..39a805e 100644 --- a/src/c-types-parse.lisp +++ b/src/c-types-parse.lisp @@ -367,15 +367,34 @@ (defun parse-declarator (scanner base-type &key kernel abstractp) (cons #'identity name)))) (argument-list () - ;; [ argument [ `,' argument ]* ] - - (parse (list (:min 0) - (seq ((base-type (parse-c-type scanner)) - (dtor (parse-declarator scanner - base-type - :abstractp t))) - (make-argument (cdr dtor) (car dtor))) - #\,))) + ;; [ argument [ `,' argument ]* [ `,' `...' ] ] | `...' + ;; + ;; The possibility of a trailing `,' `...' means that we + ;; can't use the standard `list' parser. Note that, unlike + ;; `real' C, we allow an ellipsis even if there are no + ;; explicit arguments. + + (let ((args nil)) + (loop + (when (eq (token-type scanner) :ellipsis) + (push :ellipsis args) + (scanner-step scanner) + (return)) + (multiple-value-bind (arg winp consumedp) + (parse (seq ((base-type (parse-c-type scanner)) + (dtor (parse-declarator scanner + base-type + :abstractp t))) + (make-argument (cdr dtor) (car dtor)))) + (unless winp + (if (or consumedp args) + (return-from argument-list (values arg nil t)) + (return))) + (push arg args)) + (unless (eq (token-type scanner) #\,) + (return)) + (scanner-step scanner)) + (values (nreverse args) t args))) (postfix-lparen () ;; Postfix: `(' argument-list `)'