From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stephen Leake Newsgroups: gmane.emacs.devel Subject: smie-next-sexp vs associative operators Date: Sun, 14 Oct 2012 05:16:31 -0400 Message-ID: <85lif9e7m8.fsf@member.fsf.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1350206498 1691 80.91.229.3 (14 Oct 2012 09:21:38 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 14 Oct 2012 09:21:38 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Oct 14 11:21:45 2012 Return-path: Envelope-to: ged-emacs-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 1TNKOG-0002cX-Gh for ged-emacs-devel@m.gmane.org; Sun, 14 Oct 2012 11:21:44 +0200 Original-Received: from localhost ([::1]:39325 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TNKO9-0007bF-Oh for ged-emacs-devel@m.gmane.org; Sun, 14 Oct 2012 05:21:37 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:39855) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TNKO7-0007aY-VL for emacs-devel@gnu.org; Sun, 14 Oct 2012 05:21:36 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TNKO6-0002Nf-U1 for emacs-devel@gnu.org; Sun, 14 Oct 2012 05:21:35 -0400 Original-Received: from qmta04.westchester.pa.mail.comcast.net ([76.96.62.40]:34798) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TNKO6-0002NX-Pr for emacs-devel@gnu.org; Sun, 14 Oct 2012 05:21:34 -0400 Original-Received: from omta02.westchester.pa.mail.comcast.net ([76.96.62.19]) by qmta04.westchester.pa.mail.comcast.net with comcast id AxL01k0010QuhwU54xMfax; Sun, 14 Oct 2012 09:21:39 +0000 Original-Received: from TAKVER ([69.140.67.196]) by omta02.westchester.pa.mail.comcast.net with comcast id AxG71k0014E4Fsd3NxG7vb; Sun, 14 Oct 2012 09:16:07 +0000 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (windows-nt) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 76.96.62.40 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:154324 Archived-At: I'm having a problem with the way smie-next-sexp handles associative operators. The problem comes when I'm trying to indent a line in this statement; select accept BILLY; null; or accept SILLY; null; or accept LILLY do null; end LILLY; end select; I'm indenting "accept LILLY". It should be indented relative to "select". (I could put in a special case rule for "or", but I want to use the general purpose rule, that uses smie-backward-sexp to find the statement start, and indents relative to that.) In this case, smie-backward-sexp is called with "or"; (smie-backward-sexp "or") However, this stops with point on "accept SILLY", not accept. The reason is this code: ((not (smie--associative-p toklevels)) (push toklevels levels)) ;; The new operator is associative. Two cases: ;; - it's really just an associative operator (like + or ;) ;; in which case we should have stopped right before. ((and lastlevels (smie--associative-p (car lastlevels))) (throw 'return (prog1 (list (or (car toklevels) t) (point) token) (goto-char pos)))) ;; - it's an associative operator within a larger construct ;; (e.g. an "elsif"), so we should just ignore it and keep ;; looking for the closing element. (t (setq levels lastlevels)))))))) Here `lastlevels' is "or" (the one we started with), and `toklevels' is the next "or". "or" is associative; the right and left levels are the same. So (smie--associative-p toklevels) and (smie--associative-p (car lastlevels)) are both true. That means the code decides it's like +, and stops, and the higher level indents relative to "accept", which is wrong. But this is exactly like the "elsif" case the comments are talking about, so I think the code is broken. In general, there is no way for SMIE to distinguish an "associative operator" from an "associative keyword", because at this level everything is an operator. So I'd like to add an option `smie-next-sexp-stop-on-associative', that controls whether this stops or keeps going. That way, the user can let-bind this appropriately, depending on the circumstances. For Ada, I'll probably set it to nil always, but maybe not. Somewhat apropos of this topic; I ended up leaving all of the math operators out of my Ada SMIE grammar; I don't make indentation decisions based on them, so they don't need to be in the grammar. So this "or" is the only associative operator I have. -- -- Stephe