From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Leo Newsgroups: gmane.emacs.devel Subject: Common Lisp like feature expressions (was: How and when to use GCPRO?) Date: Mon, 27 Dec 2010 19:26:03 +0000 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1293478074 5554 80.91.229.12 (27 Dec 2010 19:27:54 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 27 Dec 2010 19:27:54 +0000 (UTC) Cc: Andreas Schwab , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Dec 27 20:27:49 2010 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PXIjV-0002Ki-Fi for ged-emacs-devel@m.gmane.org; Mon, 27 Dec 2010 20:27:49 +0100 Original-Received: from localhost ([127.0.0.1]:56520 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PXIhy-0005Sw-BR for ged-emacs-devel@m.gmane.org; Mon, 27 Dec 2010 14:26:14 -0500 Original-Received: from [140.186.70.92] (port=51898 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PXIht-0005Sr-IK for emacs-devel@gnu.org; Mon, 27 Dec 2010 14:26:10 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PXIhs-0002bh-8G for emacs-devel@gnu.org; Mon, 27 Dec 2010 14:26:09 -0500 Original-Received: from mail-ww0-f49.google.com ([74.125.82.49]:53453) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PXIhr-0002bZ-Va for emacs-devel@gnu.org; Mon, 27 Dec 2010 14:26:08 -0500 Original-Received: by wwb17 with SMTP id 17so9005669wwb.30 for ; Mon, 27 Dec 2010 11:26:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:references :date:in-reply-to:message-id:user-agent:mime-version:content-type; bh=1PTzpZKouqiNEIPlnWEgqP1+UDWiBVyhXVgQ0YsUhW4=; b=bkZN15mTzFveIacRlbIYtiRnMAqN8ZzFqbqaztKXBNIvuaRCKzqHbjI0aan+YgRXjs NIqSEumbHHDtpnveC8OEMIn0V43lUl+u69XhCFyNjaIio3JiEIGQjP9cdHeSEutbw/xM q4DpPJIIU2pcnAQABQDhJysq2Marjnn0vU1a8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; b=XitH/52n52Ox0f72d/XeHQv7Yc6Rdpeq6ey27TRujPvWUn4aSlNJ5vHcmypFO4tW15 XTDos0Ht4qbkufGfkAmLY3bp0Ffz6dstehLc5k4qX0kCQlcE+ngHxDq6n8odzxGSkbbi dWZfjLDn5T8KK8FEn6KUQ1ngSJwaOMq5AxBxw= Original-Received: by 10.216.7.137 with SMTP id 9mr16121547wep.97.1293477967134; Mon, 27 Dec 2010 11:26:07 -0800 (PST) Original-Received: from Victoria.local (cpc1-cmbg13-0-0-cust596.5-4.cable.virginmedia.com [86.9.122.85]) by mx.google.com with ESMTPS id p4sm6094341wer.29.2010.12.27.11.26.05 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 27 Dec 2010 11:26:06 -0800 (PST) In-Reply-To: (Stefan Monnier's message of "Mon, 27 Dec 2010 11:00:42 -0500") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2.91 (Mac OS X 10.6.5) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:133986 Archived-At: On 2010-12-27 16:00 +0000, Stefan Monnier wrote: > Stefan "wondering why eval_feature_expression would need to be > written in C rather than in Elisp" I hadn't thought of that :( I put together a small patch for anyone who would like to try it: diff --git a/lisp/subr.el b/lisp/subr.el index 03f7e04..92f3b0a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1719,6 +1719,31 @@ FILE should be the name of a library, with no directory name." (eval-after-load file (read))) (make-obsolete 'eval-next-after-load `eval-after-load "23.2") +(defun eval-feature-expression (form) + (cond + ((atom form) (featurep form nil)) + ;; ensure form is a proper list + ((condition-case nil + (and (length form) nil) + (error (error "Invalid feature expression: %s" form)))) + ((eq (car form) 'not) + (if (= (length form) 2) + (not (eval-feature-expression (cadr form))) + (error "Invalid feature expression: %s" form))) + ((= (length form) 2) + (eval-feature-expression (cadr form))) + ((eq (car form) 'and) + (if (= (length form) 1) + t + (and (eval-feature-expression (cadr form)) + (eval-feature-expression (cons 'and (cddr form)))))) + ((eq (car form) 'or) + (if (= (length form) 1) + nil + (or (eval-feature-expression (cadr form)) + (eval-feature-expression (cons 'or (cddr form)))))) + (t (error "Invalid feature expression: %s" form)))) + ;;;; Process stuff. (defun process-lines (program &rest args) diff --git a/src/lread.c b/src/lread.c index 72c01ed..32c36ee 100644 --- a/src/lread.c +++ b/src/lread.c @@ -96,6 +96,9 @@ Lisp_Object Qinhibit_file_name_operation; Lisp_Object Qeval_buffer_list, Veval_buffer_list; Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */ +/* Used in feature expression */ +Lisp_Object Qobarray, Qeval_feature_expression; + /* Used instead of Qget_file_char while loading *.elc files compiled by Emacs 21 or older. */ static Lisp_Object Qget_emacs_mule_file_char; @@ -2426,6 +2429,24 @@ read1 (readcharfun, pch, first_in_list) UNREAD (c); invalid_syntax ("#", 1); } + /* feature expressions as in Common Lisp */ + if (c == '+' || c == '-') + { + Lisp_Object fexp = read0(readcharfun); + fexp = call1 (Qeval_feature_expression, fexp); + if (c == '-') + fexp = NILP (fexp) ? Qt : Qnil; + if (NILP (fexp)) + { + int count = SPECPDL_INDEX (); + Lisp_Object tem = Fmake_vector (make_number(17),make_number(0)); + /* use a temporary obarray */ + specbind (Qobarray, tem); + read0 (readcharfun); + unbind_to (count, Qnil); + } + goto retry; + } if (c == '^') { c = READCHAR; @@ -4536,6 +4557,11 @@ to load. See also `load-dangerous-libraries'. */); Qcomma_dot = intern_c_string (",."); staticpro (&Qcomma_dot); + Qeval_feature_expression = intern_c_string ("eval-feature-expression"); + staticpro (&Qeval_feature_expression); + Qobarray = intern_c_string ("obarray"); + staticpro(&Qobarray); + Qinhibit_file_name_operation = intern_c_string ("inhibit-file-name-operation"); staticpro (&Qinhibit_file_name_operation);