From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.devel Subject: Re: [PATCH] Implement 'scm_c_bind_kwargs' to handle keyword arguments from C Date: Sat, 06 Apr 2013 22:42:16 +0200 Message-ID: <87fvz35r2v.fsf@pobox.com> References: <87vc7ztq01.fsf@tines.lan> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1365280956 21023 80.91.229.3 (6 Apr 2013 20:42:36 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 6 Apr 2013 20:42:36 +0000 (UTC) Cc: guile-devel@gnu.org To: Mark H Weaver Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Apr 06 22:42:37 2013 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UOZwZ-0003Gx-VS for guile-devel@m.gmane.org; Sat, 06 Apr 2013 22:42:36 +0200 Original-Received: from localhost ([::1]:39728 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOZwZ-00072M-Jh for guile-devel@m.gmane.org; Sat, 06 Apr 2013 16:42:35 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:39777) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOZwP-00072A-RT for guile-devel@gnu.org; Sat, 06 Apr 2013 16:42:32 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UOZwL-0005Vu-2n for guile-devel@gnu.org; Sat, 06 Apr 2013 16:42:25 -0400 Original-Received: from a-pb-sasl-quonix.pobox.com ([208.72.237.25]:34405 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOZwK-0005VL-TL for guile-devel@gnu.org; Sat, 06 Apr 2013 16:42:21 -0400 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 71066B469; Sat, 6 Apr 2013 16:42:20 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=adYVlITU7Z8Cyjr5NU3y5lU12Qc=; b=blVeRy yigKg8x8wMyKwfqE6NuSeCtnxVZodzCRMx0uFPArbsRSliz74PruEzi6NzM/MQeu CK97dLqyPLn/QUeRJ9suQlCI0/p4ucQFhNB6MKLj4XLnL7Suv1+pU0+dFRcWwnVn uEhW+Fj8pRUY9GkMMHNKAyQjeug/Q+1yfNtHM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=GBULLXfvNUTnq2R+LovPtLLoxWCuxshK TttUyFRyPbh5OgDPCI33xvhW+mStggF5efDaawRALVT1xtOTdfWXMmSx3O8uV1EK TTS0fyIAs9n1FdpoZYGPCJfDnSU2UvfFLuG98ZrNjg/e2oah1omQJIHnh2aAuMJl 4YMtnQKvPr4= Original-Received: from a-pb-sasl-quonix.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 6A76BB468; Sat, 6 Apr 2013 16:42:20 -0400 (EDT) Original-Received: from badger (unknown [88.160.190.192]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTPSA id B6F05B466; Sat, 6 Apr 2013 16:42:19 -0400 (EDT) In-Reply-To: <87vc7ztq01.fsf@tines.lan> (Mark H. Weaver's message of "Sat, 06 Apr 2013 15:31:42 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) X-Pobox-Relay-ID: 79E73262-9EFA-11E2-9177-D36F0E5B5709-02397024!a-pb-sasl-quonix.pobox.com X-detected-operating-system: by eggs.gnu.org: Solaris 10 X-Received-From: 208.72.237.25 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:16173 Archived-At: Hi Mark, I'm OK with this in principle, but we shouldagree on names before this goes in. On Sat 06 Apr 2013 21:31, Mark H Weaver writes: > * libguile/keywords.c (scm_keyword_argument_error): New variable. > (scm_c_bind_kwargs): New API function. I think I prefer scm_c_bind_keyword_arguments, if that's OK with you. > +scm_c_bind_kwargs (const char *subr, SCM rest, int flags, ...) > +{ > + int allow_other_keys = flags & SCM_KWARGS_ALLOW_OTHER_KEYS; > + int allow_rest = flags & SCM_KWARGS_ALLOW_REST; "Allow rest" sorta sounds like the #:rest bit from lambda*, but it doesn't actually help us to bind a rest argument, because we already have it. Better to call it "ALLOW_NON_KEYWORDS" or "PERMISSIVE" or "SLOPPY" or something. > + if (SCM_UNLIKELY (!allow_rest && scm_ilength (rest) % 2 != 0)) > + scm_error (scm_keyword_argument_error, > + subr, "Odd length of keyword argument list", > + SCM_EOL, SCM_BOOL_F); > + > + while (scm_is_pair (rest)) > + { > + SCM kw_or_arg = SCM_CAR (rest); > + SCM tail = SCM_CDR (rest); > + > + if (scm_is_keyword (kw_or_arg) && scm_is_pair (tail)) > + { > + SCM kw; > + SCM *arg_p; > + > + va_start (va, allow_other_keys); "flags", no? > + for (;;) > + { > + kw = va_arg (va, SCM); > + if (SCM_UNBNDP (kw)) > + { > + /* KW_OR_ARG is not in the list of expected keywords. */ > + if (!allow_other_keys) > + scm_error (scm_keyword_argument_error, > + subr, "Unrecognized keyword", > + SCM_EOL, SCM_BOOL_F); > + break; > + } Don't we need to advance "tail" in the "allow_other_keys" case, to skip over the argument value? That is what the bind-kwargs VM op does. > + /* The next argument is not a keyword, or is a singleton > + keyword at the end of REST. */ > + if (!allow_rest) > + scm_error (scm_keyword_argument_error, > + subr, "Invalid keyword", > + SCM_EOL, SCM_BOOL_F); > + > + /* Advance REST. */ > + rest = tail; I think the semantics of rest arguments with keywords is that the rest argument *includes* the keywords. > +#define SCM_KWARGS_ALLOW_OTHER_KEYS 1 > +#define SCM_KWARGS_ALLOW_REST 2 typedef enum { SCM_KEYWORD_ARGUMENTS_NO_FLAGS = 0, SCM_KEYWORD_ARGUMENTS_ALLOW_OTHER_KEYS = (1U << 0), SCM_KEYWORD_ARGUMENTS_IGNORE_NON_KEYWORDS = (1U << 1) } scm_t_keyword_arguments_flag; Cheers, Andy -- http://wingolog.org/