From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eric Abrahamsen Newsgroups: gmane.emacs.devel Subject: Re: Make peg.el a built-in library? Date: Thu, 26 Aug 2021 20:17:59 -0700 Message-ID: <87fsuvpod4.fsf@ericabrahamsen.net> References: <875yvtbbn3.fsf@ericabrahamsen.net> <87bl5k87hq.fsf@alphapapa.net> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="37988"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Adam Porter Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Aug 27 05:19:03 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mJSOU-0009gX-DJ for ged-emacs-devel@m.gmane-mx.org; Fri, 27 Aug 2021 05:19:02 +0200 Original-Received: from localhost ([::1]:42986 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mJSOS-0002kH-4y for ged-emacs-devel@m.gmane-mx.org; Thu, 26 Aug 2021 23:19:00 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48782) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJSNe-0001z7-9v for emacs-devel@gnu.org; Thu, 26 Aug 2021 23:18:10 -0400 Original-Received: from mail.ericabrahamsen.net ([52.70.2.18]:36826) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mJSNb-0005gN-Id for emacs-devel@gnu.org; Thu, 26 Aug 2021 23:18:09 -0400 Original-Received: from localhost (c-73-109-4-106.hsd1.wa.comcast.net [73.109.4.106]) (Authenticated sender: eric@ericabrahamsen.net) by mail.ericabrahamsen.net (Postfix) with ESMTPSA id 7E4C1FA827; Fri, 27 Aug 2021 03:18:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericabrahamsen.net; s=mail; t=1630034285; bh=ymADckp0Jz5y+d5h8YZpr/OKaAJOoMW4G/xn4V3FH94=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=GULxiyzbfDQlpXZsveNP9tURZmt3M3tN2wEdm/kN7mfrmT8+g0Djnik2NVI7F40DT msHvGhKRz4BruStrhtFQabfuKpd8QZQ954iaZ86SGqt0XwRVpc2mzWmStrNjsrnKCV 6Fwe6oiagOleskFGATnUM/zpcOAdkS5GMUZ8MB+E= In-Reply-To: <87bl5k87hq.fsf@alphapapa.net> (Adam Porter's message of "Thu, 26 Aug 2021 12:02:09 -0500") Received-SPF: pass client-ip=52.70.2.18; envelope-from=eric@ericabrahamsen.net; helo=mail.ericabrahamsen.net X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:273112 Archived-At: Adam Porter writes: > FWIW, I've been happy using peg.el in org-ql. I use it to parse strings > like: > > "todo:WAITING scheduled:from=2021-08-01,to=2021-08-31" > > into a sexp like: > > (and (todo "WAITING") > (scheduled :from "2021-08-01" :to "2021-08-31")) > > You can see the code I use here: > > https://github.com/alphapapa/org-ql/blob/master/org-ql.el#L854 Whoo, I've been trying to get enough of a handle on the parsing actions to write a documentation patch for them -- now I'm seeing what Helmut meant by "semantically unintuitive". The sum total of docs regarding actions is: A "stack action" takes VARs from the "value stack" and pushes the result of evaluating FORMs to that stack. So lower-level pexs need to explicitly push values onto the stack. They can do that with either one of the built-in "operators" (substring, region, replace, list), or by using the pattern: (and `(VARS... -- FORM...)) Which confused me mightily until I realized that the backquoted sexp was essentially a lambda with funny syntax: `(VARS... -- FORM...) ==> (lambda (vars...) form...) `(-- FORM...) ==> (lambda () form...) You don't actually need the leading `and' if you're writing a top-level pex, it only seems necessary if you're lining up a series of them under an `or'. A built-in operator pushes a value onto the stack. No operator (or stack action) means no push. An action lambda with no argument but a return value simply pushes that value onto the stack. An action lambda that accepts arguments consumes values from the stack, and then pushes a new value (its return value) onto the stack. So lower-level pexs can take values from the stack and push new ones back onto the stack, and higher-level pexs can pick those up later. But because higher-level pexs often simply "or" lower-level pexs, the developer has to be consistent with the number and type of pushed values: if a high-level pex looks like: (foo (or baz bar) `(str -- (upcase str))) Then the contract is that both the "baz" and "bar" pexs (or an even lower-level pex referred to by them) will push a single string value onto the stack (probably with the "substring" operator). Essentially we need to be calling our upper-level lambda with the right number/type of argument(s). If this email makes no sense, it's because I'm halfway through trying to understand this library. I guess I could wish that these action forms were simply callables, since they're clearly modeled after function calls. Anyhoo, I'm going to try to confirm all of the above, and then at least add to the commentary section for the main package file. Eric