unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Andreas Rottmann <a.rottmann@gmx.at>
To: Andy Wingo <wingo@pobox.com>
Cc: Guile Developers <guile-devel@gnu.org>
Subject: Re: Quasisyntax broken?
Date: Sat, 25 Jul 2009 23:30:04 +0200	[thread overview]
Message-ID: <87ljmcsb6r.fsf@delenn.lan> (raw)
In-Reply-To: <m3iqhjdnir.fsf@pobox.com> (Andy Wingo's message of "Fri, 24 Jul 2009 00:48:12 +0200")

[-- Attachment #1: Type: text/plain, Size: 1443 bytes --]

Andy Wingo <wingo@pobox.com> writes:

> Hi,
>
> On Fri 24 Jul 2009 00:35, Andreas Rottmann <a.rottmann@gmx.at> writes:
>
>> Andy Wingo <wingo@pobox.com> writes:
>>
>>> On Fri 03 Jul 2009 02:04, Andreas Rottmann <a.rottmann@gmx.at> writes:
>>>
>>>> Playing around with Guile's now-in-core syntax-case support (using Git
>>>> HEAD as of today), I found that quasisyntax seems quite broken:
>>>
>>> We've spoken over IRC since then, but for those that do not frequent
>>> there, it's simply not implemented. You can implement it in terms of
>>> with-syntax, though. Did you have a patch for that, Andreas?
>>>
>> Yep, the patch is attached:
>
> What is the license of this code?
>
It's under the (unmodified) MIT license, see
<http://srfi.schemers.org/srfi-process.html>. I've attached an updated
patch, which takes the quasisyntax implementation straight from Andre
van Tonder's portable R6RS libraries implementation[0], without any
modification.

[0] http://www.het.brown.edu/people/andre/macros/index.html

> (Do you have copyright assignment on file? I assume the original
> author does not.)
>
I think I filed one for Guile several years ago, and think you assume
rightly; I guess that might be a problem; OTOH it would be (IMHO) kinda
dumb to have to ignore/rewrite all the perfectly (L)GPL-compatible BSD-
and MIT-licensed code that's out there, as you cannot expect the
respective authors to all sign copyright assignments for Guile...


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: t_quasisyntax.diff --]
[-- Type: text/x-diff, Size: 5093 bytes --]

From: Andreas Rottmann <a.rottmann@gmx.at>
Subject: [PATCH] Add support for `quasisyntax'


---
 module/ice-9/boot-9.scm |  117 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index 36a463a..31ebfe0 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -308,6 +308,123 @@
   (syntax-rules ()
     ((_ exp) (make-promise (lambda () exp)))))
 
+;; Quasisyntax in terms of syntax-case.
+;;
+;; Code taken from
+;; <http://www.het.brown.edu/people/andre/macros/index.html>;
+;; Copyright (c) 2006 Andre van Tonder
+;; Copyright statement at http://srfi.schemers.org/srfi-process.html
+;;
+;;=========================================================
+;;
+;; To make nested unquote-splicing behave in a useful way,
+;; the R5RS-compatible extension of quasiquote in appendix B
+;; of the following paper is here ported to quasisyntax:
+;;
+;; Alan Bawden - Quasiquotation in Lisp
+;; http://citeseer.ist.psu.edu/bawden99quasiquotation.html
+;;
+;; The algorithm converts a quasisyntax expression to an
+;; equivalent with-syntax expression.
+;; For example:
+;;
+;; (quasisyntax (set! #,a #,b))
+;;   ==> (with-syntax ((t0 a)
+;;                     (t1 b))
+;;         (syntax (set! t0 t1)))
+;;
+;; (quasisyntax (list #,@args))
+;;   ==> (with-syntax (((t ...) args))
+;;         (syntax (list t ...)))
+;;
+;; Note that quasisyntax is expanded first, before any
+;; ellipses act.  For example:
+;;
+;; (quasisyntax (f ((b #,a) ...))
+;;   ==> (with-syntax ((t a))
+;;         (syntax (f ((b t) ...))))
+;;
+;; so that
+;;
+;; (let-syntax ((test-ellipses-over-unsyntax
+;;               (lambda (e)
+;;                 (let ((a (syntax a)))
+;;                   (with-syntax (((b ...) (syntax (1 2 3))))
+;;                     (quasisyntax
+;;                      (quote ((b #,a) ...))))))))
+;;   (test-ellipses-over-unsyntax))
+;;
+;;     ==> ((1 a) (2 a) (3 a))
+(define-syntax quasisyntax
+  (lambda (e)
+    
+    ;; Expand returns a list of the form
+    ;;    [template[t/e, ...] (replacement ...)]
+    ;; Here template[t/e ...] denotes the original template
+    ;; with unquoted expressions e replaced by fresh
+    ;; variables t, followed by the appropriate ellipses
+    ;; if e is also spliced.
+    ;; The second part of the return value is the list of
+    ;; replacements, each of the form (t e) if e is just
+    ;; unquoted, or ((t ...) e) if e is also spliced.
+    ;; This will be the list of bindings of the resulting
+    ;; with-syntax expression.
+    
+    (define (expand x level)
+      (syntax-case x (quasisyntax unsyntax unsyntax-splicing)
+        ((quasisyntax e)
+         (with-syntax (((k _)     x) ;; original identifier must be copied
+                       ((e* reps) (expand (syntax e) (+ level 1))))
+           (syntax ((k e*) reps))))                                  
+        ((unsyntax e)
+         (= level 0)
+         (with-syntax (((t) (generate-temporaries '(t))))
+           (syntax (t ((t e))))))
+        (((unsyntax e ...) . r)
+         (= level 0)
+         (with-syntax (((r* (rep ...)) (expand (syntax r) 0))
+                       ((t ...)        (generate-temporaries (syntax (e ...)))))
+           (syntax ((t ... . r*)
+                    ((t e) ... rep ...)))))
+        (((unsyntax-splicing e ...) . r)
+         (= level 0)
+         (with-syntax (((r* (rep ...)) (expand (syntax r) 0))
+                       ((t ...)        (generate-temporaries (syntax (e ...)))))
+           (with-syntax ((((t ...) ...) (syntax ((t (... ...)) ...))))
+             (syntax ((t ... ... . r*)
+                      (((t ...) e) ... rep ...))))))
+        ((k . r)
+         (and (> level 0)
+              (identifier? (syntax k))
+              (or (free-identifier=? (syntax k) (syntax unsyntax))
+                  (free-identifier=? (syntax k) (syntax unsyntax-splicing))))
+         (with-syntax (((r* reps) (expand (syntax r) (- level 1))))
+           (syntax ((k . r*) reps))))
+        ((h . t)
+         (with-syntax (((h* (rep1 ...)) (expand (syntax h) level))
+                       ((t* (rep2 ...)) (expand (syntax t) level)))
+           (syntax ((h* . t*)
+                    (rep1 ... rep2 ...)))))
+        (#(e ...)                                                               
+         (with-syntax ((((e* ...) reps)
+                        (expand (vector->list (syntax #(e ...))) level)))
+           (syntax (#(e* ...) reps))))
+        (other
+         (syntax (other ())))))
+    
+    (syntax-case e ()
+      ((_ template)
+       (with-syntax (((template* replacements) (expand (syntax template) 0)))
+         (syntax
+          (with-syntax replacements (syntax template*))))))))
+
+(define-syntax unsyntax
+  (lambda (e)
+    (syntax-violation 'unsyntax "Invalid expression" e)))
+
+(define-syntax unsyntax-splicing
+  (lambda (e)
+    (syntax-violation 'unsyntax "Invalid expression" e)))
 \f
 
 ;;; {Defmacros}
-- 
tg: (74deff3..) t/quasisyntax (depends on: master)

[-- Attachment #3: Type: text/plain, Size: 54 bytes --]


Rotty
-- 
Andreas Rottmann -- <http://rotty.yi.org/>

  reply	other threads:[~2009-07-25 21:30 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-03  0:04 Quasisyntax broken? Andreas Rottmann
2009-07-23 21:31 ` Andy Wingo
2009-07-23 22:35   ` Andreas Rottmann
2009-07-23 22:48     ` Andy Wingo
2009-07-25 21:30       ` Andreas Rottmann [this message]
2009-07-26 13:15         ` Ludovic Courtès
2009-07-26 16:30         ` Andy Wingo
2009-07-26 22:06           ` Ludovic Courtès
2009-07-27 22:51             ` Neil Jerram
2009-08-20 21:19         ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ljmcsb6r.fsf@delenn.lan \
    --to=a.rottmann@gmx.at \
    --cc=guile-devel@gnu.org \
    --cc=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).